Docker Magic - Arbitrary docker runtimes in place

A quick post today.

I find myself working with a surprising number of different languages/environments day to day. In the last week, I’ve worked with PHP, Python, Go, Ruby, and Javascript. And different versions of several of those. While I could install something like virtualenv for Python / rbenv for Ruby / etc, I already have a tool exactly designed for this sort of thing: Docker!

In a nutshell, what I made was a very very simple alias that lets me do this:

><> ^_^ [email protected] {git master} ~/Projects/mydata2
$ ls

Gemfile       Gemfile.lock  data/         models/       mydata.db     mydata.rb     packs.csv     public/       routes/       views/

><> ;_; [email protected] {git master} ~/Projects/mydata2
$ magic ruby -p 4567:4567

[email protected]:/Users/jp/Projects/mydata2# ls
Gemfile  Gemfile.lock  data  models  mydata.db  mydata.rb  packs.csv  public  routes  views

[email protected]:/Users/jp/Projects/mydata2# bundle install
Fetching gem metadata from https://rubygems.org/...
...
Bundle complete! 2 Gemfile dependencies, 8 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

[email protected]:/Users/jp/Projects/mydata2# ruby mydata.rb
...
/usr/local/bundle/gems/sinatra-2.0.8.1/lib/sinatra/base.rb:1526: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/rack-2.2.3/lib/rack/handler/webrick.rb:26: warning: The called method `run' is defined here
[2020-08-01 18:19:48] INFO  WEBrick 1.6.0
[2020-08-01 18:19:48] INFO  ruby 2.7.1 (2020-03-31) [x86_64-linux]
== Sinatra (v2.0.8.1) has taken the stage on 4567 for development with backup from WEBrick
[2020-08-01 18:19:48] INFO  WEBrick::HTTPServer#start: pid=184 port=4567

...

><> ^_^ [email protected] {git master} ~/Projects/mydata2
$ docker ps

CONTAINER ID        IMAGE                         COMMAND                  CREATED              STATUS              PORTS                          NAMES
f9144a17cf7e        ruby                          "bash"                   About a minute ago   Up About a minute   0.0.0.0:4567->4567/tcp         strange_faraday

I don’t have to have to have Ruby installed on my host system. Instead, I run magic with the container I want (and any other args, such as ports) and it will automatically run bash in the container and map the current directory into the container as the working directory.

The code?

#!/usr/bin/env fish

docker run -it -v (pwd):(pwd) -w (pwd) $argv[2..-1] $argv[1] bash

Okay, so it’s not much, but it saves me typing -it -v (pwd):(pwd) -w (pwd) and the bash all the time. And it just works™.

You can also specify tags:

><> ^_^ [email protected] /tmp/5cwqRAsB
$ magic python:2

[email protected]:/tmp/5cwqRAsB# python --version
Python 2.7.18
[email protected]:/tmp/5cwqRAsB# exit
exit

><> ^_^ [email protected] /tmp/5cwqRAsB
$ magic python:3

[email protected]:/tmp/5cwqRAsB# python --version
Python 3.8.3
[email protected]:/tmp/5cwqRAsB# exit
exit

Like I said, quick.

I might extend it to detect things like requirements.txt and Gemfiles and automatically install packages (or possibly keep a volume between containers), but it’s easy enough to do manually for now.

I vaguely remember seeing someone else doing this before, but I can’t find the link at the moment. If someone has seen it, let me know!