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:

><> ^_^ jp@jupiter {git master} ~/Projects/mydata2
$ ls

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

><> ;_; jp@jupiter {git master} ~/Projects/mydata2
$ magic ruby -p 4567:4567

root@f9144a17cf7e:/Users/jp/Projects/mydata2# ls
Gemfile  Gemfile.lock  data  models  mydata.db  mydata.rb  packs.csv  public  routes  views

root@f9144a17cf7e:/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.

root@f9144a17cf7e:/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

...

><> ^_^ jp@jupiter {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:

><> ^_^ jp@jupiter /tmp/5cwqRAsB
$ magic python:2

root@eaebe94ec9e9:/tmp/5cwqRAsB# python --version
Python 2.7.18
root@eaebe94ec9e9:/tmp/5cwqRAsB# exit
exit

><> ^_^ jp@jupiter /tmp/5cwqRAsB
$ magic python:3

root@f99476788be0:/tmp/5cwqRAsB# python --version
Python 3.8.3
root@f99476788be0:/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!