How to run MySQL Server 8 in a Docker Container

Running MySQL Server 8 in Docker

Learn how to deploy your MySQL Server 8 in a Docker container.

Resource Management Using Limits

A high performant database stores as much data in RAM as it possibly can. The reason for this is that accessing RAM is exponential faster than from any other storage available in a server. Therefore, the more data you can place there the faster you can access it.

Chances are you are going to run your database container on a server running other containers. To prevent other containers from starving your database server of crucial RAM we can grant our MySQL higher priority.

To gain a better understanding managing system resources with Docker, read our post for limiting a Docker containers memory and CPU.

Persistent Data Using Volumes

A relational database needs its data to be persistent. Docker, on the other hand, defaults to running containers in an ephemeral state — meaning data is never preserved; it is lost as soon as the container stops.

Docker provides volumes as a way to make our data persistent. Rather than storing volume data in the container itself, where it will be lost, we can store our data on the host filesystem, for example.

Running MySQL Server 8

Before we can begin we will need the MySQL Server image. Pull down the latest official MySQL Server image now.

docker pull mysql/mysql-server

Verify the image has been pulled down by listing your available images.

docker images

Let’s start our server without any options.

docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=mypassword mysql/mysql-server

Great, you should now have a running MySQL server container accessible using root password mypassword. Unfortunately, the data is emphemral and will lose any database we create once the container is stopped.

Let’s start the container with a mounted volume for our MySQL database.

docker run -d -p 3306:3306 -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=mypassword

With the addition of a volume mounted in the container as /var/lib/mysql, the directory MySQL stores database files, our data will not be persistent. Any new MySQL server container with the same volume mounted will have access to our previous data.

Using the volume example above Docker will store the mounted volume data in its own local volume storage. If you would prefer to map the volume to a specific directory, you need set both the host path and the container path with the volume flag.

Here’ we are going to run the MySQL server container with a volume mounted from /data/mysql on our Docker host’s file system.

Create the data volume directory.

mkdir -p /data/mysql

Start a new MySQL server container that mounts our new directory.

docker run -d -p 3306:3306 -v /data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=mypassword mysql/mysql-server

When the container launches check the contents of your data directory. You should see what you would typically see in /var/lib/mysql on a server running MySQL.


MySQL Server 8 Authentication Plugin Problems

With the introduction of MySQL 8 comes a new authentication plugin. This can cause authentication problems, even when running the latest client, oddly enough. Thankfully, Oracle allows us to use the older authentication plugin instead when we launch the container.

If you cannot log into MySQL Server check the logs

docker logs <container id>

You may notice the following error. This means you need to tell MySQL Server to user an older authentication plugin.

docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password mysql/mysql-server --default_authentication_plugin=mysql_native_password