Installing plugins in the MariaDB Docker Library Container

MariaDB plugins are software components that may be added to the core software without the need to rebuild the MariaDB Server. Plugins can be storage engines, additional security requirements, special log information about the server and others. MariaDB has a large number of built-in plugins which are permanently installed (listed in SHOW PLUGINS query). Plugins can be loaded at start-up, during initialization, or loaded dynamically when the server is running.

In this blog we are going to see how to list available plugins in the MariaDB container as well as the methods of installing plugins in a container. At the end we are going to create a Dockerfile in order to build a custom image with a plugin not installed in the container image.

MariaDB Foundation maintains the official docker library images of MariaDB Server on dockerhub. You will see that most of the commands reference those images.

Initial startup of the MariaDB container

On first startup of the MariaDB container, the server needs to be configured with a database user that can connect to it. By default, this user is called root and the server will not start if one of: MARIADB_ROOT_PASSWORD, MARIADB_ALLOW_EMPTY_ROOT_PASSWORD or MARIADB_RANDOM_ROOT_PASSWORD environment variables is not set.

There are also additional variables that allow the creation of a second user and also granting it rights on only one database. These are:

  • MARIADB_USER specifying the name of the user
  • MARIADB_PASSWORD the password to be used for the MARIADB_USER
  • MARIADB_DATABASE The database that MARIADB_USER will have access to. The database will be created as well.

We recommend you make use of these variables and do not rely on simply using the root user for all access. In this blog post, whenever we need to start-up the server, we’ll be using these environment variables. You can read more about other available variables in the official dockerhub docs, search for “environment variables”.

For further information please take a look into MariaDB Container cheat sheet.

Available plugins in the MariaDB container

MariaDB Server package comes already with some available plugins and these are present by default in the mariadb container. In the container, the plugin files (ending in .so) are located in the directory /usr/lib/mysql/plugin. The server system variable plugin_dir is by default set to the same folder and it controls where the server looks for plugins.

We can list the available plugins by listing the directory within the container:

$ docker run --rm mariadb:latest ls -C /usr/lib/mysql/plugin
auth_ed25519.so		ha_blackhole.so        query_cache_info.so
auth_pam.so		ha_federated.so        query_response_time.so
auth_pam_tool_dir	ha_federatedx.so       server_audit.so
auth_pam_v1.so		ha_sphinx.so	       simple_password_check.so
disks.so		handlersocket.so       sql_errlog.so
file_key_management.so	locales.so	       type_mysql_json.so
ha_archive.so		metadata_lock_info.so  wsrep_info.so

Notice the --rm flag to make sure no container is left on the system once we’re done executing the ls command.

Enabling a plugin in the MariaDB container

In order for MariaDB plugins to be used, the server must have them installed (more specifically loaded within the server) and then enabled. There are built-in plugins that are enabled by default and can not be uninstalled. Other plugins need to be installed within the server. Simply having the .so file present in the plugin directory is not enough. There are multiple possible ways to install and enable plugins. We’ll explore four different ways to achieve this.

  1. Enabling a plugin with a command line option
  2. Enabling a plugin with a configuration file option
  3. Enabling a plugin in /docker-entrypoint-initdb.d
  4. Build a new image containing a plugin using Dockerfile (for plugins that do not come installed in the container by default)

1. Enabling a plugin with a command line option

You can pass command line options to the docker entrypoint script, which eventually starts the mariadbd binary (the Server). To load a plugin, we can use the option plugin-load-add. We use this method for one of our available plugins that are not installed by default:

$ docker run -d \
    --env MARIADB_USER=anel \
    --env MARIADB_PASSWORD='$coMp"|lex99password' \
    --env MARIADB_DATABASE=web_users \
    --env MARIADB_RANDOM_ROOT_PASSWORD=1 \
    --name mariadb-server \
    mariadb:latest --plugin-load-add=simple_password_check

We can check for the presence of simple_password_check by connecting with mariadb client to the container and running running SHOW PLUGINS SONAME LIKE 'simple_password%'.

$ docker exec mariadb-server mariadb -u anel -p'$coMp"|lex99password' -e "SHOW PLUGINS SONAME LIKE 'simple_password%'\G"

*************************** 1. row ***************************
   Name: simple_password_check
 Status: ACTIVE
   Type: PASSWORD VALIDATION
Library: simple_password_check.so
License: GPL

And here we see that the plugin is present and ACTIVE.

Before we jump into the next option, let’s stop the container and remove the reference to its name.

$ docker stop mariadb-server && docker rm mariadb-server

2. Enabling a plugin using an extra config file

Instead of passing in command line parameters to mariadbd, which can quickly get out of hand, a better approach is to have the plugin specified in a config file. As an example, let’s install the FederatedX plugin. First let’s create a config directory and a config file to instruct the server to install the plugin.

$ mkdir my_container_config/
$ printf "[mariadb]\nplugin-load-add=ha_federatedx\n" > my_container_config/my_container.conf

We can pass this file to the container as a volume, in the special /etc/mysql/conf.d directory. Files in this directory are read and appended to the default server configuration, on server startup.

$ docker run -d \
    --env MARIADB_USER=anel \
    --env MARIADB_PASSWORD='$coMp"|lex99password' \
    --env MARIADB_DATABASE=web_users \
    --env MARIADB_RANDOM_ROOT_PASSWORD=1 \
    --volume $PWD/my_container_config:/etc/mysql/conf.d:z \
    --name mariadb-server \
    mariadb:latest 

We can check for the presence of ha_federatedx like we did for simple_password_check.

$ docker exec mariadb-server mariadb -u anel -p'$coMp"|lex99password' -e "SHOW PLUGINS SONAME LIKE 'ha_federatedx%'\G"
*************************** 1. row ***************************
   Name: FEDERATED
 Status: NOT INSTALLED
   Type: STORAGE ENGINE
Library: ha_federatedx.so
License: GPL

And again, remember to cleanup.

$ docker stop mariadb-server && docker rm mariadb-server

3. Enabling a plugin during first database initialization

Another container startup hook that we can use is the /docker-entrypoint-initdb.d folder. This folder contains SQL scripts that are run when the container is initially created. They can be used to set up a custom database schema. We will be using it to install the disks plugin by running INSTALL SONAME. First, let’s create the database init folder and the sql script.

$ mkdir my_initdb/
$ printf 'INSTALL SONAME "disks";\n' > my_initdb/disks.sql

On startup with pass this directory as the /docker-entrypoint-init.d volume.

$ docker run -d \
    --env MARIADB_USER=anel \
    --env MARIADB_PASSWORD='$coMp"|lex99password' \
    --env MARIADB_DATABASE=web_users \
    --env MARIADB_RANDOM_ROOT_PASSWORD=1 \
    --volume $PWD/my_initdb:/docker-entrypoint-initdb.d:z \
    --name mariadb-server \
    mariadb:latest

Note: Usually one is passing a /var/lib/mysql volume as well. This will only have an effect if there is no database already initialized.

$ docker exec -it mariadb-server mariadb -u anel -p'$coMp"|lex99password' -e "SHOW PLUGINS SONAME LIKE 'disks%'\G"

*************************** 1. row ***************************
   Name: DISKS
 Status: ACTIVE
   Type: INFORMATION SCHEMA
Library: disks.so
License: GPL

4. Build a new image containing an additional plugin using a Dockerfile

Some plugins are not installed in the container by default because they contain additional dependencies. An example of this is the CONNECT storage engine. Instead we need to install it from the package mariadb-plugin-connect.

We use the layer approach of container images to create a new container image based on mariadb, in this case, using a Dockerfile.

Example of a Dockerfile my_connect_plugin.dockerfile:

FROM mariadb:latest
LABEL maintainer="anel@mariadb.org"
RUN apt-get -y update && \
    apt-get install mariadb-plugin-connect -y && \
    rm -rf /var/lib/apt/lists/*

In order to build the image from Dockerfile run:

$ docker build -t mariadb_connect . -f my_connect_plugin.dockerfile

We can see from the generated image, mariadb_connect, that the CONNECT storage engine is configured to load by a configuration file. This was installed from the mariadb-plugin-connect package:

$ docker run --rm mariadb_connect cat  /etc/mysql/mariadb.conf.d/connect.cnf
[mariadb]
plugin-load-add=ha_connect.so

Once built, we can use the mariadb_connect image like the original mariadb container image.

For more information see Creating a custom Docker image.

Conclusion and future work

In this blog we learned how to startup MariaDB in a container and various ways how to install plugins within the Docker Library MariaDB Container. We showed how to use configuration files and volumes in your container instances.

In the next blog we are going to use the image built from Dockerfile in order to do some work with the CONNECT Storage Engine. I have compiled a cheat sheet that covers the most frequent commands we’ll be using over the course of these tutorials.

As always, feedback is welcome! If you come across any problems when running any of these commands let us know in comments. You are welcome to chat about it on Zulip too! Any bugs you find should be reported in JIRA, in the MDEV project.