Simplify your Yocto builds using docker

Introduction

Yocto is a great set of tools which makes it easy to build and maintain your custom linux images for a big variety of hardware. But even if it is continually improved with regards to reproduceability etc, there is still always some dependencies toward the host system used when building. As a user of Debian unstable I sometimes find that I have too new versions of packages, causing issues when building older Yocto releases and sometimes even the latest release. I could of course solve this by sticking to a stable Debian release, or maybe the latest Ubuntu LTS version, but then I have to wait longer for new improvements in e.g. gnome or other projects I use.

Using docker containers

Luckily there’s a great way to address this, so that I can continue to use a very modern distro and still be able to work with older Yocto releases. A sub-project within the Yocto project called CROPS develops tools making Yocto more cross-platform. One thing that they do is that they provide docker images which contain everything you need to build using docker.

You can launch one of those base container for Yocto builds using e.g.

docker run --rm -it crops/yocto:ubuntu-16.04-base

To make it a bit more useful I usually make sure that the current directory and all it’s content is available in docker, that way I can easily access all the sources and build artifact from my regular host system as well.

docker run --rm -it -v ${PWD}:${PWD} crops/yocto:ubuntu-16.04-base --workdir ${PWD}

User id mismatch

The solution above works well in most single user systems, since the first user of the host and the first user of the docker container will likely share the same uid and thus be seen as the same user from a file system perspective. This will however be a problem if multiple users share a build server, but luckily the CROPS people has a solution for this as well. In addition to the crops/yocto docker images they have also created crops/poky which is based on crops/yocto but adds some scripts which allows you to have the same user id inside of docker as inside. The way that it works is that it sets the user id in the container to be the same as the owner of the directory passed in as –workdir.

To use this container instead, use:

docker run --rm -it -v ${PWD}:${PWD} crops/poky:ubuntu-16.04 --workdir ${PWD}

Extending with additional tools

The images provided by CROPS are quite minimalistic, and I usually end up wanting some extra tools in there like vim for editing files and rpm for inspecting generated packages. Luckily this is quite easy to do using docker.

Here’s an example of a Dockerfile extending the crops/poky image with vim and rpm:

FROM crops/poky:ubuntu-16.04

USER root
RUN apt-get update && apt-get install -y vim rpm
RUN rm -rf /var/lib/apt/lists/*

You can then build this image using:

docker build -t pokyextended /path/to/dir/of/dockerfile/

When the image is built you can use it by just replacing crops/poky:ubuntu-16.04 in the command from before:

docker run --rm -it -v ${PWD}:${PWD} pokyextended --workdir ${PWD}

In order to make it a bit more convenient I use an alias in my ~/.bash_aliases do to this:

alias pokydocker='docker run --rm -it -v ${PWD}:${PWD} pokyextended --workdir ${PWD}'

With this my workflow for starting a build is quite simple:

  • Create a new directory: mkdir my_new_build && cd my_new_build
  • Get all sources, I usually use googles “repo” tool to fetch multiple repositories.
  • Launch container: pokydocker
  • Source oe-init-build-env and start building

So the only overhead of using docker is running “pokydocker” from the directory to start the docker container, and I’m guaranteed to have the same environment regardless of my build host.

Leave a Reply

Your email address will not be published. Required fields are marked *