Operations 11 min read

Docker + MySQL: Why They Clash and How to Avoid Hair‑Pulling Pitfalls

This article analyzes common pitfalls when running MySQL inside Docker containers—such as data loss, resource exhaustion, insecure defaults, networking mishaps, and missing backups—and provides concrete, step‑by‑step remedies including volume persistence, resource limits, custom configs, security hardening, and automated backup strategies.

Golang Shines
Golang Shines
Golang Shines
Docker + MySQL: Why They Clash and How to Avoid Hair‑Pulling Pitfalls

Why Docker + MySQL can be problematic

Docker provides isolation, portability and reproducible environments for MySQL, but misconfiguration can cause data loss, resource exhaustion, security exposure, network failures and backup gaps.

Five fatal pitfalls

❌ Pitfall 1: Data "Schrödinger" persistence

Scenario: After inserting test data, the container is restarted and the data disappears. Root cause: Docker containers are ephemeral; removing a container also deletes its filesystem, including /var/lib/mysql .
📦 Container lifecycle
┌─────────────────┐
│  Start → Run → Remove  │
│                     │
│  💾 Data lives in /var/lib/mysql │
│  🗑️  Container removal → Data loss │
└─────────────────┘

❌ Pitfall 2: Resource allocation "guesswork"

Scenario: A test container runs fine, but in production MySQL consumes all memory and CPU, triggering the host OOM killer. Root cause: No resource limits were set, so MySQL monopolizes host resources.
# No limits – dangerous
docker run mysql:8.0

# With limits – safe
docker run --memory="1g" --cpus="2" mysql:8.0

❌ Pitfall 3: Insecure default configuration

Scenario: The container uses the default root/root password and exposes port 3306 to the public internet. Root cause: Weak credentials and open ports make the database an easy target.
# Dangerous: expose to world
-p 3306:3306

# Safer: bind to localhost only
-p 127.0.0.1:3306:3306

❌ Pitfall 4: Network misconfiguration "maze mode"

Scenario: Application containers cannot connect to the MySQL container, reporting Can't connect to MySQL server . Root cause: Incorrect Docker network mode or hard‑coded IPs instead of container names.
# Wrong: use IP
-h 172.18.0.3

# Correct: use container name (Docker DNS resolves it)
-h mysql_prod

❌ Pitfall 5: Backup "non‑existent"

Scenario: After accidentally deleting a database, there is no backup to restore. Root cause: Assuming a Docker volume is a backup; however, docker volume rm can delete the data instantly.

Five rescue tips

✅ Tip 1: Persist data with volumes

Mnemonic: "Data must persist, Volume cannot be omitted!"
docker run --name mysql_prod \
  -e MYSQL_ROOT_PASSWORD=StrongP@ssw0rd \
  -v mysql_data:/var/lib/mysql \
  -d mysql:8.0

# Verify volume
docker volume ls   # shows mysql_data

✅ Tip 2: Limit resources to keep the host stable

Mnemonic: "Limit resources, system stays alive!"
docker run --name mysql_prod \
  --memory="2g" \
  --memory-swap="2g" \
  --cpus="2" \
  --oom-kill-disable \
  -d mysql:8.0

Typical resource recommendations (adjust to workload):

Development / test: 512 MB‑1 GB memory, 0.5‑1 CPU core

Small production: 2‑4 GB memory, 2‑4 CPU cores

Medium production: 8‑16 GB memory, 4‑8 CPU cores

Large production: use a cluster, scale horizontally

✅ Tip 3: Custom MySQL configuration

Mnemonic: "Default config not enough, my.cnf to the rescue!"
# my-custom.cnf
[mysqld]
max_connections=500
innodb_buffer_pool_size=1G
slow_query_log=1

# Mount the config
docker run --name mysql_prod \
  -v $(pwd)/my-custom.cnf:/etc/mysql/conf.d/custom.cnf \
  -d mysql:8.0

Common tuning parameters:

max_connections ≈ 200‑500 (avoid excessive connections)

innodb_buffer_pool_size ≈ 70 % of physical memory

slow_query_log = 1, long_query_time = 2 seconds

✅ Tip 4: Security hardening

Mnemonic: "Strong password, hidden port!"
docker run --name mysql_prod \
  -e MYSQL_ROOT_PASSWORD=$(openssl rand -base64 32) \
  -p 127.0.0.1:3306:3306 \
  --network my_private_net \
  -d mysql:8.0

Password length > 16 characters, mixed case, numbers, symbols

Disable remote root login; create limited‑privilege accounts

Enable SSL for production connections

Rotate passwords regularly

✅ Tip 5: Automated backups

Mnemonic: "No backup, you’ll cry!"
# backup.sh
#!/bin/bash
CONTAINER="mysql_prod"
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)

docker exec $CONTAINER \
  /usr/bin/mysqldump -u root -p$MYSQL_ROOT_PASSWORD \
  --all-databases | gzip > $BACKUP_DIR/backup_$DATE.sql.gz

# Keep last 7 days
find $BACKUP_DIR -name "backup_*.sql.gz" -mtime +7 -delete

Backup strategy (example):

Full backup: once daily during low‑traffic window

Incremental: hourly using binary logs

Off‑site: weekly sync to object storage (OSS/S3) for disaster recovery

Troubleshooting mini‑play

🎭 Scenario 1: Container fails to start

# Check logs first (covers most issues)
docker logs mysql_prod --tail 50

# Common errors & fixes
❌ "Access denied for user 'root'@'localhost'"
✅ Verify MYSQL_ROOT_PASSWORD env var

❌ "Can't create directory '/var/lib/mysql'"
✅ Ensure volume mount permissions (chown -R 999:999 /host/mysql_data)

🎭 Scenario 2: Connection timeout

# Diagnose network
docker network ls
docker inspect mysql_prod | grep Networks
docker exec mysql_prod ping app_container

# Quick fix: use container name instead of IP
# ❌ -h 172.18.0.3
# ✅ -h mysql_prod

🎭 Scenario 3: Performance degradation

# Monitor resources
docker stats mysql_prod

# Inspect MySQL internals
docker exec -it mysql_prod mysql -uroot -p
> SHOW PROCESSLIST;
> SHOW ENGINE INNODB STATUS;

Conclusion

Key practices for a stable Docker + MySQL deployment:

1️⃣ Persist data – use Docker volumes
2️⃣ Limit resources – prevent host OOM
3️⃣ Tune configuration – improve performance
4️⃣ Harden security – block unauthorized access
5️⃣ Automate backups – avoid data loss
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DockerMySQLsecurityData persistenceBackupContainersResource limits
Golang Shines
Written by

Golang Shines

We share daily the latest Golang technical articles, practical resources, language news, tutorials, and real-world projects to help everyone learn and improve.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.