Docker is a powerful tool for building, deploying, and managing applications using containers. Docker provides a platform and ecosystem for developers and system administrators to create, distribute, and run containerized applications efficiently.
For information on how Docker compares to LXC, see Comparison between Docker and LXC |
Configure your project for Docker support:
Follow these steps to build an image with Docker support:
-
Edit your project’s
conf/bblayers.conf
configuration file and addmeta-virtualization
andmeta-filesystems
layers:conf/bblayers.conf/usr/local/dey-4.0/sources/meta-digi/meta-digi-arm \ /usr/local/dey-4.0/sources/meta-digi/meta-digi-dey \ + /usr/local/dey-4.0/sources/meta-virtualization \ + /usr/local/dey-4.0/sources/meta-openembedded/meta-filesystems \ "
-
Include virtualization in your project. Edit
conf/local.conf
, and add the following:conf/local.confDISTRO_FEATURES:append = " virtualization" IMAGE_INSTALL:append = " docker-ce"
Note the required white space when appending a value to an array variable using the :append
override syntax.
Build image with Docker support
-
Once you have configured your project for Docker support, build the image. For example:
$ bitbake core-image-base
Bitbaking an image recipe implies downloading and building the source code of all the recipes that form part of the root file system, which takes several hours the first time. Some source code repositories, such as the Linux kernel, represent a large download that might time out and make your build process fail. If this happens, run the following command to just fetch the source code of the offending recipe separately (to dedicate all CPU resources to it):
$ bitbake -k --runall=fetch <image-recipe>
When this task finishes successfully (you may need several retries), you can proceed to build your image recipe. Do the same with any recipe that fails with a timeout during the fetch operation.
Check the size of the resulting rootfs image, as it may not fit on the default rootfs partition. You may need to change the partition table. -
Program the resulting images as explained in Update firmware.
-
If you want to ensure your system is configured with Docker, you can use the
docker-info
command and verify the output.
Create a Docker container
Create a container from a pre-built image
DockerHub is a library of Docker images that contains a variety of distributions, releases, and architectures. Once you decide which image you want, run the following command:
# docker pull <dockerImage>
Where <dockerImage>
is the name of the DockerHub image.
Create a custom container with a DockerFile
You can also use a custom Dockerfile to generate a Docker image.
For example, the following Dockerfile creates a container with a base Ubuntu 22.04 image and installs several packages:
# Download base image ubuntu 22.04
FROM ubuntu:22.04
# Disable Prompt During Packages Installation
ARG DEBIAN_FRONTEND=noninteractive
# Update Ubuntu Software repository
RUN apt update
RUN apt upgrade -y
# Install nginx, php-fpm and supervisord from ubuntu repository
RUN apt install -y net-tools
RUN apt install -y iputils-ping
RUN apt install -y gpiod
Refer to the Docker documentation for more information on creating a Dockerfile.
Work with containers
# docker images
# docker ps --all
# docker start <container-name>
# docker attach <container-name>
# docker run <container-name>
# docker stop <container-name>
# docker rm <container-name>
# docker rmi <image-name>
Share native peripherals
You can define specific resources of the native device for your containers to use, such as network interfaces or GPIO pins. This allows for precise control over what resources a container can use.
Use the following arguments to share resources when you attach or run the container:
-
Resource constraints: Specify CPU and memory limits for a container using the
--cpus
and --memory
options, respectively. -
Networking configuration: Specify network settings such as port mappings, network modes, and hostnames using the
--network
and--hostname
options. -
Volume mounts: Mount host directories or volumes into a container using the
-v
or--mount
options to provide access to persistent data. -
Environment variables: Set environment variables inside a container using the
-e
or--env
options to configure application behavior. -
Health checks: Specify health check commands to monitor the health of a container using the HEALTHCHECK instruction in the Dockerfile or the
--health-cmd
option at runtime. -
Devices: Specify devices to limit the access of the container to a specific resource. For example, to specify a GPIO bank, use
--device=/dev/gpiochip9
.
Share a GPIO port
The following example shares GPIO10 port /dev/gpiochip9
of the native device with a container.
-
List the device on the native system to see its type (char, block…) and its major/minor numbers:
# ls -la /dev/gpiochip9 crw-rw---- 1 root digiapix 254, 9 Mar 20 10:01 /dev/gpiochip9
-
Run the following command to create and start the container:
# docker run -it --device=/dev/gpiochip9 --device-cgroup-rule='c 254:* rmw' --name <image-name> <container-name>
Share Ethernet
To share Ethernet between the native device and a Docker container, you can either share the native Ethernet or use a bridge.
Share the native Ethernet
This setup configures the container to directly share the native device’s primary network interface.
To do so, run the Docker container using the network of the native device:
# docker run --network host -it <image-name>
The container now has network access.
This approach is simpler but doesn’t isolate the network between the native device and the container. |
Use a bridge
This method creates a bridge on the native device and attaches the container’s virtual network interface to this bridge. Macvlan is a type of network driver in Docker and Linux networking that allows a container to have its own unique MAC address on the same network as the host. This effectively makes the container appear as a separate physical device on the network.
-
On the target, create a bridge named
br0
, attach the native device’s physical network interfaceeth0
to it, and obtain a dynamic IP:# ip link add name br0 type bridge # ip link set br0 up # ip addr flush dev eth0 # ip link set eth0 master br0 # ifconfig br0 up # udhcpc -i br0
-
Create a
macvlan
network in Docker:# docker network create -d macvlan --subnet=<your-network-subnet>/<your-network-mask> --gateway=<your-network-gateway> -o parent=br0 macvlan_net
Replace <your-network-subnet>/<your-network-mask> and <your-network-gateway> with your network’s subnet/mask and gateway.
-
Run the container using the macvlan network:
# docker run --network macvlan_net -it <image-name>