Creating a Custom Docker Image

You are viewing an old version of this article. View the current version here.

Docker containers are created from images. An image contains software that can be launched, including the underlying system. A container is an instance of that software.

When we want to automate MariaDB, creating an image with MariaDB and the desired configuration, we may want to create an image by ourselves, which fulfils our needs.

Images Architecture

The source code of a Docker image is a Dockerfile. A Dockerfile is written in Docker specific language, and can be compiled into an image by the docker binary, using the docker build command.

Most images are based on another image. The base image is specified at the beginning of the Dockerfile, with the FROM directive. If the base image is not present in the local system, it is downloaded from Dockerhub. For example, we can build an mariadb-rocksdb:10.5 image starting from the debian:13 image. In this way, we'll have all the software included in a standard Debian image, and we'll add MariaDB and its configuration upon that image.

All the following Dockerfile directives are compiled into a new Docker image, identified by an MD5 string. Each of these images is based on the image compiled from the previous directive. A physical compiled image can serve as a base for any number of images. This mechanism saves a lot of disk space, download time and build time.

Dockerfile Syntax

Here's a simple Dockerfile example:

FROM ubuntu:20.04

RUN apt-get update
RUN apt-get install -y mariadb-server
RUN systemctl stop mariadb

EXPOSE 3306

LABEL version="1.0"
LABEL description="MariaDB Server"

CMD ["mysqld_safe"]

This example is not very good for practical purposes, but it shows how a Dockerfile looks like.

First, we declare that the base image to use is ubuntu:20.04.

Then we run some commands to install MariaDB from Ubuntu default repositories and stop the MariaDB service.

We define some metadata about the image with LABEL. Any label is valid.

We declare that the port 3306 (MariaDB default port) should be exposed. However, this has no effect if the port is not exposed at container creation.

Finally, we start the container command: mysqld_safe. This command is run when a container based on this image starts. When the process stops or crashes, the container will immediately stop.

See the documentation links below to learn the syntax allowed in a Dockerfile.

Using Variables

It is possible to use variables in a Dockerfile. This allows, for example, to install different packages, install different versions of a package, or configure software differently depending on how variables are set, without modifying the Dockerfile itself.

To use a variable, we can do something like this:

FROM ubuntu:20.04

ARG MARIADB_CONFIG_FILE
ARG MARIADB_DATABASE=db1

RUN mysql mysqld_safe --defaults-file=$MARIADB_CONFIG_FILE &
RUN mysql -e 'CREATE DATABASE $MARIADB_DATABASE;'

Here ARG is used after the FROM directive, thus the variable cannot be used in FROM. It is also possible to declare a variable before FROM, so we can use a variable to select the base image to use or its tag, but in this case the variable cannot be used after the FROM directive. Here is an example:

ARG UBUNTU_VERSION
FROM ubuntu:$UBUNTU_VERSION

# But this will cause a build error:
RUN echo 'Ubuntu version: $UBUNTU_VERSION' > /var/build_log

We'll have to assign variables a value when we build the Dockerfile, in this way:

docker build --build-arg UBUNTU_VERSION=20.04 .

Publishing and Pulling Images

Good Practices and Caveats

References

More details can be found in the Docker documentation:


Content initially contributed by Vettabase Ltd.

Comments

Comments loading...
Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.