Preparing Mount Points
Create directories for persistent configuration and data storage:
mkdir -p /opt/mysql-instance/{conf,storage}
Configuring Character Sets
Create the configuration file at /opt/mysql-instance/conf/custom.cnf:
[mysqld]
user=mysql
character-set-server=utf8mb4
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
Pulling the MySQL Image
List local images:
docker images
Search for available MySQL images:
docker search mysql
Pull a specific version (5.7 recommended for stability):
docker pull mysql:5.7
Or pull the latest version:
docker pull mysql
Creating the Startup Script
Create a script file at /opt/mysql-instance/start.sh:
#!/bin/bash
docker run -d \
--name mysql-server \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=SecurePassword123 \
-v /opt/mysql-instance/conf/custom.cnf:/etc/my.cnf \
-v /opt/mysql-instance/storage:/var/lib/mysql \
--restart=unless-stopped \
mysql:5.7
The backslash (\) must be followed by an actual newline character, not spaces.
Parameter Reference
-d: Run container in detached mode (background)
-i: Interactive mode
-t: Allocate a pseudo-TTY
-p: Port mapping (host:container)
-e: Environment variables
-v: Volume mounts (host_path:container_path)
--name: Container identifier
--restart: Boot policy
Restart Policies Explained
| Policy | Behavior |
|---|---|
no |
Never restart (default) |
on-failure |
Restart on non-zero exit code |
on-failure:N |
Restart up to N times |
always |
Always restart |
unless-stopped |
Restart unless manually stopped |
The always policy ensures the container starts after Docker daemon restart. The unless-stopped policy differs in that stopped containers remain stopped after daemon restart.
Apply the script:
chmod +x /opt/mysql-instance/start.sh
./start.sh
Update an existing container's restart policy:
docker update --restart=unless-stopped mysql-server
Runtime Error Resolution
If encountering the cgroup configuration error:
container_linux.go:235: starting container process caused
"process_linux.go:258: applying cgroup configuration..."
Update the system and restart:
yum update -y
systemctl restart docker
Verifying the Installation
Check running containers:
docker ps | grep mysql
Access the container shell:
docker exec -it mysql-server bash
Connect to MySQL:
mysql -uroot -pSecurePassword123
Exit using exit command twice (once for MySQL, once for shell).
Enabling Remote Access
Security Group Configuration
Add an inbound rule for port 3306 in your cloud provider's security group settings.
Granting Remote Privileges (MySQL 8.0+)
Switch to the mysql database:
USE mysql;
Query existing users:
SELECT host, user FROM mysql.user;
Create a remote-accessible root user:
CREATE USER 'admin'@'%' IDENTIFIED BY 'StrongPassword456';
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%';
FLUSH PRIVILEGES;
Note: MySQL 8.0+ uses a different syntax for privilege grants than older versions.
Authentication Plugin Adjustment
MySQL 8.0+ uses caching_sha2_password by default. Some clients require mysql_native_password:
ALTER USER 'admin'@'%' IDENTIFIED BY 'StrongPassword456' PASSWORD EXPIRE NEVER;
ALTER USER 'admin'@'%' IDENTIFIED WITH mysql_native_password BY 'StrongPassword456';
FLUSH PRIVILEGES;
Modifying Exposed Ports
To change the external port (e.g., avoiding port 3306 for security):
- Stop the container and Docker:
docker stop mysql-server
systemctl stop docker
- Edit
/var/lib/docker/containers/{container_id}/hostconfig.json:
"PortBindings":{"3306/tcp":[{"HostIp":"","HostPort":"3307"}]}
-
Edit the corresponding
config.v2.jsonto updateExposedPortsandPortssections. -
Restart Docker and the container.