Chapter 1.6 - Deploying MySQL with Docker to Best Practices

MySQL is the world’s most popular open-source relational database management system (RDBMS), widely used for web applications. It is a product of Oracle.

This guide provides a comprehensive overview of how to deploy and manage MySQL using Docker, incorporating the latest standards and best practices.

1. Downloading the Docker Image

To begin, you need to pull the official MySQL Docker image. It’s highly recommended to use the latest stable or Long Term Support (LTS) version for enhanced features, performance, and security. As of July 2025, MySQL 8.4 is the latest LTS release.

You can pull the image using the docker pull command:

# Or for the absolute latest version:
docker pull mysql:latest
# Or for the latest Long Term Support release:
# docker pull mysql:latest-lts

This command fetches the specified MySQL image from Docker Hub.

2. Running the MySQL Container

When running a database in Docker, data persistence is crucial. Docker named volumes are the recommended way to manage data, ensuring your database files are not lost when the container is stopped, removed, or updated.

Here’s an updated docker run command incorporating best practices:

docker volume create mysql_data

docker run --name mysql-server \
  -p 3306:3306 \
  -v mysql_data:/var/lib/mysql \
  -v /path/to/your/custom/my.cnf:/etc/mysql/conf.d/my.cnf:ro \
  -e MYSQL_ROOT_PASSWORD=your_strong_password \
  -e TZ=America/Edmonton \
  -d mysql:latest

Let’s break down each option:

Note on Bind Mounts vs. Named Volumes:

While the original article used bind mounts (-v $HOME/_docker/mysql/data:/var/lib/mysql), Docker named volumes (-v mysql_data:/var/lib/mysql) are generally preferred for database persistence. Named volumes are fully managed by Docker, are easier to back up, and ensure better portability.

3. Accessing the Container and Viewing Logs

You can execute commands inside your running MySQL container using docker exec.

To get a bash shell inside the mysql-server container:

docker exec -it mysql-server bash

To view the MySQL Server logs, which are streamed to Docker’s standard output:

docker logs mysql-server

4. Configuring MySQL

For advanced configurations, create a custom my.cnf file on your host machine and mount it into the container as shown in the docker run command. Below are common configurations that should be included in your my.cnf (e.g., at /path/to/your/custom/my.cnf):

# For advice on how to change settings please see
# https://dev.mysql.com/doc/refman/8.4/en/server-configuration-defaults.html

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

# Ignore case sensitivity of database table names (common for development/testing, but consider implications for production)
lower_case_table_names = 1

# Set server ID for replication (must be unique in a replication topology)
server-id = 1

# Enable binary logging for replication and point-in-time recovery
log_bin = /var/lib/mysql/mysql-bin.log
binlog_format = ROW # Recommended format for reliability in replication
max_binlog_size = 100M # Maximum size of each binary log file
binlog_expire_logs_seconds = 864000 # Expire binary logs after 10 days (864000 seconds)

# Basic InnoDB settings (adjust based on your server's RAM)
# innodb_buffer_pool_size = 70% of your RAM for dedicated server, else 10%
# Example for a server with 2GB RAM:
# innodb_buffer_pool_size = 1400M

# Data directory and socket path (usually handled by Docker image, but can be specified)
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

# Error log path (optional, Docker logs are usually sufficient)
# log-error=/var/log/mysqld.log

# PID file path (usually handled by Docker image)
# pid-file=/var/run/mysqld/mysqld.pid

Key Configuration Details:

5. Applying Configuration Changes and Restarting

After modifying your my.cnf file on the host, you need to restart the MySQL container for the changes to take effect:

docker restart mysql-server

6. Entering the Database and Verification

To connect to your MySQL database inside the container:

# Enter the mysql container's bash shell
docker exec -it mysql-server bash

# Then, login to MySQL as root (you'll be prompted for the password)
mysql -uroot -p

Once logged into the MySQL prompt, you can verify your configurations:

7. Additional Best Practices

8. Troubleshooting

Conclusion

By leveraging Docker for your MySQL deployments, you gain significant advantages in terms of portability, isolation, and simplified management. Adhering to the best practices outlined in this guide, from utilizing named volumes for data persistence and carefully configuring my.cnf to prioritizing strong security measures and regular backups will ensure a robust, scalable, and maintainable MySQL environment. Continuously monitor your database performance and keep your Docker images updated to maintain optimal operation and security.