August 7, 2015

OCaml development box using Docker

I’ve just had to reinstall some software on my mac, and I decided to switch to Docker for my OCaml developments and tests. Here’s what I did:

Boot docker

$ boot2docker init
$ boot2docker up
Waiting for VM and Docker daemon to start...
..........oooo
Started.
$ $(boot2docker shellinit)
Writing /Users/alex/.boot2docker/certs/boot2docker-vm/ca.pem
Writing /Users/alex/.boot2docker/certs/boot2docker-vm/cert.pem
Writing /Users/alex/.boot2docker/certs/boot2docker-vm/key.pem

Run Ubuntu

$ docker run -P --name ocamlbox -t -i ubuntu:14.04 /bin/bash
Unable to find image 'ubuntu:14.04' locally
Pulling repository ubuntu
63e3c10217b8: Download complete
2eaf0096818b: Download complete
dac7bccb8ac3: Download complete
389028aa9e91: Download complete
Status: Downloaded newer image for ubuntu:14.04
4954b2805f905e6bb39fda5a4b3e1dc18f66c93ae039972e4d99a0f5db70d077

Install what’s needed

root@4954b2805f90:/$ cd
root@4954b2805f90:~$ apt-get install software-properties-common
root@4954b2805f90:~$ add-apt-repository ppa:avsm/ppa
root@4954b2805f90:~$ apt-get update
root@4954b2805f90:~$ apt-get install opam build-essential m4

Configure OPAM

root@4954b2805f90:~$ opam init
root@4954b2805f90:~$ opam switch 4.02.1
root@4954b2805f90:~$ eval `opam config env`
root@4954b2805f90:~$ opam install batteries core lwt redis

Test it’s working

root@4954b2805f90:~$ cat <<EOF > foo.ml
let _ =
    Printf.printf "Hello, %s!\n" Sys.argv.(1);;
EOF
root@4954b2805f90:~$ ocaml foo.ml Alex
Hello, Alex!
root@4954b2805f90:~$ ocamlfind ocamlc -linkpkg foo.ml -o foo
root@4954b2805f90:~$ ./foo Alex
Hello, Alex!
root@4954b2805f90:~$ ocamlbuild foo.native
root@4954b2805f90:~$ ./foo.native Alex
Hello, Alex!

Save the changes (in another shell)

$ $(boot2docker shellinit)
$ docker commit 4954b2805f90 agrison/ocamlbox
ac21b1ad791b4aa00b30ce1c1e1b8ebb63ff874a61010608b06f755a355484ab

Now you can close that shell, and exit from the docker running instance

root@4954b2805f90:~$ exit

Just to be sure that we can go back where we were:

$ docker run -P -t -i agrison/ocamlbox /bin/bash
root@f34a51ab5ac8:/$ cd
root@f34a51ab5ac8:~$ ls
_build foo.ml foo.native
root@f34a51ab5ac8:~$ exit

Share the source code

Ok, but I’ve got my source files on my host, and I want to edit them from the docker container.

$ docker run -P -t -i -v ~/Dev:/root/dev agrison/ocamlbox /bin/bash
root@011866ec528f:/$ cd
root@011866ec528f:~$ ls
dev _build foo.ml foo.native
root@011866ec528f:~$ ls dev
docs github grison.me redis tools web
root@011866ec528f:~$ cd dev/github/ocamail
root@011866ec528f:~/dev/github/ocamail$ ocamlfind ocamlc -package unix -package str -linkpkg ocamail.ml -o ocamail
root@011866ec528f:~/dev/github/ocamail$ ./ocamail
OCaMail - Binding on 0.0.0.0:25.
OCaMail - Waiting for client.
^C
root@011866ec528f:~/dev/github/ocamail$ exit

Now you’ve got an OCaml developer box ready to rocks some code just by typing:

docker run -P -t -i -v ~/Dev:/root/dev agrison/ocamlbox /bin/bash

just make an alias and you’re good to go.

Enjoy!

Alexandre Grison - //grison.me - @algrison