Building a QNX Container application image
In this section, you build a container application image.
Building a container application image starts with building a
regular QNX application using the conventions and tools defined in
Conventions for Recursive Makefiles and Directories
of the QNX OS Programmer's Guide
And then running the make command.
The following discussion assumes a simple application,
named hello-container,
which prints the message
Hello from a QNX container!
to stdout once a second.
Note:
Usage of the printfs command in your application
doesn't show up immediately in the container logs due to buffering.
There are ways to turn this off.
In your C applications, for example, you can call
setbuf() or fflush().
To convert the QNX application into a QNX Container application image,
you need to complete the following steps:
- Define a new Makefile, container.mk, at the same level as the common.mk, which contains the container build commands that gets appended to the install step.
- Define a new Dockerfile with the specifics of the container image to include files, environment variables, and the container process to launch.
- Run the make install command which uses the two new files to generate a local QNX Container application image.
The following example shows a sample container.mk
for hello-container application binary:
ifndef __NTO_VERSION
__NTO_VERSION=800
endif
CONTAINER_NAME = hello-container
INSTALLDIR := $(CONTAINER_NAME)/$(INSTALLDIR)
IMAGE_VER = v0
IMAGE_TAG = $(CONTAINER_NAME)-$(CPU)-qnx$(__NTO_VERSION):$(IMAGE_VER)
DOCKER_FILE = $(PROJECT_ROOT)/Dockerfile
DOCKER_IGNORE_FILE = $(PROJECT_ROOT)/.dockerignore
CONTAINER_INSTALL_DIR = $(INSTALL_ROOT_$(BUILD_TYPE))/$(CONTAINER_NAME)
define CONTAINER_CREATE
@$(CP_HOST) $(DOCKER_FILE) $(CONTAINER_INSTALL_DIR)
@$(CP_HOST) $(DOCKER_IGNORE_FILE) $(CONTAINER_INSTALL_DIR)
docker build -t $(IMAGE_TAG) $(CONTAINER_INSTALL_DIR) --build-arg="ARCH=$(CPU)" --build-arg="NTO_VER=$(__NTO_VERSION)" --platform=linux/$(CPU)
endef
POST_INSTALL = $(CONTAINER_CREATE)
define CONTAINER_DELETE
$(RM_HOST) -rf $(CONTAINER_INSTALL_DIR)
docker image rm -f $(IMAGE_TAG)
endef
POST_UNINSTALL = $(CONTAINER_DELETE)
This file instructs the QNX OS makefile system to do the
following steps on a make install:
- Install the build artifacts under the path, target/qnx8/nto/[arch]/<container_name>/usr/..., rather than the default path, target/qnx8/nto/[arch]/usr/...
- Copy the Dockerfile and the .dockerignore files to that same installation directory
- Run the docker build command from that directory to create the local QNX Container application image
In addition, on a make uninstall, the following results occurs:
- The target/qnx8/nto/[arch]/<container_name> path is removed
- The local QNX Container application image is deleted
To enable this new container.mk file,
add the following entry to the end of your common.mk file:
# Container configuration
include $(PROJECT_ROOT)/container.mk
Next, create Dockerfile
using the base image you created earlier:
ARG ARCH=x86_64
ARG NTO_VER=800
FROM qnx-base-${ARCH}:${NTO_VER}
ENV PATH=/proc/boot:/system/bin:/usr/bin
ENV LD_LIBRARY_PATH=/proc/boot:/system/lib
ADD . /
CMD ["/hello-container"]
And your .dockerignore as follows:
Dockerfile
.dockerignore
# Any other files we want the docker build to ignore when building the container image
The project directory should contain the following files:
- nto
- .dockerignore
- Dockerfile
- Makefile
- common.mk
- container.mk
- hello-container.c
- hello-container.use
Running a make install command from this
directory should produce your local QNX Container application image -
one for each architecture specified in your nto folder:
make install
make -Cnto -fMakefile install
make[1]: Entering directory ...
make -Caarch64 -fMakefile install
...
docker build -t hello-container-aarch64-qnx800:v0 ... --build-arg="ARCH=aarch64" --build-arg="NTO_VER=800" --platform=linux/aarch64
[+] Building 0.2s (7/7) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 235B 0.0s
=> [internal] load metadata for docker.io/library/qnx-base-aarch64:800 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 77B 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 12.20kB 0.0s
=> [1/2] FROM docker.io/library/qnx-base-aarch64:800 0.0s
=> [2/2] ADD . / 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:02f18a6674dde6c35605cc01cc56a3def28502a406d6e4851218a563d6ccc016 0.0s
=> => naming to docker.io/library/hello-container-aarch64-qnx800:v0 0.0s
make[2]: Leaving directory ...
make -Cx86_64 -fMakefile install
...
docker build -t hello-container-x86_64-qnx800:v0 ... --build-arg="ARCH=x86_64" --build-arg="NTO_VER=800" --platform=linux/x86_64
[+] Building 0.1s (7/7) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 235B 0.0s
=> [internal] load metadata for docker.io/library/qnx-base-x86_64:800 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 77B 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 11.83kB 0.0s
=> [1/2] FROM docker.io/library/qnx-base-x86_64:800 0.0s
=> [2/2] ADD . / 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:cab3e5f365175ce5057ae80fcffe0673941af61f93099e9f519c79d4b96c4572 0.0s
...
❯ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-container-x86_64-qnx800 v0 cab3e5f36517 3 seconds ago 4.34MB
hello-container-aarch64-qnx800 v0 02f18a6674dd 3 seconds ago 4.23MB
CAUTION:
By default, container image files are owned by root,
unless otherwise defined in the Dockerfile.
If qcmgr is given -U and -G
options to restrict the UID or GID of the extracted files as part of a container image,
then make sure that the ranges given to qcmgr include 0,
or make sure that the owners (users or groups) of the container image files are
part of the permitted range specified in the arguments of qcmgr.
Page updated:
