Skip to main content

Docker & containers

For a general understanding of what Docker and Container is, have a look at What is a Container or a more in-depth presentation from the Stavanger playground.

Other resources could be the official Docker documentation.

Security

Running as non-root

Application hosted on Radix must be run with non-root privileges in the container. A security policy enabled in the Radix platform will prevent the application from running if it is not configured to run as non-root. Here's an sample on how you can run change a Docker container to run as a non-root user, the principle is that you create a dedicated user and group on the image and use this user to run the process.

tip

If this is not configured, your deployment will not start.

If your base image is a unprivileged image, you'll need to find the ID of the running user, and use that id in your Dockerfile.

USER [USER_ID] specifies which user to run as, this must be the ID of the user, not the name. This will ensure that Kubernetes can verify that the container is running as a non-root user.

This is a sample on how it can be done for node alpine based images.

FROM node:lts-alpine

WORKDIR /src

COPY . /src

# Add a new group "radix-non-root-group" with group id 1001
RUN addgroup -S -g 1001 radix-non-root-group

# Add a new user "radix-non-root-user" with user id 1001 and include in group
RUN adduser -S -u 1001 -G radix-non-root-group radix-non-root-user

USER 1001
EXPOSE 8001

The ID of the group and user can be anything in the range 1000-65535.

groupadd command follows the syntax groupadd -S -g [GROUP_ID] [GROUP-NAME]

useradd command follows the syntax useradd -S -u [USER_ID] -g [GROUP_NAME] [USER_NAME]

Be aware

The syntax for add user and group can be different for the distribution of images

There are many great articles on securing docker images. See Snyk.

Use immutable (read-only) root filesystem

An immutable root filesystem prevents applications from writing to the local disk. This is desirable, if an intrusion from an attacker, the attacker will not be able to tamper with the filesystem or write foreign executables to disk.

The container's root filesystem should be treated as a golden image by using Docker run's --read-only option. This prevents any writes to the container's root filesystem at container runtime and enforces the principle of immutable infrastructure.

The Radix equivalent to Docker's --read-only is the readOnlyFileSystem property in radixconfig.yaml.

Best-practice Dockerfile

The official Docker documentation has a set of best practices when it comes to creating Dockerfiles. This is often related to optimizing build, push and pull speed and creating small and secure images.

Limit image size

Many of the best practices are connected to creating small images either through using the "correct" BASE image or through Multistage builds.

Small images will be faster to build, push and pull then bigger images. It will have less frameworks dependencies, and therefore smaller risk of security vulnerabilities and bugs. Google cloud platform have a great video on why and how to create small images - link, or you can check the official doc.

Try to find a guide for the technology stack you work on, to optimize your container further.

Layers

Docker build speed can be reduced by understanding caching of layers. In short, each line in the Dockerfile can be seen as a layer for the finished image. Docker caches these layers and, if there are no changes, can reuse the cached version when building several times. See digging-into-docker-layers for more information.

Radix specific

Testing

Automatic testing of an application can be done as a build stage inside the container. This will then be run as one of the steps when radix build the image.