Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
When using containers in production, it is important to be aware of container security concerns.
Depending on the container runtime, containers may be running on the host system's kernel or a kernel shared with other containers. If this kernel has security bugs, those bugs are also present in the containers. Malicious containers may attempt to explain a kernel vulnerability to impact the confidentiality, integrity or availability of other containers.
In particular, Linux based containers have a container runtime that can use the following features:
Namespaces, to isolate containers from each other and make sure that a container can't establish unauthorized connections to another container.
.
, or
, to limit the resources (CPU, memory, IO) that each container can consume.
The administrators of a system should be particularly careful to upgrade the kernel whenever security bugs to these features are fixed.
It is important to note that when we upgrade the kernel, runC or Docker itself we cause downtime for all the containers running on the system.
Containers are built from images. If security is a major concern, you should make sure that the images you use are secure.
If you want to be sure that you are pulling authentic images, you should only pull images signed with . Signing only ensure authenticity or origin, it doesn't dictate that entity is trustworthy.
Updated images should be used. An image usually downloads packages information at build time. If the image is not recently built, a newly created container will have old packages. Updating the packages on container creation and regularly re-updating them will ensure that the container uses packages with the most recent versions. Rebuilding an image often will reduce the time necessary to update the packages the first time.
Security bugs are usually important for a database server, so you don't want your version of MariaDB to contain known security bugs. But suppose you also have a bug in Docker, in runC, or in the kernel. A bug in a user-facing application may allow an attacker to exploit a bug in those lower level technologies. So, after gaining access to the container, an attacker may gain access to the host system. This is why system administrators should keep both the host system and the software running in the containers updated.
For more information, see the following links:
from Red Hat.
on Docker documentation.
Content initially contributed by .
This page is licensed: CC BY-SA / Gnu FDL
MariaDB has many plugins. Most are not enabled by default, some are in the mariadb container, while others need to be installed from additional packages.
The following methods summarize Installing plugins in the MariaDB Docker Library Container (mariadb.org blog post) on this topic.
To see which plugins are available in the mariadb:
Using the --plugin-load-add flag with the plugin name (can be repeated), the plugins will be loaded and ready when the container is started:
For example, to enable the simple\_password\_check plugin:
plugin-load-add` can be used as a configuration option to load plugins. The example below loads the .
can be used to install a plugin as part of the database initialization.
Create the SQL file used in initialization:
In this case, the my\_initdb is a /docker-entrypoint-initdb.d directory per "Initializing a fresh instance" section above.
A number of plugins are in separate packages to reduce their installation size. The package names of MariaDB-created plugins can be determined using the following command:
A new image needs to be created when using additional packages. The mariadb image can however be used as a base:
In the following, the is installed:
Installing plugins from packages creates a configuration file in the directory /etc/mysql/mariadb.conf.d/ that loads the plugin on startup.
This page is licensed: CC BY-SA / Gnu FDL
Containers are an OCI standard format for software images and their specified time all bundled up into a single distributable time. They can be used for production, development or testing.
Docker Inc. run a program to provide users with an essential base implementation of MariaDB in a container and to exemplify best practices of a container.
The containers are as docker.io/library/mariadb though many container runtime implementation will fill in the docker.io/library where the host/path isn't specified.
The containers are in a Open Container Initiative format that allows the containers to be interoperable with a number of container runtime implementations. Docker, or more fully Docker Engine, is just one of the many available runtimes.
Many people use MariaDB Docker Official Image containers in CI systems like GitHub Actions, though its possible to use these in production environments like kubernetes.
The MariaDB Server container images are available with a number of tags:
$ docker run --rm mariadb:latest ls -C /usr/lib/mysql/pluginA major version like 10.11
The most recent stable GA version - latest
The most recent stable LTS version - lts
Versions that aren't stable will be suffixed with -rc, or -alpha to clearly show their release status, and enables Renovatebot and other that follow semantic versioning to follow updates.
For a consistent application between testing an production environment using the SHA hash of the image is recommended like docker.io/library/mariadb@sha256:29fe5062baf36bae8ec68f21a3dce4f0372dadc185e687624f1252fc49d91c67. There is a list of mapping and history of tags to SHA hash on the Docker Library repository.
In this page we'll discuss why automating containers with software like Ansible or Puppet may be desirable in some cases. To talk about this, we'll first need to discuss why containers are defined ephemeral, and how this applies to containerized database servers (particularly MariaDB).
During the discussion, we should keep in mind that Docker Engine, CRI-I, containerd, Mirantis Container Runtime, Podman and other OCI container runtimes can be used to setup production and/or development environments. These use cases are very different from a database perspective: a production database may be big, and typically contains data that we don't want to lose. Development environments usually contain small sample data that can be rebuilt relatively quickly. This page focuses on the latter case.
Images are an OCI specified format that can be compiled from Dockerfiles as one of the ways. Containers are the way of creating a runtime version of an images. Normally, a container is not modified from the moment it is created. In other words, containers are usually designed to be ephemeral, meaning that they can be destroyed and replaced with new containers at any time. Provided that there is proper redundancy (for example, there are several web servers running the same services) destroying one container and starting a new one of the same type won't cause any damage.
We will discuss a bit later how this applies to MariaDB, and more generally to database servers.
When something should change, for example some software version or configuration, normally Dockerfiles are updated and containers are recreated from the latest image versions. For this reason, containers shouldn't contain anything that shouldn't be lost, and recreating them should be an extremely cheap operation. Docker Compose or the Swarm mode are used to declare which containers form a certain environment, and how they communicate with each other.
On the contrary, Ansible and Puppet are mainly built to manage the configuration of existing servers. It doesn't recreate servers, it changes their configuration. So Docker and Ansible have very different approaches. For this reason, Ansible and Puppet are not frequently used to deploy containers to production. However, using them together can bring some benefits, especially for development environments.
More on this later in the page. First, we need to understand how these concepts apply to database servers.
Using ephemeral containers works very well for stateless technologies, like web servers and proxies. These technologies virtually only need binaries, configuration and small amounts of data (web pages). If some data need to be restored after a container creation, it will be a fast operation.
In the case of a database, the problem is that data can be large and need to be written somewhere. We don't want all databases to disappear when we destroy a container. Even if we had an up-to-date backup, restoring it would take time.
However, OCI Containers has features called volumes. A volume is a directory in the host system mapped to a directory in one or more containers. Volumes are not destroyed when containers are destroyed. They can be used to share data between any number of containers and the host system. Therefore, they are also a good way to persist data.
Suppose a MariaDB container called mariadb-main-01 uses a volume that is mapped to /var/docker/volumes/mariadb-main. At some point we want to use a more recent MariaDB version. As explained earlier, the container way to do this is to destroy the container and create a new one that uses a more recent version of the MariaDB image.
So, we will destroy mariadb-main-01. The volume is still there. Then we create a new container with the same name, but based on a newer image. We make sure to link the volume to the new container too, so it will be able to use /var/docker/volumes/mariadb-main again. At this point we may want to run , but apart from that, everything should just work.
The container runtime implementations also provide the opportunity to create a volume with an explicit name and this is also persistent. The actual location on the filesystem is managed by the runtime.
The above described steps are simple, but running them manually is time consuming and error-prone. Automating them with some automation software like Ansible or Puppet is often desirable.
Containers can be deployed in the following ways:
Manually. See . This is not recommended for production, or for complex environments. However, it can easily be done for the simplest cases. If we want to make changes to our , we'll need to modify the Dockerfiles, destroy the containers and recreate them.
With Docker Compose. See for a simple example. When we modify a Dockerfile, we'll need to destroy the containers and recreate them, which is usually as simple as running docker compose down followed by docker compose up. After changing docker-cmpose.yml (maybe to add a container or a network) we'll simply need to run docker compose up again, because it is idempotent.
In all these cases, it is entirely possible to add to the picture. Vagrant is a way to deploy or provision several hosts, including virtual machines (the most common case), and containers. It is agnostic in regarding the underlying technology, so it can deploy to a virtual machine, a container, or even a remote server in the same way. Containers can work with Vagrant in two ways:
As a . In this case Vagrant will most commonly deploy a virtual machine, and will use Docker to setup the applications that need to run in it, as containers. This guarantees a higher level of isolation, compared to running the containers in the local host. Especially if you have different environments to deploy locally, because you can have them on different virtual machines.
As a . Vagrant will deploy one or more containers locally. Once each container is up, Vagrant can optionally use a provisioner on it, to make sure that the container runs the proper software with proper configuration. In this case, Ansible, Puppet or other automation software can be used as a provisioner. But again, this is optional: it is possible to make changes to the Dockerfiles and recreate the containers every time.
Containers can be entirely managed with Docker Compose or the Swarm mode. This is often a good idea.
However, choosing to use automation software like Ansible or Puppet has some benefits too. Benefits include:
Containers allow working without modifying the host system, and their creation is very fast. Much faster than virtual machines. This makes containers desirable for development environments.
As explained, making all containers ephemeral and using volumes to store important data is possible. But this means adding some complexity to adapt an ephemeral philosophy to technologies that are not ephemeral by nature (databases). Also, many database professionals don't like this approach. Using automation software allows easily triggering upgrades and configuration changes in the containers, treating them as non-ephemeral systems.
Sometimes containers are only used in development environments. If production databases are managed via Ansible, Puppet, or other automation software, this could lead to some code duplication. Dealing with configuration changes using the same procedures will reduce the cost of maintenance.
With all this in mind, let's see some examples of cases when managing containers with Ansible, Puppet or other automation software is preferable, rather than destroying containers every time we want to make a change:
We use Ansible or Puppet in production, and we try to keep development environments as similar as possible to production. By using Ansible/Puppet in development too, we can reuse part of the code.
We make changes to the containers often, and recreating containers is not as fast as it should be (for example because a MariaDB needs to be restored).
Creating a container implies some complex logic that does not easily fit a Dockerfile or Docker Compose (including, but not limited to, running multiple processes per container).
That said, every case is different. There are environments where these advantages do not apply, or bring a very small benefit. In those cases, the cost of adding some automation with Ansible, Puppet or similar software is probably not justified.
Suppose you want to manage containers configuration with Ansible.
At a first glance, the simplest way is to run Ansible in the host system. It will need to connect to the containers via SSH, so they need to expose the 22 port. But we have multiple containers, so we'll need to map the 22 port of each container to a different port in the host. This is hard to maintain and potentially insecure: in production you want to avoid exposing any container port to the host.
A better solution is to run Ansible itself in a container. The playbooks will be in a container volume, so we can access them from the host system to manage them more easily. The Ansible container will communicate with other containers using a container network, using the standard 22 port (or another port of your choice) for all containers.
See these pages on how to manage containers with different automation technologies:
.
.
Content initially contributed by .
This page is licensed: CC BY-SA / Gnu FDL
$ docker run --name some-%%REPO%% -e MARIADB_ROOT_PASSWORD=my-secret-pw --network=host -d mariadb:latest --plugin-load-add=simple_password_check$ printf "[mariadb]\nplugin-load-add=ha_federatedx\n" > /my/custom/federatedx.conf
$ docker run --name some-mariadb -v /my/custom:/etc/mysql/conf.d -e MARIADB_ROOT_PASSWORD=my-secret-pw -d mariadb:latest$ echo 'INSTALL SONAME "disks";' > my_initdb/disks.sql$ docker run --rm mariadb:latest sh -c 'apt-get update -qq && apt-cache search mariadb-plugin'FROM mariadb:latest
RUN apt-get update && \
apt-get install mariadb-plugin-connect -y && \
rm -rf /var/lib/apt/lists/*Using Ansible, Puppet or other automation software, as mentioned before. We can use Ansible or Puppet to create the containers, and run them again every time we want to apply some change to the containers. This means that the containers are potentially created once and modified any number of times.
While recreating containers is fast, being able to apply small changes with Ansible or Puppet can be more convenient in some cases: particularly if we write files into the container itself, or if recreating a container bootstrap involves some lengthy procedure.
Trying to do something non-standard with Dockerfiles can be tricky. For example, running two processes in a container is possible but can be problematic, as containers are designed to run single main process per container. However there are situations when this is desirable. For example PMM containers run several different processes. Launching additional processes with Ansible or Puppet may be easier than doing it with a Dockerfile.
MariaDB databases in containers need backup and restore like their non-container equivalents.
In this section, we will assume that the MariaDB container has been created as follows:
is in the Docker Official Image and can be used as follows:
For restoring data, you can use the following docker exec command:
is in the Docker Official Image.
mariadb-backup can create a backup as follows:
To perform a backup using , a second container is started that shares the original container's data directory. An additional volume for the backup needs to be included in the second backup instance. Authentication against the MariaDB database instance is required to successfully complete the backup. In the example below, a mysql@localhost user is used with the MariaDB server's Unix socket shared with the backup container.
Note: Privileges listed here are for 10.5+. For an exact list, see .
mariadb-backup will run as the mysql user in the container, so the permissions on /backup will need to ensure that it can be written to by this user:
These steps restore the backup made with mariadb-backup.
At some point before doing the restore, the backup needs to be prepared. The prepare must be done with the same MariaDB version that performed the backup. Perform the prepare like this:
Now that the image is prepared, start the container with both the data and the backup volumes and restore the backup. The data directory must be empty to perform this action:
With mariadb_restore volume containing the restored backup, start normally as this is an initialized data directory. At this point a later version of <mariadb-image> container can be used:
On the environment variables here:
here in addition to upgrading the system tables ensures there is a .
MARIADB_ROOT_PASSWORD is a convenience if any scripts, like logical backup above, use the environment variable. This environment variable is not strictly required.
For further information on mariadb-backup, see .
This page is licensed: CC BY-SA / Gnu FDL
$ docker volume create mariadb_data
$ docker volume create mariadb_backup
$ docker run --rm \
-v mariadb_data:/var/lib/mysql \
-v mariadb_backup:/backup \
mariadb \
chown -R mysql:mysql /var/lib/mysql /backup
$ docker run -d --name mariadb \
-v mariadb_data:/var/lib/mysql \
-v mariadb_backup:/backup \
-e MARIADB_ROOT_PASSWORD='MariaDB11!' \
<mariadb-image>$ docker exec mariadb \
sh -c 'mariadb-dump --all-databases -u root -p"$MARIADB_ROOT_PASSWORD" > backup/db.sql'$ docker exec mariadb \
sh -c 'mariadb -u root -p"$MARIADB_ROOT_PASSWORD" < backup/db.sql'$ docker volume create mariadb_data
$ docker volume create mariadb_backup
$ docker run --rm \
-v mariadb_data:/var/lib/mysql \
-v mariadb_backup:/backup \
mariadb \
chown -R mysql:mysql /var/lib/mysql /backup
$ docker run -d --name mariadb \
-v mariadb_data:/var/lib/mysql \
-v mariadb_backup:/backup \
-e MARIADB_ROOT_PASSWORD='MariaDB11!' \
-e MARIADB_MYSQL_LOCALHOST_USER=1 \
-e MARIADB_MYSQL_LOCALHOST_GRANTS='RELOAD, PROCESS, LOCK TABLES, BINLOG MONITOR' \
<mariadb-image>$ docker exec --user mysql mariadb mariadb-backup --backup --target-dir=backup$ docker run --rm \
--name mariadb-restore \
-v mariadb_backup:/backup \
<mariadb-image> \
mariadb-backup --prepare --target-dir=backup$ docker volume create mariadb_restore
$ docker run --rm \
-v mariadb_restore:/var/lib/mysql \
--name mariadb-restore-change-permissions \
<mariadb-image> \
chown mysql: /var/lib/mysql
$ docker run --rm \
--name mariadb-restore \
-v mariadb_restore:/var/lib/mysql \
-v mariadb_backup:/backup \
--user mysql \
<mariadb-image> \
mariadb-backup --copy-back --target-dir=backup$ docker run -d --name mariadb \
-v mariadb_restore:/var/lib/mysql \
-e MARIADB_AUTO_UPGRADE=1 \
-e MARIADB_ROOT_PASSWORD='MariaDB11!' \
<mariadb-image>When you start the image, you can adjust the initialization of the MariaDB Server instance by passing one or more environment variables on the docker run command line. Do note that all of the variables below, except MARIADB_AUTO_UPGRADE, will have no effect if you start the container with a data directory that already contains a database: any pre-existing database will always be left untouched on container startup.
All tags from 10.6 and above, MARIADB_* variables will be used in preference to MYSQL_* variables.
One of the following is required: MARIADB_ROOT_PASSWORD_HASH, MARIADB_ROOT_PASSWORD, MARIADB_ALLOW_EMPTY_ROOT_PASSWORD, or MARIADB_RANDOM_ROOT_PASSWORD (including *_FILE equivalents).
Other environment variables are optional.
MARIADB_ROOT_PASSWORD_HASH / MARIADB_ROOT_PASSWORD / MYSQL_ROOT_PASSWORDThis specifies the password that will be set for the MariaDB root superuser account.
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD / MYSQL_ALLOW_EMPTY_PASSWORDSet to a non-empty value, like 1, to allow the container to be started with a blank password for the root user.
Setting this variable to yes is not recommended unless you really know what you are doing, since this will leave your MariaDB instance completely unprotected, allowing anyone to gain complete superuser access.
MARIADB_RANDOM_ROOT_PASSWORD / MYSQL_RANDOM_ROOT_PASSWORDDefine a non-empty value, such as "yes," to auto-generate a random initial password for the root user. The password will be output to stdout, prefixed with "GENERATED ROOT PASSWORD: ...".
MARIADB_ROOT_HOST / MYSQL_ROOT_HOST% is the default hostname part of the root user in MariaDB. This can be changed to any valid hostname. Setting it to localhost restricts root access to only the local machine via the Unix socket.
MARIADB_DATABASE / MYSQL_DATABASEThis variable allows you to specify the name of a database to be created on image startup.
MARIADB_USER / MYSQL_USER, MARIADB_PASSWORD_HASH / MARIADB_PASSWORD / MYSQL_PASSWORDTo create a new user with full access permissions in MariaDB, both user and password variables are required, along with a designated database. This new user will be granted comprehensive privileges (GRANT ALL) to the specified MARIADB_DATABASE. Note that this method should not be utilized for creating the root superuser, as this user is automatically created with the password provided by the MARIADB_ROOT_PASSWORD or MYSQL_ROOT_PASSWORD variable.
MARIADB_MYSQL_LOCALHOST_USER / MARIADB_MYSQL_LOCALHOST_GRANTSSet MARIADB_MYSQL_LOCALHOST_USER to a non-empty value to create the mysql@localhost database user. This user is useful for health checks and backup scripts. The mysql@localhost user gets USAGE privileges by default. If more access is needed, additional global privileges can be provided as a comma-separated list. Be cautious when sharing a volume containing MariaDB's unix socket (/var/run/mysqld by default) as privileges beyond USAGE may pose security risks. This user can also be used with mariadb-backup. Refer to healthcheck.sh for required privileges for each health check test.
MARIADB_HEALTHCHECK_GRANTSSet MARIADB_HEALTHCHECK_GRANTS to the grants required to be given to the healthcheck@localhost, healthcheck@127.0.0.1, healthcheck@::1, users. When not specified the default grant is .
The main value used here will be [REPLICA MONITOR](../../../../../reference/sql-statements-and-structure/sql-statements/account-management-sql-commands/grant.md#replica-monitor) for the [healthcheck --replication](using-healthcheck-sh.md) test.
MARIADB_INITDB_SKIP_TZINFO / MYSQL_INITDB_SKIP_TZINFOBy default, the entrypoint script automatically loads the timezone data needed for the CONVERT_TZ() function. If it is not needed, any non-empty value disables timezone loading.
MARIADB_AUTO_UPGRADE / MARIADB_DISABLE_UPGRADE_BACKUPSet MARIADB_AUTO_UPGRADE to a non-empty value to have the entrypoint check whether needs to run, and if so, run the upgrade before starting the MariaDB server.
Before the upgrade, a backup of the system database is created in the top of the datadir with the name system_mysql_backup_*.sql.zst. This backup process can be disabled by setting MARIADB_DISABLE_UPGRADE_BACKUP to a non-empty value.
If MARIADB_AUTO_UPGRADE is set, and the .my-healthcheck.cnf file is missing, the healthcheck users are recreated if they don't exist, MARIADB_HEALTHCHECK_GRANTS grants are given, the passwords of the healthcheck users are reset to a random value and the .my-healthcheck.cnf file is recreated with the new password populated.
MARIADB_MASTER_HOSTWhen specified, the container will connect to this host and replicate from it.
MARIADB_REPLICATION_USER / MARIADB_REPLICATION_PASSWORD_HASH / MARIADB_REPLICATION_PASSWORDWhen MARIADB_MASTER_HOST is defined, MARIADB_REPLICATION_USER and MARIADB_REPLICATION_PASSWORD will be used to connect to the master. When not specified, the MARIADB_REPLICATION_USER will be created with the REPLICATION REPLICA grants needed for a client to initiate replication.
This page is licensed: CC BY-SA / Gnu FDL
To start the container in the background with the MariaDB server image, run:
Additionally, environment variables are also provided.
Note: specify the flag -a in case you want to see all containers
To start the mariadb client inside the created container and run specific commands, run the following:
In the logs you can find status information about the server, plugins, generated passwords, errors and so on.
One can specify custom configuration files through the /etc/mysql/conf.d volume during container startup.
User created with the environment variables has full grants only to the MARIADB_DATABASE. In order to override those grants, one can specify grants to a user, or execute any SQL statements from host file to docker-entrypoint-initdb.d. In the local_init_dir directory we can find the file, created like this:
This page is licensed: CC BY-SA / Gnu FDL
$ docker images -a$ docker network create mynetwork$ docker run --rm --detach \
--env MARIADB_ROOT_PASSWORD=sosecret \
--network mynetwork \
--name mariadb-server \
mariadb:latest$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ad374ec8a272 mariadb:latest "docker-entrypoint.s…" 3 seconds ago Up 1 second 3306/tcp mariadb-server$ docker exec -it mariadb-server mariadb -psosecret -e "SHOW PLUGINS"$ docker logs mariadb-server$ docker restart mariadb-server$ docker exec -it mariadb-server bash$ docker run --detach --env MARIADB_USER=anel \
--env MARIADB_PASSWORD=anel \
--env MARIADB_DATABASE=my_db \
--env MARIADB_RANDOM_ROOT_PASSWORD=1 \
--volume $PWD/my_container_config:/etc/mysql/conf.d:z \
--network mynetwork \
--name mariadb-server1 \
mariadb:latest$ docker run --detach --env MARIADB_USER=anel\
--env MARIADB_PASSWORD=anel \
--env MARIADB_DATABASE=my_db \
--env MARIADB_RANDOM_ROOT_PASSWORD=1 \
--volume $PWD/my_init_db:/docker-entrypoint-initdb.d \
--network mynetwork \
--name mariadb-server1 \
mariadb:latest$ echo "GRANT ALL PRIVILEGES ON *.* TO anel;" > my_init_db/my_grants.sqlOCI containers, frequently and incorrectly called Docker containers, are created from OCI 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.
One "source code" of an 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. It can also be compiled by buildah using buildah bud.
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 the repository specified, or if not specified, from the default repository of the build program. This is often Docker Hub. For example, we can build a 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 SHA256 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.
The following diagram shows the relationship between Dockerfiles, images and containers:
Here's a simple Dockerfile example:
This example is not very good for practical purposes, but it shows what 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 the 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.
We also define a healthcheck. This is a command that is run to check if the container is healthy. If the return code is 0 the healthcheck succeeds, if it's 1 it fails. In the MariaDB specific case, we want to check that it's running and able to answer a simple query. This is better than just checking that MariaDB process is running, because MariaDB could be running but unable to respond, for example because was reached or data si corrupted. We read a system variable, because we should not assume that any user-created table exists. We also specify --start-period to allow some time for MariaDB to start, keeping in mind that restarting it may take some time if some data is corrupted. Note that there can be only one healthcheck: if the command is specified multiple times, only the last occurrence will take effect.
Finally, we start the container command: . This command is run when a container based on this image starts. When the process stops or crashes, the container will immediately stop.
Note that, in a container, we normally run mariadbd directly or in an entrypoint script exec mariadbd, rather than running or running MariaDB as a service. Containers restart can be handled by the container service. See .
See the documentation links below to learn the syntax allowed in a Dockerfile.
It is possible to use variables in a Dockerfile. This allows us, 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:
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, unless ARG is re-declared after the FROM. Here is an example:
We'll have to assign variables a value when we build the Dockerfile, in this way:
Note that Dockerfile variables are just placeholders for values. Dockerfiles do not support assignment, conditionals or loops.
Dockerfiles are normally versioned, as well as the files that are copied to the images.
Once an image is built, it can be pushed to a container registry. Whenever an image is needed on a host to start containers from it, it is pulled from the registry.
A default container registry for OCI images is Docker Hub. It contains Docker Official Images maintained by the Docker Library team and the community. Any individual or organization can open an account and push images to Docker Hub. Most Docker images are open source: the Dockerfiles and the needed files to build the images are usually on GitHub.
It is also possible to setup a self-hosted registry. Images can be pushed to that registry and pulled from it, instead of using Docker Hub. If the registry is not publicly accessible, it can be used to store images used by the organization without making them publicly available.
But a self-hosted registry can also be useful for open source images: if an image is available on Docker Hub and also on a self-hosted registry, in case Docker Hub is down or not reachable, it will still be possible to pull images.
The names of images developed by the community follow this schema:
It doesn't matter if the maintainer is an individual or an organization. For images available on Docker Hub, the maintainer is the name of a Docker Hub account.
Official images maintained by the Docker Library maintainers have the implicit name of library filled in by the container fetching tool. For example, the official MariaDB image is called mariadb which is an alias for docker.io/library/mariadb.
All images have a tag, which identifies the version or the variant of an image. For example, all MariaDB versions available on Docker are used as image tags. is called mariadb:10.11.
By conversion, tags form a hierarchy. So for example, there is a 10.1.1 tag whose meaning will not change over time. 10.5 will always identify the latest stable version in the 10.5 branch. For some time it was 10.5.1, then it became 10.5.2, and so on.
When we pull an image without specifying a tag (ie, docker pull mariadb), we are implicitly requiring the image with the latest tag. This is even more mutable: at different periods of time, it pointed to the latest 10.0 version, to the latest 10.1 version, and so on.
In production, it is always better to know for sure which version we are installing. Therefore it is better to specify a tag whose meaning won't change over time, like 10.5.21. To keep to a latest LTS version, the lts can be used.
To pull an image from Docker Hub or a self-hosted registry, we use the docker pull command. For example:
This command downloads the specified image if it is not already present in the system, or if the local version is not up to date.
After modifying a Dockerfile, we can build an image in this way:
This step can be automated by services like Docker Hub and GitHub. Check those service's documentation to find out how this feature works.
Once an image is created, it can be pushed to a registry. We can do it in this way:
Docker has a feature called Docker Content Trust (DCT). It is a system used to digitally sign images, based on PEM keys. For environments where security is a major concern, it is important to sign images before pushing them. This can be done with both Docker Hub and self-hosted registries.
As mentioned, a Dockerfile is built by creating a new image for each directive that follows FROM. This leads to some considerations.
Sometimes it can be a good idea to run several shell commands in a single RUN directive to avoid creating images that are not useful.
Modifying a directive means that all subsequent directives also need to be rebuilt. When possible, directives that are expected to change often should follow directives that will change seldom.
Directives like LABEL or EXPOSE should be placed close to the end of Dockerfiles. In this way they will be rebuilt often, but this operation is cheap. On the other side, changing a label should not trigger a long rebuild process.
More details can be found in the Docker documentation:
.
.
.
.
See also:
on Wikipedia.
Content initially contributed by .
This page is licensed: CC BY-SA / Gnu FDL
This process shows how to deploy MariaDB in a Docker container running on an EC2 instance. First we'll create the EC2 VM, then we'll deploy Docker to it. After that, we'll pull the MariaDB Docker image which we'll use to create a running container with a MariaDB instance. Finally, we'll load a sample database into the MariaDB instance.
Install MariaDB client on your local machine, either bundled with Maria DB server or standalone.
Login to AWS, navigate to
Choose Region for EC2 in the upper right corner of the console
Launch (1) Instance, giving instance a name (e.g. mrdb-ubuntu-docker-use1) and create or re-use a key pair
Choose Ubuntu 22.04 or similar free tier instance
Choose hardware, t2.micro or similar free tier instance
Create Key Pair with name (e.g. mrdb-docker-aws-pk.pem if using openSSH at the command line, or mrdb- docker-aws-pk..ppk for use with programs like PuTTY.)
Create or select a security group where SSH is allowed from anywhere 0.0.0.0/0. If you’d like to make this more secure, it can be restricted to a specific IP address or CIDR block.
Accept remaining instance creation defaults and click “launch instance”.
Save the *.pem or *.ppk keyfile on your local hard drive when prompted. You will need it later. If you’re on Linux, don’t forget to change permissions on the downloaded *.pem / *.ppk key file:
Click into the instance summary (EC2 > Instances > Instance ID) and click on the “security” tab towards the bottom.
In the relevant security group for your instance, Create an inbound rule so that TCP port 3306 is open, allowing external connections to Maria DB (like your local command line client for MariaDB). Double check that port 22 is open while you're there for SSH.
For more detailed instructions, refer to
Back in the instance summary (EC2 > Instances > Instance ID), copy the public IP (e.g. ww.xx.yyy.zzz)
Open terminal window, navigate to the directory with private key (*.pem or *.ppk) file and start a SSH remote shell session by typing:
(switch ww.xx.yyy.zzz for your IP address from step 14).
Are you sure you want to continue connecting (yes/no/[fingerprint])? Say yes
Escalate to root
Install Docker
Pull MariaDB Docker image
Start MDRB docker process at your terminal / command line
To ensure persistent storage, use the -v flag to mount your chosen directory as /var/lib/mysql. For Windows, represent file paths like C:\Users\YourUID\Documents\YourDirName accordingly. On Linux, use absolute file paths. Always replace the root password with a secure one, especially outside of development environments.
Shell into container
Login to MRDB inside container using the root password specified in step 20.
Setup admin account with permission for remote connection, configure access control
Obviously replace these passwords with something that is a bit more secure than you see in this example for anything other than development purposes.
Setup service account for your app with permission for remote connection, configure access control
Obviously replace these passwords with something that is a bit more secure than you see in this example for anything other than development purposes.
Load up your database from your preexisting SQL script that contains ; ; and statements.
Open a new terminal window (not your SSH session) and navigate to the directory containing your database creation script, for example, init.sql. Then, enter the command:
(switch ww.xx.yyy.zzz for your IP address from step 14).
This page is licensed: CC BY-SA / Gnu FDL
This process shows how to deploy MariaDB in a Docker container running on an GCE instance. First we'll create the GCE VM, then we'll deploy Docker to it. After that, we'll pull the MariaDB Docker image which we'll use to create a running container with a MariaDB instance. Finally, we'll load a sample database into the MariaDB instance.
Install on your local machine, either bundled with Maria DB server or standalone.
Variables should be used to avoid Dockerfiles proliferation. But if a variable is used, changing its value should be tested. So, be sure not to use variables without a good reason.
Writing logic into a Dockerfile is impossible or very hard. Call shell scripts instead, and write your logic into them. For example, in a shell script it is easy to perform a certain operation only if a variable is set to a certain value.
If you need MariaDB containers with different configurations or different sets of plugins, use the method explained above. Do not create several Dockerfiles, with different tags, for each desired configuration or plugin set. This may lead to undesired code duplication and increased maintenance costs.

FROM ubuntu:20.04
RUN apt-get update
RUN apt-get install -y mariadb-server
EXPOSE 3306
LABEL version="1.0"
LABEL description="MariaDB Server"
HEALTHCHECK --start-period=5m \
CMD mariadb -e 'SELECT @@datadir;' || exit 1
CMD ["mariadbd"]FROM ubuntu:20.04
ARG MARIADB_CONFIG_FILE
...
ENTRYPOINT mariadbd --defaults-file=$MARIADB_CONFIG_FILEARG UBUNTU_VERSION
FROM ubuntu:$UBUNTU_VERSION
# Uncomment for the build error to be avoided
# ARG UBUNTU_VERSION
# But this will cause a build error:
RUN echo 'Ubuntu version: $UBUNTU_VERSION' > /var/build_logdocker build --build-arg UBUNTU_VERSION=20.04 .repository/maintainer/technologydocker pull mariadb:10.5docker build .docker push <image_name>:<tag>{{aws-firewall}}$ chmod 400 mrdb-docker-pk.pem{{security-group}}{{aws-instance-ip}}$ ssh -i mrdb-docker-pk.pem ubuntu@ww.xx.yyy.zzz$ sudo su$ curl -fsSL https://get.docker.com | sudo sh$ docker pull mariadb:lts$ docker run --detach --name mariadb-docker -v \Users\YouUID\Documents\YourDirName:/var/lib/mysql:Z -p 3306:3306 -e MARIADB_ROOT_PASSWORD=yoursecurepassword mariadb:lts$ docker exec -it mariadb-docker bash$ mariadb -pyoursecurepasswordMariaDB [(none)]> CREATE USER 'admin'@'%' IDENTIFIED BY 'admin';
MariaDB [(none)]> GRANT ALL ON *.* to 'admin'@'%' WITH GRANT OPTION;
MariaDB [(none)]> SHOW GRANTS FOR admin;MariaDB [(none)]> CREATE USER 'yourappname'@'%' IDENTIFIED BY 'yoursecurepassword';
MariaDB [(none)]> GRANT INSERT, UPDATE, DELETE ON *.* to 'yourappname'@'%';
MariaDB [(none)]> SHOW GRANTS FOR yourappname;$ mariadb --host=ww.xx.yyy.zzz --port=3306 --user=admin --password=admin -e “SOURCE init.sql”Login to Google Cloud, navigate to VM instances
Enable Compute Engine API if you haven’t already.
Click create instance, give instance a name (e.g. mrdb-ubuntu-docker-use1b), choose a region and zone.
Machine configuration: Choose general-purpose / E2 micro
Boot Disk > Change
Switch the operating system to a modern Ubuntu release x86/64 CPU architecture, or similar free tier offering.
Create a firewall rule in the Firewall Policies section of the console. After naming it, change the targets, add 0.0.0.0/0 as a source IP range, and open TCP port 3306. Then Click create.
Connect using Google Cloud’s built in browser SSH. Accept all prompts for authorization.
For more detailed instructions, refer to Installing and Using MariaDB via Docker
Escalate to root Escalate to root
Install Docker
Pull Docker image
Start MDRB docker process at your terminal / command line.
Mounting a Directory for Persistent MySQL Storage
When using the -v flag to mount a directory as /var/lib/mysql, you ensure that your MySQL data is stored persistently.
Windows: Use a file path format similar to C:\Users\YourUsername\Documents\YourDirectory.
Linux: Always use absolute paths instead of relative ones.
Root Password: Replace the default root password with a strong, secure password for production environments.
Shell into container
Login to MRDB inside container using the root password specified in step 12.
Setup admin account with permission for remote connection, configure access control Execute these SQL commands in sequence:
Obviously replace these passwords with something that is a bit more secure than you see in this example for anything other than development purposes.
Setup service account for your app with permission for remote connection, configure access control Execute these SQL commands in sequence:
Obviously replace these passwords with something that is a bit more secure than you see in this example for anything other than development purposes.
Load up your database from your preexisting SQL script that contains CREATE DATABASE; USE DATABASE; and CREATE TABLE statements.
Copy the external IP address of your VM instance from the Console in the VM instances list.
To run your database creation script using MariaDB, open a new terminal window and navigate to the directory containing the script, init.sql. Then, execute the following command, replacing ww.xx.yyy.zzz with your IP address:
This page is licensed: CC BY-SA / Gnu FDL
MariaDB Corporation provides Docker images for MariaDB Enterprise Server in the MariaDB Enterprise Docker Registry.
Docker provides multiple benefits:
Docker is an open platform for developing, shipping, and running applications that allows you to separate your applications from your infrastructure.
Docker images are portable. A Docker image can be deployed in a Docker container on any system using the Docker platform, regardless of the host operating system.
Docker containers are isolated from the host operating system and from other Docker containers.
If you want to deploy MariaDB Enterprise Server without Docker, alternative deployment methods are available.
MariaDB Enterprise Server can be deployed with Docker to support use cases that require software to be rapidly deployed on existing infrastructure, such as:
Continuously create and destroy automated testing environments as part of a continuous integration (CI) pipeline
Create a small test environment on a local workstation
Create multiple isolated test environments on the same host
Deployment alongside related containers using Docker Compose
The following products and versions can be deployed using the MariaDB Enterprise Docker Registry:
MariaDB Enterprise Server 11.8
MariaDB Enterprise Server 11.4
MariaDB Enterprise Server 10.6
For details about which storage engines and plugins are supported in the images for each version, see "".
To deploy MariaDB Enterprise Server in a Docker container, follow the instructions below.
MariaDB Corporation requires customers to authenticate when logging in to the MariaDB Enterprise Docker Registry. A customer-specific Customer Download Token must be provided as the password.
Customer Download Tokens are available through the MariaDB Customer Portal.
To retrieve the customer download token for your account:
Navigate to the Customer Download Token at the MariaDB Customer Portal.
Log in using your MariaDB ID.
Copy the Customer Download Token to use as the password when logging in to the MariaDB Enterprise Docker Registry.
Log in to the MariaDB Enterprise Docker Registry by executing docker login:
When prompted, enter the login details:
As the user name, enter the email address associated with your MariaDB ID.
As the password, enter your Customer Download Token.
The login details will be saved.
Confirm the login details were saved by checking the /.docker/config.json file for a JSON object named "docker.mariadb.com" inside an "auths" parent JSON object:
The enterprise-server repository in the MariaDB Enterprise Docker Registry contains images for different MariaDB Enterprise Server releases using specific tags. Before continuing, you will need to decide which tag to use.
To deploy a container using the most recent image for the latest MariaDB Enterprise Server release series (currently 11.8), use the latest tag.
For additional information, see "".
Pull the Docker image with the chosen tag by executing docker pull:
Confirm the Docker image has been pulled by executing docker images:
Create a container using the pulled Docker image by executing docker run:
Configure the container and set the root password using environment variables by setting the --env command-line option.
Configure TCP port bindings for the container by setting the --publish or --publish-all command-line options.
Configure MariaDB Enterprise Server by setting mariadbd command-line options.
Confirm the container is running by executing docker ps:
By default, Docker uses Docker bridge networking for new containers. For details on how to use host networking for new containers, see "Create a Container with Host Networking".
Connect to the container by executing MariaDB Client on the container using docker exec:
Confirm the container is using the correct version of MariaDB Enterprise Server by querying the version system variable with the SHOW GLOBAL VARIABLES statement:
Exit the container using exit:
Stop a Docker container using docker stop:
Confirm the container is stopped by executing docker ps:
Remove a Docker container using docker rm:
Confirm the container is removed by executing docker ps:
This page is: Copyright © 2025 MariaDB. All rights reserved.
This process shows how to deploy MariaDB in a Docker container running on an Azure VM instance. First we'll create the Azure VM, then we'll deploy Docker to it. After that, we'll pull the MariaDB Docker image which we'll use to create a running container with a MariaDB instance. Finally, we'll load a sample database into the MariaDB instance.
Create a VM in Azure
Install MariaDB client on your local machine, either bundled with Maria DB server or standalone.
Login to Azure, navigate to Azure Virtual Machine
. Give the VM a name (e.g. mrdb-ubuntu-docker-use1), and create new or use an existing resource group. Selection region and availability zone, and choose Ubuntu 22.04 LTS x64 (free services eligible).
Choose the VM instance size, like a B1s or similar free tier. Note that Azure free works on a credit based system for new accounts
Configure an administrator account and generate a new key pair, and give the key pair a name.
Click "Review + Create" at the very bottom of the "create virtual machine" page to create the VM.
Download the SSH keys and them in a safe place, you will need them later. For this example, let's name the key file mrdb-docker-pk.pem.
If your local machine is Linux or you are using WSL on Windows, open a terminal window and:
Once the VM is deployed, "click to resource" to get back to the virtual machine's overview page.
From the overview page, the left-hand navigation, choose settings > networking.
Click "add inbound port rule"
Install Docker on the Azure VM
For more detailed instructions, refer to
To connect to your remote server using SSH, open a terminal window and use the following command, replacing placeholders with your specific details:
Replace your-keyfile.pem with your private key file name.
Replace your.ip.address with your actual IP address from step 12.
If you forget your admin details, go to Azure's left-hand navigation, select Settings >
Pull the MariaDB Docker image and create the container
To download the latest MariaDB Docker image, run the following command:
To start the MariaDB Docker process, open your terminal or command line and enter the following command:
Use the -v flag to mount a directory for persistent storage under /var/lib/mysql.
23. To login to MRDB inside the container, use the root password from step 20:
24. Setup admin account with permission for remote connection, configure access control
Obviously replace these passwords with something that is a bit more secure than you see in this example for anything other than development purposes.
Setup service account for your app with permission for remote connection, configure access control
Obviously replace these passwords with something that is a bit more secure than you see in this example for anything other than development purposes.
Load up your database from your preexisting SQL script that contains ; ; and statements.
Open a new local terminal window and navigate to the directory containing your init.sql script. Then, run the command: mariadb --host=ww.xx.yyy.zzz --port=3306 --user=admin --password=admin -e "SOURCE init.sql", replacing ww.xx.yyy.zzz with your server's IP address.
This page is licensed: CC BY-SA / Gnu FDL
Docker Compose is a tool that allows one to declare which Docker containers should run, and which relationships should exist between them. It follows the infrastructure as code approach, just like most automation software and Docker itself.
For information about installing Docker Compose, see in Docker documentation.
docker-compose.yml FileWhen using Docker Compose, the Docker infrastructure must be described in a YAML file called docker-compose.yml.
The healthcheck.sh script is part of the Docker Official Images of MariaDB Server. The script is part of the .
The script processes a number of argument and tests, together, in strict order. Arguments pertaining to a test must occur before the test name. If a test fails, no further processing is performed. Both arguments and tests begin with a double-hyphen.
By default, (since 2023-06-27), official images will create healthcheck@localhost, healthcheck@127.0.0.1, healthcheck@::1
docker exec -it mariadb-docker bash$ sudo su$ curl -fsSL get.docker.com | sudo sh$ docker pull mariadb:lts$ docker run --detach --name mariadb-docker -v \Users\YouUID\Documents\YourDirName:/var/lib/mysql:Z -p 3306:3306 -e MARIADB_ROOT_PASSWORD=yoursecurepassword mariadb:lts$ mariadb -pyoursecurepasswordMariaDB [(none)]> CREATE USER 'admin'@'%' IDENTIFIED BY 'admin';
MariaDB [(none)]> GRANT ALL ON _._ to 'admin'@'%' WITH GRANT OPTION;
MariaDB [(none)]> SHOW GRANTS FOR admin;MariaDB [(none)]> CREATE USER 'yourappname'@'%' IDENTIFIED BY 'yoursecurepassword';
MariaDB [(none)]> GRANT INSERT, UPDATE, DELETE ON *.* TO 'yourappname'@'%';
MariaDB [(none)]> SHOW GRANTS FOR yourappname;$ mariadb --host=your_ip_address --port=3306 --user=admin --password=admin -e "SOURCE init.sql"




$ docker login docker.mariadb.com$ cat ~/.docker/config.json{
"auths": {
"docker.mariadb.com": {
"auth": "<auth_hash>"
}
}
}docker pull docker.mariadb.com/enterprise-server:latestlatest: Pulling from enterprise-server
5d87d5506868: Pull complete
Digest: sha256:68795ca747901e3402e30dab71d6d8bc72bce727db3b9e4888979468be77d250
Status: Downloaded newer image for docker.mariadb.com/enterprise-server:latest
docker.mariadb.com/enterprise-server:latestdocker images \
--filter=reference='docker.mariadb.com/enterprise-server'REPOSITORY TAG IMAGE ID CREATED SIZE
docker.mariadb.com/enterprise-server latest dd17291aa340 3 months ago 451MBdocker run --detach \
--name mariadb-es-latest \
--env MARIADB_ROOT_PASSWORD='YourSecurePassword123!' \
--publish '3307:3306/tcp' \
docker.mariadb.com/enterprise-server:latest \
--log-bin=mariadb-bin \
<other mariadbd command-line options>3082ab69e565be21c6157bb5a3d8c849ec03a2c51576778ac417a8a3aa9e7537docker ps \
--all \
--filter ancestor='docker.mariadb.com/enterprise-server:latest'CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3082ab69e565 docker.mariadb.com/enterprise-server:latest "/es-entrypoint.sh -…" 12 seconds ago Up 11 seconds 3306/tcp mariadb-es-latestdocker exec --interactive --tty \
mariadb-es-latest \
mariadb \
--user=root \
--passwordSHOW GLOBAL VARIABLES
LIKE 'version'\G*************************** 1. row ***************************
Variable_name: version
Value: 11.8.3-1-MariaDB-enterprise-logexitByedocker stop mariadb-es-latestmariadb-es-latestdocker ps \
--all \
--filter ancestor='docker.mariadb.com/enterprise-server:latest'CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3082ab69e565 docker.mariadb.com/enterprise-server:latest "/es-entrypoint.sh -…" 2 minutes ago Exited (143) About a minute ago mariadb-es-latestdocker rm mariadb-es-latestmariadb-es-latestdocker ps \
--all \
--filter ancestor='docker.mariadb.com/enterprise-server:latest'CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESNavigate back to the virtual machine's overview page. Then copy the public IP address to the clipboard.
Are you sure you want to continue connecting (yes/no/[fingerprint])? Say yes
To switch to the root user, use the following command:
C:\Users\YourUID\Documents\YourDirName should be specified as shown above.Ensure paths are absolute, not relative.
Replace yoursecurepassword with a strong password, especially for environments beyond development.
To access the MariaDB container's shell, use the following command:








In the first line we declare that we are using version 3 of the Docker compose language.
Then we have the list of services, namely the web and the mariadb services.
Let's see the properties of the services:
port
Maps the 8080 container port to the 80 host system port; useful for development, allows browser connection to containerized web server.
links
Declares container connectivity, ensuring that the container can connect to mariadb. The hostname is the container name.
depends_on
Specifies that mariadb must start before web, ensuring the application can connect once MariaDB is ready.
restart
Ensures containers restart automatically if they crash (restart: always).
volumes
Creates accessible directories for containers on the host system, facilitating data persistence even if a container is destroyed.
environment
Sets environment variables within the container, crucial for defining MariaDB root credentials.
It is good practice to create volumes for:
The data directory, so we don't lose data when a container is created or replaced, perhaps to upgrade MariaDB.
The directory where we put all the logs, if it is not the datadir.
The directory containing all configuration files (for development environments), so we can edit those files with the editor installed in the host system. Normally no editor is installed in containers. In production we don't need to do this, because we can copy files from a repository located in the host system to the containers.
Note that Docker Compose variables are just placeholders for values. Compose does not support assignment, conditionals or loops.
In the above example you can see several variables, like ${MARIADB_VERSION}. Before executing the file, Docker Compose will replace this syntax with the MARIADB_VERSION variable.
Variables allow making Docker Compose files more re-usable: in this case, we can use any MariaDB image version without modifying the Docker Compose file.
The most common way to pass variables is to write them into a file. This has the benefit of allowing us to version the variable file along with the Docker Compose file. It uses the same syntax you would use in BASH:
For bigger setups, it could make sense to use different environment files for different services. To do so, we need to specify the file to use in the Compose file:
Docker Compose is operated using docker-compose. Here we'll see the most common commands. For more commands and for more information about the commands mentioned here, see the documentation.
Docker Compose assumes that the Composer file is located in the current directory and it's called docker-compose.yml. To use a different file, the -f <filename> parameter must be specified.
docker-compose pull
Pulls the necessary images.
docker-compose up --no-recreate
Creates containers only if they do not already exist.
docker-compose up
Creates containers if they don't exist and recreates them if their image or configuration has changed.
docker-compose up --force-recreate
Recreates containers in all cases.
docker-compose up --no-start
Creates containers without starting them.
docker-compose restart
Restarts containers without recreating them.
Overview of Docker Compose in the Docker documentation.
Compose file in the Docker documentation.
Docker Compose on GitHub.
Further information about the concepts explained in this page can be found in Docker documentation:
Content initially contributed by Vettabase Ltd.
This page is licensed: CC BY-SA / Gnu FDL
--replication where additional grants are required. This is stored in .my-healthcheck.cnf in the datadir of the container and passed as the --defaults-extra-file to the healthcheck.sh script if it exists. The .my-healthcheck.cnf also sets protocol=tcp for the mariadb so --connect is effectively there on all tests.The MARIADB_AUTO_UPGRADE=1 will regenerate the .my-healthcheck.cnf file if missing and recreate the healthcheck users of the database with a new random password. The current port configuration of the MariaDB container is written into this file.
The MARIADB_MYSQL_LOCALHOST_USER=1, MARIADB_MYSQL_LOCALHOST_GRANTS environment variables can also be used, but with the creation of the healthcheck user, these are backwards compatible.
An example of a compose file that uses the healthcheck.sh to determine a healthy service as a dependency before starting a WordPress service:
The various health check flags used for monitoring the status and readiness of a MariaDB server.
--connect
Active when an external user can connect to the TCP port of MariaDB Server. This strictly tests the TCP connection, not authentication.
--innodb_initialized
True when InnoDB has completed initializing, including any rollback or crash recovery.
The connecting user must have USAGE privileges.
--innodb_buffer_pool_loaded
Indicates that the previously saved buffer pool dump has been completely loaded, meaning the server has a hot cache ready for use.
The connecting user must have USAGE privileges.
--galera_online
Indicates that the Galera node is online (based on the wsrep_local_state variable). This includes states like "joining" and "donor" where it cannot serve SQL queries.
To customize the health checks described previously, you can use the following parameters:
--replication_all
Checks all replication sources.
--replication_name=n
Sets the multisource connection name to be tested. This unsets --replication_all.
--replication_io
Checks if the replication IO thread is running.
--replication_sql
Checks if the replication SQL thread is running.
--replication_seconds_behind_master=n
Checks if the replication delay is less than or equal to n seconds.
--replication_sql_remaining_delay=n
Checks if the remaining SQL delay is less than or equal to n seconds.
Switch to mysql user, and check if can connect and the innodb is initialized.
Switch to mysql user, check if connections can be made. For the replication channel archive, ensure IO and SQL threads are running, the seconds behind master is less than 600 seconds, and the SQL remaining delay is less than 30 seconds. For the channel1, the seconds behind master is limited to 10 seconds maximum.
This page is licensed: CC BY-SA / Gnu FDL
Frequently asked questions about the Docker Official Image
If you have an existing data directory and wish to reset the root and user passwords, and to create a database which the user can fully modify, perform the following steps.
First create a passwordreset.sql file:
Adjust myuser, databasename
sudo sumv /mnt/c/ ~/.ssh/
chmod 400 ~/.ssh/ssh -i ~/.ssh/your-keyfile.pem azureuser@your.ip.addressMicrosoft Azure offers two machine types with pre-installed Docker. If you need to reinstall Docker or choose a machine type without Docker pre-installed, you can install it manually. Connect to your machine via SSH and use the following command:```bash
curl -fsSL get.docker.com | sudo sh
```docker pull mariadb:ltsdocker run --detach --name mariadb-docker -v C:\Users\YourUID\Documents\YourDirName:/var/lib/mysql:Z -p 3306:3306 -e MARIADB_ROOT_PASSWORD=yoursecurepassword mariadb:lts```bashdocker exec -it mariadb-docker bash
``````bash
mariadb -p'yoursecurepassword'
```MariaDB [(none)]> CREATE USER 'admin'@'%' IDENTIFIED BY 'admin';
MariaDB [(none)]> GRANT ALL ON *.* to 'admin'@'%' WITH GRANT OPTION;
MariaDB [(none)]> SHOW GRANTS FOR admin;MariaDB [(none)]> CREATE USER 'yourappname'@'%' IDENTIFIED BY 'yoursecurepassword';
MariaDB [(none)]> GRANT INSERT, UPDATE, DELETE ON _._ to 'yourappname'@'%';
MariaDB [(none)]> SHOW GRANTS FOR yourappname;version: "3"
services:
web:
image: "apache:${PHP_VERSION}"
restart: 'always'
depends_on:
- mariadb
restart: 'always'
ports:
- '8080:80'
links:
- mariadb
mariadb:
image: "mariadb:${MARIADB_VERSION}"
restart: 'always'
volumes:
- "/var/lib/mysql/data:${MARIADB_DATA_DIR}"
- "/var/lib/mysql/logs:${MARIADB_LOG_DIR}"
- /var/docker/mariadb/conf:/etc/mysql
environment:
MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}"
MYSQL_DATABASE: "${MYSQL_DATABASE}"
MYSQL_USER: "${MYSQL_USER}"
MYSQL_PASSWORD: "${MYSQL_PASSWORD}"PHP_VERSION=8.0
MARIADB_VERSION=10.6
...services:
web:
env_file:
- web-variables.env
...version: "3"
services:
mariadb:
image: mariadb:lts
environment:
- MARIADB_DATABASE=testdb
- MARIADB_USER=testuser
- MARIADB_PASSWORD=password
- MARIADB_RANDOM_ROOT_PASSWORD=1
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
start_period: 10s
interval: 10s
timeout: 5s
retries: 3
wordpress:
image: wordpress
environment:
- WORDPRESS_DB_HOST=mariadb
- WORDPRESS_DB_NAME=testdb
- WORDPRESS_DB_USER=testuser
- WORDPRESS_DB_PASSWORD=password
depends_on:
mariadb:
condition: service_healthyhealthcheck.sh --su-mysql --connect --innodb_initializedhealthcheck.sh --su-mysql --connect --replication_io --replication_sql --replication_seconds_behind_master=600 --replication_sql_remaining_delay=30 ----replication_name=archive --replication --replication_seconds_behind_master=10 --replication_name=channel1 --replicationdocker-compose kill <service>
Kills a specific container by sending it a SIGKILL signal.
docker-compose rm -f <service>
Instantly removes a running container.
docker-compose down
Tears down all containers, networks, and volumes created by the Compose file.
The connecting user must have USAGE privileges.
--replication
Tests a replica based on the --replication_* parameters. All subtests must pass: <ul><li>io: The IO thread is running.</li><li>sql: The SQL thread is running.</li><li>seconds_behind_master: The replica is less than a specified number of seconds behind the primary.</li><li>sql_remaining_delay: The delayed replica is less than a specified number of seconds behind the primary's execution.</li></ul>
REPLICATION_CLIENT (before MariaDB 10.5) or REPLICA MONITOR (MariaDB 10.5+).
--mariadbupgrade
Indicates that MariaDB is upgraded to the current version.
--su=n
Changes to the specified user (n). Can only be used once from the default root user.
--su-mysql
Changes to the mysql unix user. Respawns the script, resetting all parameters, so it should be the first argument.
--datadir=n
Specifies the data directory location (n) for the --mariadbupgrade test.
--no-defaults
--defaults-file
--defaults-extra-file
--defaults-group-suffix
These parameters are passed to the mariadb shell for all tests except --mariadbupgrade.


Then:
On restarting the MariaDB container in this /my/own/datadir, the root and myuser passwords will be reset.
Question, are you getting errors like the following where a temporary server start fails to succeed in 30 seconds?
Example of log:
The timeout on a temporary server start is a quite generous 30 seconds.
The lack of a message like the following indicates it failed to complete writing a temporary file of 12MiB in 30 seconds.
If the datadir where this is stored is remote storage maybe it's a bit slow. It's ideal to have an InnoDB temporary path local so this can be configured using the command or configuration setting:
Note: depending on container runtime this space may be limited.
MARIADB_REPLICATION_USER / MARIADB_REPLICATION_PASSWORD specify the authentication for the connection. The MARIADB_MASTER_HOST is the indicator that it is a replica and specifies the container aka hostname, of the master.
A docker-compose.yml example:
This will show up in the container log as:
The cause is the underlying table has change structure from the last MariaDB version. The easiest solution to this is to start the container with the environment variable MARIADB_AUTO_UPGRADE=1 and system tables will be updated. This is safe to keep on as it detects the version installed. The next start should not show this error.
This will show up in the error log as:
This is attempting to start on a higher MariaDB version when the shutdown of the previous version crashed.
By crashed, it means the MariaDB was force killed or had a hard power failure. MariaDB, being a durable database, can recover from these, if started with the same version. The redo log however is a less stable format, so the recovery has to be on the same Major.Minor version, in this case 10.5. This error message is saying that you when from force killed MariaDB to a later version.
So whenever you encounter this message. Start with the again with the tag set to the version in the error message, like 10.5.4, or as the redo long format is consistent in the Major.Minor version 10.5 is sufficient. After this has been started correctly, cleanly shut the service down and it will be recovered.
The logs on shutdown should have a message like:
After you see this, you can update your MariaDB tag to a later version.
Or:
In this case, the container is running as a user that, inside the container, does not have write permissions on the datadir /varlib/mysql.
From the transaction coordinator log this is a corrupted file. This will have a log message like the following:
The cause of this is headed by the first not, its a crash recovery. Like the Every MariaDB start is a crash recovery answer below, this is an indication that MariaDB wasn't given enough time by the container runtime to shutdown cleanly. While MariaDB was shutdown, the new version that was started is a newer MariaDB and doesn't recognise the updated magic information in the header.
MariaDB should always perform crash recovery with the same version that actually crashed, the same major/minor number at least.
As such the solution is to restart the container with the previous MariaDB version that was running, and configure the container runtime to allow a longer stop time. See the Every MariaDB start is a crash recovery answer below to see if the timeout is sufficiently extended.
Do you get on every start:
Container runtimes are assume to start and stop very quickly. Check the shutdown logs. They may be a log like:
Note that the logs didn't include the following messages:
As these messages aren't here, the container was killed off before it could just down cleanly. When this happens, the startup will be a crash recovery and you won't be able to upgrade your MariaDB instance (previous FAQ) to the next Major.Minor version.
Solution is to extend the timeout in the container runtime to allow MariaDB to complete its shutdown.
With the backup prepared like previously:
Because Apptainer has all the filesystems readonly except or the volume, the /run/mysqld directory is used as a pidfile and socket directory. An easy way is to mark this as a scratch directory.
Alternately:
The MariaDB entrypoint briefly starts as root, and if an explicit volume is there, the owner of this volume will be root. To allow MariaDB to use the CHOWN capability to change the volume owner to a user that can write to this volume, it needs to be briefly root. After this one action is taken, the entrypoint uses gosu to drop to a non-root user and continues execution. There is no accessible exploit vector to remotely affect the container startup when it is briefly running as the root user.
In a Docker Compose file or when running a command, you can specify the user with user: 2022 or --user 2022 to execute the entrypoint as user ID 2022. Ensure the datadir volume has appropriate permissions for MariaDB access, aligning with local ownership by user ID 2022. Note that inside the container, user names are not defined as they are outside, so using numeric IDs offers better portability.
This page is licensed: CC BY-SA / Gnu FDL
CREATE USER IF NOT EXISTS root@localhost IDENTIFIED BY 'thisismyrootpassword';
SET PASSWORD FOR root@localhost = PASSWORD('thisismyrootpassword');
GRANT ALL ON *.* TO root@localhost WITH GRANT OPTION;
GRANT PROXY ON ''@'%' ON root@localhost WITH GRANT OPTION;
CREATE USER IF NOT EXISTS root@'%' IDENTIFIED BY 'thisismyrootpassword';
SET PASSWORD FOR root@'%' = PASSWORD('thisismyrootpassword');
GRANT ALL ON *.* TO root@'%' WITH GRANT OPTION;
GRANT PROXY ON ''@'%' ON root@'%' WITH GRANT OPTION;
CREATE USER IF NOT EXISTS myuser@'%' IDENTIFIED BY 'thisismyuserpassword';
SET PASSWORD FOR myuser@'%' = PASSWORD('thisismyuserpassword');
CREATE DATABASE IF NOT EXISTS databasename;
GRANT ALL ON databasename.* TO myuser@'%';$ docker run --rm -v /my/own/datadir:/var/lib/mysql -v /my/own/passwordreset.sql:/passwordreset.sql:z %%IMAGE%%:latest --init-file=/passwordreset.sql2023-01-28 12:53:42+00:00 [Note] [Entrypoint]: Starting temporary server
2023-01-28 12:53:42+00:00 [Note] [Entrypoint]: Waiting for server startup
2023-01-28 12:53:42 0 [Note] mariadbd (server 10.10.2-MariaDB-1:10.10.2+maria~ubu2204) starting as process 72 ...
....
2023-01-28 12:53:42 0 [Note] InnoDB: Setting file './ibtmp1' size to 12.000MiB. Physically writing the file full; Please wait ...
2023-01-28 12:54:13 0 [Note] mariadbd: ready for connections.
Version: '10.10.2-MariaDB-1:10.10.2+maria~ubu2204' socket: '/run/mysqld/mysqld.sock' port: 0 mariadb.org binary distribution
2023-01-28 12:54:13+00:00 [ERROR] [Entrypoint]: Unable to start server.2023-01-28 12:53:46 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.innodb_temp_data_file_path=/dev/shm/ibtmp1:12M:autoextendversion: "3"
services:
master:
image: mariadb:latest
command: --log-bin --log-basename=mariadb
environment:
- MARIADB_ROOT_PASSWORD=password
- MARIADB_USER=testuser
- MARIADB_PASSWORD=password
- MARIADB_DATABASE=testdb
- MARIADB_REPLICATION_USER=repl
- MARIADB_REPLICATION_PASSWORD=replicationpass
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 3
replica:
image: mariadb:latest
command: --server-id=2 --log-basename=mariadb
environment:
- MARIADB_ROOT_PASSWORD=password
- MARIADB_MASTER_HOST=master
- MARIADB_REPLICATION_USER=repl
- MARIADB_REPLICATION_PASSWORD=replicationpass
- MARIADB_HEALTHCHECK_GRANTS=REPLICA MONITOR
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--replication_io", "--replication_sql", "--replication_seconds_behind_master=1", "--replication"]
interval: 10s
timeout: 5s
retries: 3
depends_on:
master:
condition: service_healthy2024-01-29 17:38:13 0 [ERROR] Incorrect definition of table mysql.event: expected column 'definer' at position 3 to have type varchar(, found type char(141).
2024-01-29 17:38:13 0 [ERROR] mariadbd: Event Scheduler: An error occurred when initializing system tables. Disabling the Event Scheduler.2022-05-23 12:29:20 0 [ERROR] InnoDB: Upgrade after a crash is not supported. The redo log was created with MariaDB 10.5.4.
2022-05-23 12:29:20 0 [ERROR] InnoDB: Plugin initialization aborted with error Generic error2023-11-06 10:49:23 0 [Note] InnoDB: Shutdown completed; log sequence number 84360; transaction id 49
2023-11-06 10:49:23 0 [Note] mariadbd: Shutdown complete2024-02-06 03:03:18+00:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:10.11.6+maria~ubu2204 started.
/usr/local/bin/docker-entrypoint.sh: line 600: /var/lib/mysql//mysql_upgrade_info: Permission denied
2024-02-06 03:03:18+00:00 [Note] [Entrypoint]: MariaDB upgrade (mariadb-upgrade) required, but skipped due to $MARIADB_AUTO_UPGRADE setting
2024-02-06 3:03:18 0 [Warning] Can't create test file '/var/lib/mysql/80a2bb81d698.lower-test' (Errcode: 13 "Permission denied")
2024-02-06 3:03:18 0 [Note] Starting MariaDB 10.11.6-MariaDB-1:10.11.6+maria~ubu2204 source revision fecd78b83785d5ae96f2c6ff340375be803cd299 as process 1
2024-02-06 3:03:18 0 [ERROR] mariadbd: Can't create/write to file './ddl_recovery.log' (Errcode: 13 "Permission denied")
2024-02-06 3:03:18 0 [ERROR] DDL_LOG: Failed to create ddl log file: ./ddl_recovery.log
2024-02-06 3:03:18 0 [ERROR] Aborting2024-08-16 4:54:05 0 [ERROR] InnoDB: Operating system error number 13 in a file operation.
2024-08-16 4:54:05 0 [ERROR] InnoDB: The error means mariadbd does not have the access rights to the directory.2024-05-21 8:55:58 0 [Note] Recovering after a crash using tc.log
2024-05-21 8:55:58 0 [ERROR] Bad magic header in tc log
2024-05-21 8:55:58 0 [ERROR] Crash recovery failed. Either correct the problem (if it's, for example, out of memory error) and restart, or delete tc log and start server with --tc-heuristic-recover={commit|rollback}
2024-05-21 8:55:58 0 [ERROR] Can't init tc log
2024-05-21 8:55:58 0 [ERROR] Abortingdb-1 | 2023-02-25 19:10:02 0 [Note] Starting MariaDB 10.11.2-MariaDB-1:10.11.2+maria~ubu2204-log source revision cafba8761af55ae16cc69c9b53a341340a845b36 as process 1
db-1 | 2023-02-25 19:10:02 0 [Note] mariadbd: Aria engine: starting recovery
db-1 | tables to flush: 3 2 1 0
db-1 | (0.0 seconds);
db-1 | 2023-02-25 19:10:02 0 [Note] mariadbd: Aria engine: recovery done
...
db-1 | 2023-02-26 13:03:29 0 [Note] InnoDB: Initializing buffer pool, total size = 32.000GiB, chunk size = 512.000MiB
db-1 | 2023-02-26 13:03:29 0 [Note] InnoDB: Completed initialization of buffer pool
db-1 | 2023-02-26 13:03:29 0 [Note] InnoDB: File system buffers for log disabled (block size=512 bytes)
db-1 | 2023-02-26 13:03:29 0 [Note] InnoDB: Starting crash recovery from checkpoint LSN=193796878816db-1 | 2023-02-26 13:03:17 0 [Note] InnoDB: Starting shutdown...
db-1 | 2023-02-26 13:03:17 0 [Note] InnoDB: Dumping buffer pool(s) to /var/lib/mysql/ib_buffer_pool
db-1 | 2023-02-26 13:03:17 0 [Note] InnoDB: Restricted to 519200 pages due to innodb_buf_pool_dump_pct=25
db-1 | 2023-02-26 13:03:17 0 [Note] InnoDB: Buffer pool(s) dump completed at 230226 13:03:17
db-1 exited with code 0db-1 | 2023-02-26 13:03:43 0 [Note] InnoDB: Shutdown completed; log sequence number 46590; transaction id 15
db-1 | 2023-02-26 13:03:43 0 [Note] mariadbd: Shutdown completedocker volume create backup
docker run --name mdb -v backup:/backup -v datavolume:/var/lib/mysql mariadb
docker exec mdb mariadb-backup --backup --target-dir=/backup/d --user root --password soverysecret
docker exec mdb mariadb-backup --prepare --target-dir=/backup/d
docker exec mdb sh -c '[ ! -f /backup/d/.my-healthcheck.cnf ] && cp /var/lib/mysql/.my-healthcheck.cnf /backup/d'
docker exec --workdir /backup/d mdb tar -Jcf ../backup.tar.xz .
docker exec mdb rm -rf /backup/ddocker run -v backup:/docker-entrypoint-initdb.d -v newdatavolume:/var/lib/mysql mariadbmkdir mydatadir
apptainer run --no-home --bind $PWD/mydatadir:/var/lib/mysql --env MARIADB_RANDOM_ROOT_PASSWORD=1 --net --network-args "portmap=3308:3306/tcp" --fakeroot --scratch=/run/mysqld docker://mariadb:10.5apptainer run --no-home --bind $PWD/mydatadir:/var/lib/mysql --env MARIADB_RANDOM_ROOT_PASSWORD=1 --net --network-args "portmap=3308:3306/tcp" --fakeroot docker://mariadb:10.5 --socket=/var/lib/mysql/mariadb.sock --pid-file=/var/lib/mysql/mariadb.pidSometimes we want to install a specific version of MariaDB, MariaDB ColumnStore, or MaxScale on a certain system, but no packages are available. Or maybe, we simply want to isolate MariaDB from the rest of the system, to be sure that we won't cause any damage.
A virtual machine would certainly serve the scope. However, this means installing a system on the top of another system. It requires a lot of resources.
In many cases, the best solution is using containers. Docker is a framework that runs containers. A container is meant to run a specific daemon, and the software that is needed for that daemon to properly work. Docker does not virtualize a whole system; a container only includes the packages that are not included in the underlying system.
Docker requires a very small amount of resources. It can run on a virtualized system. It is used both in development and in production environments. Docker is an open source project, released under the Apache License, version 2.
Note that, while your package repositories could have a package called docker, it is probably not the Docker we are talking about. The Docker package could be called docker.io or docker-engine.
For information about installing Docker, see in Docker documentation.
The script below will install the Docker repositories, required kernel modules and packages on the most common Linux distributions:
On some systems you may have to start the dockerd daemon yourself:
If dockerd is not running, you will encounter the following error when using most docker commands:
The easiest way to use MariaDB on Docker is choosing a MariaDB image and creating a container.
You can download a MariaDB image for Docker from the , or choose another image that better suits your needs. You can search Docker Hub (the official set of repositories) for an image with this command:
Once you have found an image that you want to use, you can download it via Docker. Some layers including necessary dependencies will be downloaded too. Note that, once a layer is downloaded for a certain image, Docker will not need to download it again for another image.
For example, if you want to install the default MariaDB image, you can type:
This will install the 10.6 version.
You will see a list of necessary layers. For each layer, Docker will say if it is already present, or its download progress.
To get a list of installed images:
An image is not a running process; it is just the software needed to be launched. To run it, we must create a container first. The command needed to create a container can usually be found in the image documentation. For example, to create a container for the official MariaDB image:
mariadbtest is the name we want to assign the container. If we don't specify a name, an id will be automatically generated.
10.2 and 10.5 are also valid target versions:
Optionally, after the image name, we can specify some . For example:
Docker will respond with the container's id. But, just to be sure that the container has been created and is running, we can get a list of running containers in this way:
We should get an output similar to this one:
Docker allows us to restart a container with a single command:
The container can also be stopped like this:
The container will not be destroyed by this command. The data will still live inside the container, even if MariaDB is not running. To restart the container and see our data, we can issue:
With docker stop, the container will be gracefully terminated: a SIGTERM signal will be sent to the mariadbd process, and Docker will wait for the process to shutdown before returning the control to the shell. However, it is also possible to set a timeout, after which the process will be immediately killed with a SIGKILL. Or it is possible to immediately kill the process, with no timeout.
In case we want to destroy a container, perhaps because the image does not suit our needs, we can stop it and then run:
Note that the command above does not destroy the data volume that Docker has created for /var/lib/mysql. If you want to destroy the volume as well, use:
When we start a container, we can use the --restart option to set an automatic restart policy. This is useful in production.
Allowed values are:
no: No automatic restart.
on-failure: The container restarts if it exits with a non-zero exit code.
unless-stopped: Always restart the container, unless it was explicitly stopped as shown above.
It is possible to change the restart policy of existing, possibly running containers:
A use case for changing the restart policy of existing containers is performing maintenance in production. For example, before upgrading the Docker version, we may want to change all containers restart policy to always, so they will restart as soon as the new version is up and running. However, if some containers are stopped and not needed at the moment, we can change their restart policy to unless-stopped.
A container can also be frozen with the pause command. Docker will freeze the process using croups. MariaDB will not know that it is being frozen and, when we unpause it, MariaDB will resume its work as expected.
Both pause and unpause accept one or more container names. So, if we are running a cluster, we can freeze and resume all nodes simultaneously:
Pausing a container is very useful when we need to temporarily free our system's resources. If the container is not crucial at this moment (for example, it is performing some batch work), we can free it to allow other programs to run faster.
If the container doesn't start, or is not working properly, we can investigate with the following command:
This command shows what the daemon sent to the stdout since the last attempt of starting - the text that we typically see when we invoke mariadbd from the command line.
On some systems, commands such as docker stop mariadbtest and docker restart mariadbtest may fail with a permissions error. This can be caused by AppArmor, and even sudo won't allow you to execute the command. In this case, you will need to find out which profile is causing the problem and correct it, or disable it. Disabling AppArmor altogether is not recommended, especially in production.
To check which operations were prevented by AppArmor, see in AppArmor documentation.
To disable a profile, create a symlink with the profile name (in this example, mariadbd) to etc/apparmor.d/disable, and then reload profiles:
For more information, see in AppArmor documentation.
After disabling the profile, you may need to run:
Restarting the system will then allow Docker to operate normally.
To access the container via Bash, we can run this command:
Now we can use normal Linux commands like cd, ls, etc. We will have root privileges. We can even install our favorite file editor, for example:
In some images, no repository is configured by default, so we may need to add them.
Note that if we run or the command to stop the container, the container will be deactivated, and we will automatically exit to our system.
If we try to connect to the MariaDB server on localhost, the client will bypass networking and attempt to connect to the server using a socket file in the local filesystem. However, this doesn't work when MariaDB is running inside a container because the server's filesystem is isolated from the host. The client can't access the socket file which is inside the container, so it fails to connect.
Therefore connections to the MariaDB server must be made using TCP, even when the client is running on the same machine as the server container.
Find the IP address that has been assigned to the container:
You can now connect to the MariaDB server using a TCP connection to that IP address.
After enabling network connections in MariaDB as described above, we will be able to connect to the server from outside the container.
On the host, run the client and set the server address ("-h") to the container's IP address that you found in the previous step:
This simple form of the connection should work in most situations. Depending on your configuration, it may also be necessary to specify the port for the server or to force TCP mode:
Multiple MariaDB servers running in separate Docker containers can connect to each other using TCP. This is useful for forming a Galera cluster or for replication.
When running a cluster or a replication setup via Docker, we will want the containers to use different ports. The fastest way to achieve this is mapping the containers ports to different port on our system. We can do this when creating the containers (docker run command), by using the -p option, several times if necessary. For example, for Galera nodes we will use a mapping similar to this one:
It is possible to download a Linux distribution image, and to install MariaDB on it. This is not much harder than installing MariaDB on a regular operating system (which is easy), but it is still the hardest option. Normally we will try existing images first. However, it is possible that no image is available for the exact version we want, or we want a custom installation, or perhaps we want to use a distribution for which no images are available. In these cases, we will install MariaDB in an operating system image.
First, we need the system image to run as a daemon. If we skip this step, MariaDB and all databases will be lost when the container stops.
To demonize an image, we need to give it a command that never ends. In the following example, we will create a Debian Jessie daemon that constantly pings the 8.8.8.8 special address:
At this point, we can enter the shell and issue commands. First we will need to update the repositories, or no packages will be available. We can also update the packages, in case some of them are newer than the image. Then, we will need to install a text editor; we will need it to edit configuration files. For example:
Now we are ready to in the way we prefer.
.
.
.
.
This page is licensed: CC BY-SA / Gnu FDL
always: Similar to unless-stopped, but when Docker itself restarts, even containers that were explicitly stopped will restart.curl -sSL https://get.docker.com/ | shsudo systemctl start docker
sudo gpasswd -a "${USER}" dockerCannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?docker search mariadbdocker pull mariadb:10.6docker imagesdocker run --name mariadbtest -e MYSQL_ROOT_PASSWORD=mypass -p 3306:3306 -d docker.io/library/mariadb:10.3docker run --name mariadbtest -e MYSQL_ROOT_PASSWORD=mypass -p 3306:3306 -d docker.io/library/mariadb:10.2docker run --name mariadbtest -e MYSQL_ROOT_PASSWORD=mypass -p 3306:3306 -d docker.io/library/mariadb:10.5docker run --name mariadbtest -e MYSQL_ROOT_PASSWORD=mypass -p 3306:3306 -d mariadb:10.3 --log-bin --binlog-format=MIXEDdocker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
819b786a8b48 mariadb "/docker-entrypoint. 4 minutes ago Up 4 minutes 3306/tcp mariadbtestdocker restart mariadbtestdocker stop mariadbtestdocker start mariadbtestdocker stop --time=30 mariadbtest
docker kill mariadbtestdocker rm mariadbtestdocker rm -v mariadbtestdocker update --restart always mariadb
# or, to change the restart policy of all containers:
docker update --restart always $(docker ps -q)docker pause node1 node2 node3
docker unpause node1 node2 node3docker logs mariadbtestln -s /etc/apparmor.d/usr.sbin.mariadbd /etc/apparmor.d/disable/
sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mariadbdsudo service docker restart
docker system prune --all --volumesdocker exec -it mariadbtest bashapt-get update
apt-get install vimdocker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mariadbtestmysql -h 172.17.0.2 -u root -pmysql -h 172.17.0.2 -P 3306 --protocol=TCP -u root -p-p 4306:3306 -p 5567:5567 -p 5444:5444 -p 5568:5568docker run --name debian -p 3306:3306 -d debian /bin/sh -c "while true; do ping 8.8.8.8; done"# start an interactive Bash session in the container
docker exec -ti debian bash
apt-get -y update
apt-get -y upgrade
apt-get -y install vimMariaDB Corporation provides the MariaDB Enterprise Docker Registry. The MariaDB Enterprise Docker Registry provides Docker images for MariaDB Enterprise Server.
This page contains reference material for the MariaDB Enterprise Docker Registry.
The reference material on this page applies to MariaDB Enterprise Server 10.6 and later.
Docker is an open platform for developing, shipping, and running applications that allows you to separate your applications from your infrastructure.
MariaDB Corporation provides the MariaDB Enterprise Docker Registry. The MariaDB Enterprise Docker Registry provides Docker images for MariaDB Enterprise Server.
For examples that show how to use the Docker images in the MariaDB Enterprise Docker Registry for MariaDB Enterprise Server, see .
Other details are listed in the sections below.
The MariaDB Enterprise Docker Registry provides Docker images for MariaDB Enterprise Server 10.6 and later.
The Docker images for MariaDB Enterprise Server include all storage engines that are installed with MariaDB Enterprise Server by default. The following storage engines are currently included:
You can check which storage engines are installed by connecting to the Docker container and executing the statement.
The Docker images for MariaDB Enterprise Server include all plugins that are installed with MariaDB Enterprise Server by default.
You can check which plugins are installed by connecting to the Docker container and executing the statement.
The container contains shared libraries for additional plugins that can be installed with the statement or the command-line option. You can check which plugins are available by querying the table:
The MariaDB Enterprise Docker Registry contains a single repository, which provides images for MariaDB Enterprise Server:
enterprise-server
The enterprise-server repository in the MariaDB Enterprise Docker Registry contains images for different MariaDB Enterprise Server releases using specific tags:
To connect to a Docker container that uses Docker bridge networking, execute on the container using :
To confirm the client is connected to the Docker container and the container is using the correct version of MariaDB Enterprise Server, query the system variable with the statement:
To exit the container, use exit:
The example above shows how to connect to a Docker container using MariaDB Client on the container, but you can also connect using MariaDB Client on the host using TCP/IP. You can to find the container's IP address and TCP port bindings.
To connect to a Docker container that uses host networking, execute on the host node and specify the host's IP address and the container's port:
To confirm the client is connected to the Docker container and the container is using the correct version of MariaDB Enterprise Server, query the system variable with the statement:
To exit the container, use exit:
By default, Docker containers use Docker bridge networking. To make connecting to the container easier, Docker can use port bindings to publish the container's TCP ports to the host.
To create a Docker container using Docker bridge networking, execute :
Configure the container using by setting the --env command-line option.
Configure TCP port bindings for the container by setting the --publish or --publish-all command-line options.
Configure MariaDB Enterprise Server by setting .
To confirm the Docker container is running, execute :
A Docker container can be configured to use the host operating system's network.
To create a Docker container using host networking, execute and specify the --network host option:
Configure the container using by setting the --env command-line option.
Configure the port for MariaDB Enterprise Server by setting the command-line option.
Configure MariaDB Enterprise Server by setting .
To confirm the Docker container is running, execute :
A Docker container can be configured to perform the following tasks using environment variables:
Create a custom database
Create a custom database user account with a custom password
Initialize the timezone tables
Set the host for the root database user
The following table contains details about the environment variables that are supported:
To create a Docker container using environment variables, execute , environment variables and specify each environment variable using the --env option:
A Docker contained can be inspected to find out internal details about the container, such as the following details:
IP addresses
MAC addresses
Port bindings
To inspect all internal details about a Docker container, execute :
To inspect a specific internal detail about a Docker container, execute and specify a filter using the --format option. Some examples are shown below.
To inspect the container's IP address:
To inspect the container's TCP port bindings:
To log in to the MariaDB Enterprise Docker Registry, execute :
When prompted, enter the login details:
As the user name, enter the email address associated with your .
As the password, enter your .
The login details will be saved.
To confirm the login details were saved, check the ~/.docker/config.json file for a JSON object named "docker.mariadb.com" inside an "auths" parent JSON object:
To obtain a shell in the Docker container, execute the shell on the container using :
To pull a Docker image with the , execute :
To confirm the Docker image has been pulled, execute :
To remove a Docker container, execute :
To confirm the container is removed, execute :
To stop a Docker container, execute :
To confirm the container is stopped, execute :
To view the logs in the Docker container, execute :
Set the password for the root database user
MARIADB_ROOT_HOST
When the MARIADB_ROOT_HOST environment variable is set to a valid hostname, the root user account will be restricted to logins from that hostname.
%
Any valid hostname
MARIADB_ROOT_PASSWORD
When the MARIADB_ROOT_PASSWORD environment variable is set to RANDOM, a random password is generated for the root user account. When the MARIADB_ROOT_PASSWORD environment variable is set to EMPTY, the root user account uses an empty password. When the MARIADB_ROOT_PASSWORD environment variable is set to a valid password, the root user account uses the specified password.
No default
RANDOM
EMPTY
Any valid password
MARIADB_USER
When the MARIADB_USER and MARIADB_PASSWORD environment variables are both set, create a user account with the specified user name and password.
No default
Any valid user name
Latest release series
latest
This tag refers to the most recent image for the latest MariaDB Enterprise Server release series, which is currently MariaDB Enterprise Server 11.8.
Specific release series
11.8
11.4
10.6
These tags refer to the images for the most recent minor release of each specific MariaDB Enterprise Server release series.
Specific minor release
11.8.3-1
11.4.8-5
10.6.23-19
These tags refer to images for specific MariaDB Enterprise Server minor releases. The listed tags are examples of minor releases. For a full list of minor releases, see .
MARIADB_DATABASE
When the MARIADB_DATABASE environment variable is set to a valid database name, create the specified database if it does not already exist.
No default
Any valid database name
MARIADB_INITDB_SKIP_TZINFO
By default, the entrypoint script automatically loads the timezone data needed for the CONVERT_TZ() function. If it is not needed, any non-empty value disables timezone loading.
No default
0
1
MARIADB_PASSWORD
When the MARIADB_USER and MARIADB_PASSWORD environment variables are both set, create a user account with the specified user name and password.
No default
Any valid password
SELECT PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_LIBRARY
FROM information_schema.ALL_PLUGINS
WHERE PLUGIN_STATUS = 'NOT INSTALLED';+---------------------------+----------------+------------------------+
| PLUGIN_NAME | PLUGIN_VERSION | PLUGIN_LIBRARY |
+---------------------------+----------------+------------------------+
| pam | 1.0 | auth_pam_v1.so |
| LOCALES | 1.0 | locales.so |
| BLACKHOLE | 1.0 | ha_blackhole.so |
| SQL_ERROR_LOG | 1.0 | sql_errlog.so |
| METADATA_LOCK_INFO | 0.1 | metadata_lock_info.so |
| pam | 2.0 | auth_pam.so |
| SERVER_AUDIT | 1.4 | server_audit.so |
| file_key_management | 1.0 | file_key_management.so |
| QUERY_RESPONSE_TIME | 1.0 | query_response_time.so |
| QUERY_RESPONSE_TIME_AUDIT | 1.0 | query_response_time.so |
+---------------------------+----------------+------------------------+docker exec --interactive --tty \
mariadb-es-11.4 \
mariadb \
--user=root \
--passwordSHOW GLOBAL VARIABLES
LIKE 'version'\G*************************** 1. row ***************************
Variable_name: version
Value: 11.4.5-3-MariaDB-enterprise-logexitByemariadb --host=192.0.2.1 \
--port=3307 \
--user=root \
--passwordSHOW GLOBAL VARIABLES
LIKE 'version'\G*************************** 1. row ***************************
Variable_name: version
Value: 11.8.3-1-MariaDB-enterprise-logexitByedocker run --detach \
--name mariadb-es-11.8 \
--env MARIADB_ROOT_PASSWORD='Password123!' \
--publish '3307:3306/tcp' \
docker.mariadb.com/enterprise-server:11.8 \
--log-bin=mariadb-bin \
<other mariadbd command-line options>3082ab69e565be21c6157bb5a3d8c849ec03a2c51576778ac417a8a3aa9e7537docker ps \
--all \
--filter ancestor='docker.mariadb.com/enterprise-server:11.8'CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3082ab69e565 docker.mariadb.com/enterprise-server:11.8 "/es-entrypoint.sh -…" 12 seconds ago Up 11 seconds 3306/tcp mariadb-es-11.8docker run --detach \
--network host \
--name mariadb-es-11.8 \
--env MARIADB_ROOT_PASSWORD='Password123!' \
docker.mariadb.com/enterprise-server:11.8 \
--port=3307 \
--log-bin=mariadb-bin \
<other mariadbd command-line options>3082ab69e565be21c6157bb5a3d8c849ec03a2c51576778ac417a8a3aa9e7537docker ps \
--all \
--filter ancestor='docker.mariadb.com/enterprise-server:11.8'docker run --detach \
--network host \
--name mariadb-es-11.8 \
--env MARIADB_ROOT_PASSWORD='Password123!' \
docker.mariadb.com/enterprise-server:11.83082ab69e565be21c6157bb5a3d8c849ec03a2c51576778ac417a8a3aa9e7537docker inspect mariadb-es-11.8[
{
"Id": "d784a193ad828cbd3db10dfbef3e3b7274465fa587453c3f6e2e27703b361173",
"Created": "2021-10-13T20:25:04.994759266Z",
"Path": "docker-entrypoint.sh",
"Args": [
"--log-bin=mariadb-bin"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 33714,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-10-13T20:25:05.32049779Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
..
}
]docker inspect \
--format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \
mariadb-es-11.8172.17.0.3docker inspect \
--format='{{range $p, $conf := .NetworkSettings.Ports}}Container port: {{$p}} -> Host port: {{(index $conf 0).HostPort}} {{end}}' \
mariadb-es-11.8Container port: 3306/tcp -> Host port: 3307docker login docker.mariadb.comcat ~/.docker/config.json
{
"auths": {
"docker.mariadb.com": {
"auth": "<auth_hash>"
}
}
}docker exec --interactive --tty \
mariadb-es-11.8 \
bashdocker pull docker.mariadb.com/enterprise-server:11.811.8: Pulling from enterprise-server
5d87d5506868: Pull complete
Digest: sha256:68795ca747901e3402e30dab71d6d8bc72bce727db3b9e4888979468be77d250
Status: Downloaded newer image for docker.mariadb.com/enterprise-server:11.8
docker.mariadb.com/enterprise-server:11.8docker images \
--filter=reference='docker.mariadb.com/enterprise-server'REPOSITORY TAG IMAGE ID CREATED SIZE
docker.mariadb.com/enterprise-server 11.8 dd17291aa340 3 months ago 451MBdocker rm mariadb-es-11.8mariadb-es-11.8docker ps \
--all \
--filter ancestor='docker.mariadb.com/enterprise-server:11.8'CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESdocker stop mariadb-es-11.8mariadb-es-11.8docker ps \
--all \
--filter ancestor='docker.mariadb.com/enterprise-server:11.8'CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3082ab69e565 docker.mariadb.com/enterprise-server:11.8 "/es-entrypoint.sh -…" 2 minutes ago Exited (143) About a minute ago mariadb-es-11.8docker logs mariadb-es-11.8