Docker provides software containers to ease the deployment of applications. It is also very convenient to use it to deploy a development environment.
We at wisol use it to distribute environments that include tools to compile and deploy our projects to different embedded target platforms. Our images contain cross compilers, already compiled software such as Qt, or the BSP to support our platforms.
Using a Container
One way a container can be used is to specify interactive mode, allocate a
pseudo TTY, and start a shell in the container. This way, one can log-in into
the container and do some work. For example, assuming the ubuntu
container,
the following command can be used.
sudo docker run -i -t --rm ubuntu /bin/bash
-i
is for interactive mode, -t
for pseudo-TTY, and --rm
to destroy the
container on exit.
Shared Folders
In addition to the above command, it is often useful to share some directories with the host environment. This can be used to do the coding in the preferred editor from the host and to compile, run, and test the result with the target compiler and environment.
Docker has an option to share a directory with its -v
option. To follow the
above example, to share the folder shared
in the current working directory,
the following command can be used.
sudo docker run -i -t --rm -v `pwd`/shared:/target ubuntu /bin/bash
This will bind mount the directory shared
from the host environment to the
directory /target
in the container environment. Note that the path must be
absolute, and the given syntax works for bash
.
Aliases
The above is already nice and works well. However, instead of logging into docker and execute the commands, it would be even nicer to be able to execute commands that do the following.
- Log-in into the container.
- Mount some shared folders.
- Execute a command in the container and apply it to some files from the host.
- Exit and remove the container.
This procedure can then be used to e.g. compile a file or project with a compiler from a docker container instead of the host compiler, but with the same syntax.
Since docker passes arguments to the command which is invoked in the container,
it is no longer difficult to extend the above command to achieve this. The only
thing we have to do is to specify the working directory in the docker
container. This can be done with the -w
flag. Obviously it should be the same
as the shared folder.
sudo docker run -i -t --rm -v `pwd`/shared:/target -w /target ubuntu gcc
Such a command can then be aliased by the shell and invoked the same as the
regular host compiler. How to create aliases depends on the shell, but for bash
something like this can be used in $HOME/.bashrc
.
alias dgcc='sudo docker run ...'
sudo
Finally, to avoid having to type the password over and over, it is convenient to let a user execute the docker commands through sudo without a password.
Add the following line to the sudo configuration. Always do this with sudo
visudo
instead of directly editing the file.
username ALL=(root) NOPASSWD: /usr/bin/docker