Configure development environment: Manage multi-version MySQL and Redis with Docker
This article is a development environment for the ‘From Windows to Ubuntu: Complete Guide to Migration and Configuration’ series.
It is suitable for developers who have completed the Ubuntu system installation and hope to build an efficient, isolated and multi-version database environment.
Why use Docker to manage databases?
Under Windows, I am used to running a separate database container with WSL2 + Docker, and it will naturally continue after migrating to Ubuntu. Compared to install directly on the host machine:
- Coexist with multiple versions: The same machine runs mysql 5.7 and 8.0 at the same time, and redis does not interfere with each other.
- environmental isolation: The database of each project is shared independently or by version, and the configuration is not fighting.
- Easy to clean: Release resources when the container stops, the data volume is reserved, and there is no residue after deletion.
- version locked:
mysql:5.7The image always corresponds to the latest version 5.7, and will not be automatically changed due to system upgrades.
This article has MySQL 5.7, MySQL 8.0, Redis 7.2 For example, build three independent containers for subsequent Go/PHP projects to share.
1. Install the Docker engine (pure command line, no docker desktop)
Ubuntu’s ‘Software’ or ‘Application Center’ cannot find Docker Desktop, which is a feature of the Linux distribution software distribution – professional tools usually need to manually add official software sources. The official source installation is lighter and more stable.
1. Uninstall old packages that may conflict (the new system can be skipped)
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
sudo apt remove -y $pkg
done
If you are a newly installed Ubuntu 26.04, these packages do not exist, this step can be skipped.
2. Add the official Docker GPG key and software source
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl --http1.1 -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
Step on the pit record: if
curlDownload GPG TimesCurl: (16) Error in the HTTP2 Framing Layer, plus parameters--http1.1can be solved.
3. Install the Docker engine and the Compose plugin
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
4. Add the current user to the Docker group (sudo free)
sudo usermod -aG docker $USER
Must log out and log in again (or restart), otherwise docker The command still requires sudo.
5. Verify the installation
docker --version # 输出如 Docker version 29.5.2
docker compose version # 输出 Docker Compose version v2.x
2. Troubleshooting the problem of network and mirror pulling (real record of stepping on the pit)
In the VPN environment, the network timeout is encountered when the first test image is pulled. The following is a complete investigation and solution process.
2.1 First attempt: run hello-world directly
docker run hello-world
output:
Unable to find image 'hello-world:latest' locally
docker: Error response from daemon: failed to resolve reference "docker.io/library/hello-world:latest": failed to do request: Head "https://registry-1.docker.io/v2/library/hello-world/manifests/latest": dial tcp 128.242.240.85:443: i/o timeout
2.2 Restart the Docker service, try again
sudo systemctl restart docker
docker run hello-world
Still timed out, this time the IP becomes 31.13.69.245:
dial tcp 31.13.69.245:443: i/o timeout
2.3 Check if the host can access the Docker Hub
curl -I https://registry-1.docker.io/v2/
output:
HTTP/1.1 200 Connection established
HTTP/2 401
date: Sun, 31 May 2026 10:04:04 GMT
content-type: application/json
content-length: 87
...
This meansThe host network is normal(Returns 401 because there is no authentication, but the connection is established), the problem is with the Docker daemon itself.
2.4 Configure the domestic mirror accelerator (first attempt)
Create /etc/docker/daemon.json, use the University of Science and Technology of China, NetEase, Baidu mirror:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
]
}
EOF
sudo systemctl daemon-reload
docker run hello-world
The result is still timed out (IP becomes 103.97.3.19):
dial tcp 103.97.3.19:443: i/o timeout
2.5 Restart Docker again, the problem remains
sudo systemctl restart docker
docker run hello-world
This error changed:
dial tcp: lookup docker.mirrors.ustc.edu.cn on 127.0.0.53:53: no such host
Explain that the domain name of the image accelerator cannot be resolved – VPN affects DNS.
2.6 Final Scenario: Use DaoCloud Image + Specify Public DNS
Modify /etc/docker/daemon.json, and configure the image and DNS at the same time:
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://docker.m.daocloud.io"],
"dns": ["8.8.8.8", "1.1.1.1"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
docker run hello-world
This time it finally succeeded in pulling and running:
latest: Pulling from library/hello-world
4f55086f7dd0: Pull complete
d5e71e642bf5: Download complete
Digest: sha256:0e760fdfbc48ba8041e7c6db999bb40bfca508b4be580ac75d32c4e29d202ce1
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
...
Conclusion: In a VPN environment, the Docker daemon may not use the system DNS correctly, and you need to explicitly specify a common DNS (such as 8.8.8.8) and cooperate with an available image accelerator. DaoCloud image docker.m.daocloud.io Available in this environment.
3. Deploy MySQL 5.7/8.0 and Redis 7.2 containers
3.1 Create a project directory
mkdir -p ~/docker/services
cd ~/docker/services
3.2 Writing docker-compose.yml
cat > docker-compose.yml << 'EOF'
version: "3.8" # 新版 Docker Compose 可省略该行,会有警告但无影响
networks:
dev-network:
driver: bridge
services:
mysql57:
image: mysql:5.7
container_name: mysql57
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: mystrongpwd57
ports:
- "3306:3306"
volumes:
- ./data/mysql57:/var/lib/mysql
networks:
- dev-network
mysql80:
image: mysql:8.0
container_name: mysql80
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: mystrongpwd80
ports:
- "3307:3306"
volumes:
- ./data/mysql80:/var/lib/mysql
networks:
- dev-network
command: --default-authentication-plugin=mysql_native_password
redis:
image: redis:7.2
container_name: redis72
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- ./data/redis72:/data
command: redis-server --requirepass myredispass --appendonly yes
networks:
- dev-network
EOF
dodge a pit reminder: MySQL 8.0 needs to be added
--default-authentication-plugin=mysql_native_passwordOtherwise, some old client connections will reportcaching_sha2_passworderror.
3.3 The first startup (encountered to network fluctuations)
docker compose up -d
The output shows:
WARN[0000] the attribute `version` is obsolete...
[+] up 19/24
✘ Image mysql:8.0 Error failed to resolve reference ... EOF
The cause of the error is that authentication failure (EOF) is a temporary problem with the image accelerator when pulling MySQL 8.0.
3.4 Retry directly, success
docker compose up -d
All images were pulled successfully this time:
[+] up 25/34
✔ Image mysql:5.7 Pulled
✔ Image redis:7.2 Pulled
✔ Image mysql:8.0 Pulled
✔ Network services_dev-network Created
✔ Container mysql57 Started
✔ Container redis72 Started
✔ Container mysql80 Started
Experience: Docker Hub or mirror accelerator has occasional network problems, and it can often be solved by retrying.
4. Verify container operation and connection test
4.1 View container status
docker ps
output:
CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
9ec38ca384b6 redis:7.2 "docker-entrypoint.s…" 45 seconds ago Up 42 seconds 0.0.0.0:6379->6379/tcp, [::]:6379->6379/tcp redis72
4e93fd2e2c3f mysql:8.0 "docker-entrypoint.s…" 45 seconds ago Up 42 seconds 33060/tcp, 0.0.0.0:3307->3306/tcp, [::]:3307->3306/tcp mysql80
29598dd51087 mysql:5.7 "docker-entrypoint.s…" 45 seconds ago Up 42 seconds 0.0.0.0:3306->3306/tcp, [::]:3306->3306/tcp, 33060/tcp mysql57
4.2 Connecting to MySQL 5.7
docker exec -it mysql57 mysql -uroot -pmystrongpwd57
Enter the mysql command line and execute exit Exit.
4.3 Connect MySQL 8.0
docker exec -it mysql80 mysql -uroot -pmystrongpwd80
Also successfully entered.
4.4 Connecting to Redis
docker exec -it redis72 redis-cli -a myredispass
output prompt Warning: using a password with-a... may not be safe(only security warnings, not affecting use), then enter 127.0.0.1:6379> prompt.
At this point, all three database containers have been running normally.

5. Provide project container connection (network communication)
Database containers are located on custom networks services_dev-network(automatically created by docker-compose). The project container only needs to join the same external network, you can pass container name visit.
Give typical examples docker-compose.yml Fragment:
networks:
default:
external:
name: services_dev-network
services:
go-app:
image: golang:1.26-alpine
networks:
- default
environment:
DB_HOST: mysql57 # 或 mysql80
REDIS_HOST: redis72
Connect in code mysql57:3306,redis72:6379 can.
6. Version selection instructions and precautions
| Service | Version | mainstream | life cycle reminder |
|---|---|---|---|
| mysql 5.7 | 5.7.44 | About 18.8%, which is a common version of the legacy system | EOL in October 2023,No more official security updates, it is not necessary to recommend the use of new projects |
| MySQL 8.0 | 8.0.46 | The current most mainstream (58%) | Official support will be April 30, 2026 At the end of the day, you need to upgrade to 8.4 LTS |
| Redis 7.2 | 7.2.x | Stable and mature | The basic version of the open source branch Valkey, you can use it with confidence |
If it is a new project, it is recommended to use it directly MySQL 8.4 LTS(supported until 2031) and Redis 7.2.
7. Quick check of daily management orders
| Operating | Command |
|---|---|
| Start all services | cd ~/docker/services && docker compose up -d |
| Stop all services | cd ~/docker/services && docker compose down |
| Restart MySQL 8.0 alone | Docker restart mysql80 |
| View MySQL 5.7 logs | docker logs -f mysql57 |
| Enter the Redis command line | docker exec -it redis72 redis-cli -a password |
| Clean up unused images/containers | docker system prune -a |
| Backup data volumes | tar -czf mysql57-backup.tar.gz ~/docker/services/data/mysql57 |
8. Summary
At this point, we have completed a clean, reusable database container environment:
- MySQL 5.7 → Port 3306
- MySQL 8.0 → Port 3307
- Redis 7.2 → Port 6379
All data is persisted in ~/docker/services/data/, the container automatically runs with the system startup. For any subsequent Go, PHP, Node.js projects, just connect these container names through the Docker network, you can quickly get multi-version database support.
The commands in this article are all verified under Ubuntu 26.04, and Docker version 29.5.2.
If you have any questions or exchanges, please leave a message in the comment area.