Install MySQL in Docker

For developers, installing MySQL isn’t difficult, but it often involves several steps. I’ve documented a Docker Compose template that can directly launch a pre-configured MySQL container for development.

Docker compose

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
version: '3'
services:
mysql:
image: mysql:5.7
container_name: mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: '123456'
ports:
- 43306:3306
volumes:
- mysql_data:/var/lib/mysql
command: mysqld --character-set-server=utf8 --collation-server=utf8_general_ci --character-set-client-handshake=FALSE
healthcheck:
test: out=$$(mysqladmin ping -h 127.0.0.1 -u root --password=$$MYSQL_ROOT_PASSWORD); echo $$out | grep 'mysqld is alive' || { echo $$out; exit 1; }
start_period: 0s
interval: 5s
timeout: 3s
retries: 2

volumes:
mysql_data:
external: true

Configuration Explanation

Volumes

MySQL has three directories for storing data:

  • /var/lib/mysql: Data directory
  • /var/log/mysql: Log directory
  • /etc/mysql/conf.d: Configuration file directory

1️⃣ The most important one is, of course, the data directory.

2️⃣ The configuration file directory is optional, as we can use startup parameters instead. If you want to use it, create a my.cnf file with the following content:

1
2
3
4
5
[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
character_set_server = utf8

In fact, only character sets are configured, so it can be replaced by startup parameters.

3️⃣The log directory is the least important.

mysqld Startup Parameters

Use the following command to view them (there are a lot of options, save them to a file and then view):

1
2
docker run -it --rm mysql:5.7 --verbose --help > mysqld_args.txt
more mysqld_args.txt

Most options in the configuration file can be replaced by startup parameters, which are very suitable for quickly creating containers.

The startup command is:

1
mysqld --character-set-server=utf8 --collation-server=utf8_general_ci --character-set-client-handshake=FALSE

--character-set-server and --collation-server are easy to understand.

The meaning of --character-set-client-handshake is:

Don’t ignore client side character set value sent during handshake.

Namely, the client’s character set is prioritized, defaulting to TRUE. I set it to FALSE to force the client to use the server’s character set.

Health Check

The test command is:

1
out=$$(mysqladmin ping -h 127.0.0.1 -u root --password=$$MYSQL_ROOT_PASSWORD); echo $$out | grep 'mysqld is alive' || { echo $$out; exit 1; }
  • $$ is used to escape $, so every $ in the shell command should be doubled.
  • If the command’s exit code is 0, it means healthy; otherwise, it’s unhealthy.
  • This command can be used as a template: if the output of mysqladmin ping includes ‘mysqld is alive’, it exits normally. Otherwise, it prints the output and sets the exit code to 1.

References