Welcome to our best attempt to create a guide to use Docker for embedded systems, the guys from web development had been enjoying the benefits of this technology for quiet sometime now as part of the so-called DevOps ( I’m not going to define DevOps ). Now is our turn to implemented as part of what the guys from DojoFive calls EmbedOps, pretty cool ha, I really liked. Some knowledge of Linux CLI and how to install packages will be very helpful, Remember Containers are at the end, Linux distros.
This is not a Docker tutorial. I will not explain Docker concepts because they are already well-explained all over the internet. Instead, I will write some use case scenarios on how you can implement Docker containers for embedded development based on my experience.
There are two ways to install docker in your Linux and Windows machines. Docker Desktop and Docker Engine, docker desktop comes with a fancy GUI to control your images and container but the most important thing runs all containers inside a Virtual Machine created especially for these purposes, while docker engine runs natively in Linux and inside WSL in the case of Windows.
Docker Engine
My preferred choice for Linux and WSL because CLI is the only thing I need. Let’s get straight to the point: in your fancy Arch Linux ( or WSL ) open a terminal and install Docker using pacman. This is the official docker engine package supported in the Arch repositories. For Ubuntu, Fedora or CentOS users, just follow instructions in their respective section from official documentation
For Windows user with WSL, you need a fresh instance with Arch Linux already configured just like is illustrated in here
$ sudo pacman -S docker
Once installed we will need to add our user to docker group to avoid the need of using sudo to invoke docker (where <your username> is of course your Linux username)
$ sudo usermod -a -G docker <your user name>
Once installed it is necessary to run the docker daemon in the background otherwise we won't be able to run anything
$ sudo systemctl start docker
$ sudo systemctl status docker
If you don’t want to type the enable command every time you boot your computer or WSL you can use
$ sudo systemctl enable docker
Test you Docker instance is actually running with the hello world example
$ docker run --rm hello-world
Docker Desktop
There is a limitation on Linux that prevents direct access to USB ports from within containers (at least as of the time of writing, I couldn't find a way to achieve it). I'm not sure about Windows or macOS in this regard. As embedded engineers, we often need to access debuggers, protocol analyzers, and various tools via USB ports. Fortunately, Docker Engine on Linux doesn’t face this issue.
I’m going to borrow the following text from the Arch Linux wiki because summarize very well what Docker Desktop is. Proprietary desktop application that runs the Docker Engine inside a Linux virtual machine. Additional features such as a Kubernetes cluster and a vulnerability scanner are included. This application is useful for software development teams who develop Docker containers using macOS and Windows. To install in any of the mayor OS just follow the official instruction from the official documentation or look for some videos on YouTube, there are many.
For Linux users, if you installed Docker Engine and you want to try docker desktop you should uninstall any previous docker tools before, otherwise many conflicts will arise. Also keep in mind to read the previous requirements first
$ sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
$ systemctl --user restart docker-desktop
Docker commands quick reference
Here is a list of the most common docker commands you will use the 99% of the time, there are more but trust me this are the ones you would like to keep at hand
- Download an image, version is optional
docker pull <image name>:<version>
- List the images in your host machine
docker images
- Remove an image
docker image rm <image name>:<version>
- Create a container from an image
docker create --name <container name> <image name>:<version>
- Create a container from an image with interactive mode and a terminal, with this your container will run your linux image to interact with it
docker create -i -t --name <container name> <image name>:<version>
- Start a container
docker start <container name>
- Start a container in interactive mode,
-i
is in case you want to interact with a container create with-i
and-t
, if not only will output the STDIN for some program you run with out container form the entry point
docker start -i <container name>
- Stop a container from running
docker stop <container name>
- Display all container running
docker ps
- Display all containers running or not
docker ps -a
- Remove a container, you must stop the container first
docker rm <container name>
- Build an image from a Dockerfile, version is optional
docker build -t <image name>:<version>
- Create and start and remove a container in interactive mode from an image
docker run --rm -it <image name>:<version>