Herman J. Radtke III

Read more of my blog or subscribe to my feed.


Using Docker to Test Rust on Linux

Written by Herman J. Radtke III on 23 Aug 2015

I use a MacBook Air as my main laptop. I have been using Vagrant to test rust programs on linux. This feels a little heavy to me though as I have to create a Vagrant machine for each repository. The up and halt phases of the Vagrant box are a little slow and each machine eats away at my available hard drive space. I do not need an entire virutalized operating system, just a place to test my programs. This seems like a good use case for Docker.

The first thing I had to do was get boot2docker installed. This was pretty straight-forward, but did take a fair bit of time. The second thing was finding an upstream Rust container (I think this is called an image) to use. I do not want to build one myself. Doing a search on Docker Hub I chose the schickling/rust container. The repo info had a simple walkthrough, the Dockerfile itself seemed straightforward and it included gdb.

This container is setup to be used interatively or to run commands. To run cargo tests:

$ docker run --rm -it -v $(pwd):/source schickling/rust cargo test

Let us go over the command. If you are familiar with Docker, you can skip this section. To start, docker run runs a command in a new contianer. The --rm, -it and -v flags are very common when running Docker containers. Here is what they mean:

  • --rm - automatically remove the container when it exists. This means when the command is over, the container will stop running. This removes the container, but not the schickling/rust image.
  • -it - make the docker container interactive and allocate a tty. This basically means your shell will work.
  • -v - mount a volume. In the example above, it binds the local present working directory to the /source directory inside the container.

After the flags, we specify the upstream Docker container name schickling/rust and then finally our command.

If you want to run experiment inside the linux container, just omit a command. The docker file used to buildschickling/rust specifies bash as the default command.

$ docker run --rm -it -v $(pwd):/source schickling/rust cargo test

This is basically like a vagrant ssh command. You will be given a shell inside the container. I do this when playing with mob because I want to run the server, then the client in various ways. Example:

$ docker run --rm -it -v $(pwd):/source schickling/rust
root@f237a067addb:/source# cargo build
root@f237a067addb:/source# RUST_LOG=trace ./target/debug/mob-server 2> server.log &
root@f237a067addb:/source# ./target/debug/mob-client
root@f237a067addb:/source# fg

Make sure you run cargo build inside the container as Linux cannot run the executable built on OS X. If you see the error bash: ./target/debug/mob-server: cannot execute binary file then you need to cargo build. I then run the mob server in the background and send the log output to a file. I run the mob client (sometimes repeatedly). When done, I use the fg command to bring the mob server process back into the foreground where I can terminate it (using Ctrl-C). I then exit the container (using Ctrl-D), the container is cleaned up and I can start fresh again if I want.

Docker was fairly easy to get setup and I have found it to be more efficient for these types of use-cases. The hardest part was getting boot2docker installed correctly. Docker will not completely replace Vagrant on my machine, but it certainly has found a place.