Skip to main content
Version: 6

Deploy Application in a Container Using a Custom-built Image - The Advanced Way

Overview

Up to this point, you have been running pre-existing container images from Docker Hub, built by Toradex or other third parties. That is very good and sometimes you will choose to use container images as they are provided. On the other hand, sometimes you will need to customize a container image with additional libraries, tools, and your own application. Dockerfiles are used for this.

In this section, you will:

  • Write a Dockerfile.
  • Build a Docker image from the Dockerfile.
  • Upload the image to Docker Hub.
  • Upload the docker image to Docker Hub.
  • Pull the docker image from Docker Hub in your target device.
  • Run the image on the device.
Typographic Conventions

Throughout the Toradex documentation, the following typographic conventions are used:

$ (dollar sign) Command in the host computer (e.g. your PC)

$ Command in your PC

$$ (double dollar sign) Command in a container in the host computer (e.g. your PC)

$$ Command inside a container in your PC

# (hashtag) Command in the target device/board (e.g. Linux terminal)

# Command in the target board, e.g. Colibri iMX6

## (double hashtag) Command inside a container in the target device (Torizon)

## Command inside a container in Torizon

> (greater-than sign) Command in the bootloader (e.g. U-Boot console)

> Command in the Bootloader

No symbol: Command output

$ Command waiting for output
Output

Prerequisites

Step 1

caution

A standard Dockerfile has no extension, therefore make sure your file is not named Dockerfile.txt. Consult this lesson's FAQ for details about naming.

info

If you wish, modify the Dockerfile to include more commands, such as RUN apt install -y python.

In this example, the FROM command shows where to get the base of our Docker image. It is important to specify the platform correctly to ensure compatibility with the target device. You will also use some RUN commands to install the necessary packages from Debian feeds and test that the build process works correctly.

Step 2

Step 3

Enter the previously created quickstart folder and build the image:

$ cd ~/quickstart
$ docker build --pull -t <username>/qs-torizon .

Note that this <username> is your Docker Hub username.

Step 4

Upload the image to your Docker Hub:

$ docker push <username>/qs-torizon

Now your custom container image is accessible from Docker Hub just like the other images you've used until this lesson.

caution

The next steps provides commands for you to run in the target device.

Step 5

On the board, make sure there are no running containers:

# docker stop $(docker ps -a -q)

Step 6

Pull the image you just pushed to Docker Hub (See the previous lesson if you didn't) :

# docker pull <username>/qs-torizon

You can use the same command above to pull new container image versions every time a new one is pushed to Docker Hub.

Step 7

The following command starts a new container based on the Docker image and opens the new container's terminal:

# docker run --rm -it -v /var/run/dbus:/var/run/dbus -v /dev:/dev <username>/qs-torizon

Step 8

Check that the package you've installed in the Dockerfile is available in this new container:

## nano

You are now inside the nano text editor. Press Ctrl + x to exit it.

info

Since all the containers are run with the flag --rm, the changes made inside the container after its creation will be lost when the container exits. To keep data, one needs to use methods to store data outside the container, for example, by using bind mounting.

Step 9

You can exit the container by either typing exit on the command-line or by pressing Ctrl + d:

## exit

FAQ

What is a Dockerfile?

A Dockerfile is a text file containing instructions for building a Docker image. At the Docker Documentation there is a lot of information about them, and guidelines which we will use in this article.

This is a sample Dockerfile:

Dockerfile
# Points to a base, pre-existing image. In this case, it points to the [ubuntu container](https://hub.docker.com/_/ubuntu), tagged with version 18.04;
FROM ubuntu:18.04

# Copies files from the host machine to the created image;
COPY script.sh /root

# Runs commands as root on the created image;
RUN apt update && apt install nano

# Specifies what command will run when a new container is created based on the resulting image.
CMD [ "./startup.sh" ]
caution

Be aware that the resulting image will be compatible with the host system architecture only, by default.

What does the created Dockerfile do?
  1. The FROM command shows where to get the base of our Docker image. If you want to cross-build it, make sure to choose a pre-built image for ARM.
  2. We run some commands to install packages from Debian feeds, to test if the cross-build really works.
  3. Starts the X server, so we can have a graphical user interface.
Can I have multiple Dockerfiles with different names?

Yes, you can. The docker build command allows you to specify a different name for your Dockerfile. This feature allows you to have separate Dockerfiles for development and production or for different base images, such as Python vs. Python Slim or the latest stable vs. the bleeding edge release of a distribution. For example for a Dockerfile named foo.Dockerfile:

$ docker build -f foo.Dockerfile .

Any name is acceptable, though you may consider using a standard. Some Visual Studio Code plugins automatically have syntax highlighting for files with the .Dockerfile extension, like prod.Dockerfile and dev.Dockerfile.

What does `docker ps -a -q` do?

The fastest way to understand it is by running docker ps --help, either on the board or your computer:

$ docker ps --help

Usage: docker ps [OPTIONS]

List containers

Options:
-a, --all Show all containers (default shows just running)
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print containers using a Go template
-n, --last int Show n last created containers (includes all states) (default -1)
-l, --latest Show the latest created container (includes all states)
--no-trunc Don't truncate output
-q, --quiet Only display numeric IDs
-s, --size Display total file sizes

Alternatively, you can consult the online Docker documentation that is more comprehensive, and has some usage examples:



Send Feedback!