Scenario
You are building a web app that needs a database and a cache, and you want MySQL + Redis running locally. Installing services by hand is painful (version conflicts, leftover residue, redo everything on a new machine), tutorials each cover one piece, and image pulls fail. What you want is a reusable compose file: one command brings up the whole stack, data survives restarts, and the same file works on another machine. This combo walks that path: docker compose defines the services (MySQL + Redis), the domestic image prefix solves image pulls, and named volumes keep data. After install you get a local dev stack started with one docker compose up -d, plus verification commands, daily operations and cleanup. It complements combo-docker-wsl-env (fixing "it won't run") and combo-mirror-setup (mirror config per package): this one covers "bring up a whole environment with compose".
Combo members
docker compose: the orchestration carrier (base tool, non-collected concept member)
- Download: bundled with Docker Desktop (Windows); docker-compose-plugin on Linux (Docker official or distro repos)
- Version: v2+ (measured v5.4.0); requires a working Docker daemon
- Install: confirm with
docker compose version; if missing, install Docker Desktop (Windows) or docker-compose-plugin (Linux)
MySQL 8.0 image (daocloud domestic mirror prefix)
- Download:
docker.m.daocloud.io/library/mysql:8.0(domestic mirror prefix of the official image; direct docker hub pulls failed in measurement, daocloud worked) - Version: 8.0 (pulled 2026-08-30, ~500MB)
- Install: point the compose
image:field at it;docker compose up -dpulls automatically (see walkthrough steps 2/3)
Redis 7 image (daocloud domestic mirror prefix)
- Download:
docker.m.daocloud.io/library/redis:7-alpine(lightweight alpine variant, starts in seconds - measured) - Version: 7-alpine (pulled 2026-08-30, ~100MB)
- Install: point the compose
image:field at it;docker compose up -dpulls automatically (see walkthrough steps 2/3)
Solution overview
| Component | Owns what | Why this one |
|---|---|---|
| docker compose (base tool, non-collected concept member) | Define multiple services in one YAML and orchestrate start/stop | De-facto standard; bundled with Docker Desktop (measured v5.4.0) |
| MySQL 8.0 image (daocloud) | Database | The most common dev database; domestic mirror pull measured working |
| Redis 7 image (daocloud) | Cache/queue | Lightweight (alpine), starts in seconds (measured) |
Why this install order: confirm docker compose first, then write the compose file (service definitions), then bring the stack up and wait for MySQL before smoke testing (MySQL initializes its data directory on first start, ~20s measured; Redis starts in seconds). Adjust port mappings to what is free on your machine (this measurement used 13306 because 3306 was occupied).
Quick start (skip the walkthrough)
The one-click script is generated from this document (rendered at pages/combos/combo-docker-compose-dev.sh). Backup and check prerequisites first, then run:
bash pages/combos/combo-docker-compose-dev.sh
- You get: a MySQL + Redis dev stack, started with one
docker compose up -d, data kept in named volumes. - Estimated time: 3-8 minutes. Biggest risk point = first image pull (mysql:8.0 + redis:7-alpine total ~600MB measured, via daocloud).
- Prerequisites: Docker Desktop (WSL2 backend) or Linux Docker; RAM >= 4GB; disk >= 2GB free; ports 3306/6379 free (change mappings if occupied).
Want to understand each step and how to recover? See the walkthrough. If the one-click script fails, run the steps manually.
Walkthrough
Step 1: confirm docker compose works (first because it carries everything)
Docker Desktop bundles compose v2 (docker compose subcommand). Confirm the version:
docker compose version
Expected output: Docker Compose version v5.4.0 (measured in this environment; v2+ is fine) Confirm:
docker compose versionprints a version;docker infoshows a healthy Server (daemon reachable).
Stuck?:
- command not found -> install Docker Desktop (Windows) or docker-compose-plugin (Linux).
- daemon unreachable -> see the docker-daemon-connect troubleshooting in combo-docker-wsl-env.
Step 2: write docker-compose.yml (the core step: one file defines every service)
The compose file declares services, ports, volumes and health checks. The one below matches the measurement: db service (MySQL 8.0, volume dbdata, health check via mysqladmin ping), cache service (Redis 7-alpine, volume cachedata). Images use the docker.m.daocloud.io prefix - this is the key to pulling in China (direct docker hub was unreachable in measurement).
services:
db:
image: docker.m.daocloud.io/library/mysql:8.0
container_name: dev-db
environment:
MYSQL_ROOT_PASSWORD: yourpass
MYSQL_DATABASE: app_dev
ports:
- "13306:3306"
volumes:
- dbdata:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-pyourpass"]
interval: 5s
timeout: 3s
retries: 20
cache:
image: docker.m.daocloud.io/library/redis:7-alpine
container_name: dev-cache
ports:
- "16379:6379"
volumes:
- cachedata:/data
volumes:
dbdata:
cachedata:
Expected output: file written (no output) Confirm:
docker compose configrenders the resolved config with no errors (measured PASS).
Stuck?:
- YAML error -> indentation must be consistent (two spaces); a space is required after colons.
- Port conflict -> map to 13306 when 3306 is occupied locally (the measured scenario); check with
ss -ltn | grep 3306first.
Step 3: bring the stack up and wait (because MySQL initializes on first start)
up -d starts everything in the background. MySQL initializes its data directory on first start (~20s measured; connections are refused during that window). Redis is ready in seconds. Poll with the health check:
docker compose up -d
for i in $(seq 1 18); do
docker exec dev-db mysqladmin ping -h 127.0.0.1 -pyourpass >/dev/null 2>&1 && { echo "mysql ready ~$((i*5))s"; break; }
sleep 5
done
docker compose ps
Expected output: mysql ready ~20s; docker compose ps shows both services Up (measured: cache Up, db Up with health: starting -> healthy) Confirm:
docker compose psshows both containers Up;docker exec dev-db mysqladmin ping -h 127.0.0.1 -pyourpassprintsmysqld is alive(measured exit 0).
Stuck?:
- not ready after 90s ->
docker compose logs dbfor the init log; usually slow disk or wrong config. - container restart loop ->
docker compose logsto locate; port conflicts are common (if a changed mapping still conflicts, use a larger port).
Step 4: smoke test (because a running process is not a working service)
Process Up != readable/writable. This measurement used real DML and Redis reads/writes:
docker exec dev-db mysql -h 127.0.0.1 -uroot -pyourpass -e "USE app_dev; CREATE TABLE IF NOT EXISTS smoke (id INT PRIMARY KEY AUTO_INCREMENT, v VARCHAR(32)); INSERT INTO smoke (v) VALUES ('ok'); SELECT COUNT(*) FROM smoke;"
docker exec dev-cache redis-cli ping
docker exec dev-cache redis-cli set probe ok
docker exec dev-cache redis-cli get probe
Expected output: MySQL prints COUNT(*) -> 1 (measured rows_ok=1, exit 0); Redis prints PONG / OK / ok (measured all passed) Confirm:
- all three commands exit 0; MySQL can create/insert/query, Redis can write and read.
Stuck?:
- MySQL Access denied -> password mismatch with MYSQL_ROOT_PASSWORD in the compose file (after changing the password, rebuild with
down -v; the volume re-initializes). - Redis unreachable -> if even the in-container redis-cli fails, it is a service problem; check logs.
Step 5: daily operations and volumes (because volumes are how data survives)
Daily commands: docker compose ps (status), logs -f (logs), exec <service> bash (enter a container), down (stop and remove containers, data kept), up -d (start again, data still there).
docker compose down # stop the stack, named volumes kept
docker compose up -d # start again, data survives (measured)
docker compose down -v # remove everything (volumes too) - only when you want a reset
Expected output: down prints Stopped/Removed; after up -d, docker exec dev-db mysql ... -e "SELECT COUNT(*) FROM smoke" still returns 1 (data survived, measured) Confirm:
- data survives: after down -> up -d, the table and rows from before are still there;
- zero residue: after
docker compose down -v,docker ps -a | grep dev-returns nothing (measured: containers/volumes/network all removed).
Stuck?:
- data lost -> check whether you ran
down -v; also check the volume is actually mounted (missingvolumes:section loses data).
Daily use
- Start/stop:
docker compose up -d/docker compose down(no -v keeps data). - Logs:
docker compose logs -f db. - Enter a container:
docker exec -it dev-db bash. - App connections: MySQL
127.0.0.1:13306(root/yourpass, db app_dev); Redis127.0.0.1:16379. - New machine: copy the compose file +
up -d(volumes are per-machine, they don't travel with the file).
Uninstall and cleanup
- Stop the stack:
docker compose down(volumes kept, restartable anytime). - Full cleanup:
docker compose down -v(containers + network + volumes removed; measured zero residue). - Optional image cleanup:
docker image rm docker.m.daocloud.io/library/mysql:8.0 docker.m.daocloud.io/library/redis:7-alpine.
Install order
- Confirm docker compose (step 1) -> 2. write the compose file (step 2) -> 3. bring up and wait (step 3) -> 4. smoke test (step 4). The combo is ready only after reads/writes pass end to end.
Dependency warnings
- Conflicts/ports: map to 13306 when 3306 is occupied locally (the measured scenario); 16379 for 6379; check
ss -ltn | grep -E ":3306|:6379"before starting. - Versions: compose v2+ (measured v5.4.0); mysql:8.0; redis:7-alpine; no port overlap with existing services (site 8123 / open-webui 3000 / ollama 11434 - measured).
- Environment: Docker Desktop (WSL2 backend) or Linux Docker; RAM >= 4GB; disk >= 2GB; MySQL needs ~20s initialization on first start (measured), refused connections during that window are normal.
- China network: images must use the
docker.m.daocloud.ioprefix (direct docker hub pulls failed in measurement; daocloud succeeded);compose pullpre-pulls. - Data: named volumes survive
down;down -vdeletes them (measured) - only use when you want a reset.
FAQ
- 3306 is taken by a local MySQL? -> Map
"13306:3306"and connect to 13306; inside the container it is always 3306, no app changes needed. - Image pulls fail? -> Use the
docker.m.daocloud.io/library/prefix (measured working); otherwise retrydocker compose pullin another network window. - Does
down -vdelete data? -> Yes. Named volumes are removed with -v (measured). To keep data usedocker compose down(no -v). - Does this conflict with other Docker Desktop clusters? -> No. Independent compose project name and port mappings (measured: containers/volumes/network zero residue); no interaction with hello-k8s-ai-dev or other clusters.
Acceptance check (one shot)
Run this block after installing; all green = combo ready; any failure -> back to the matching step in the install walkthrough.
docker compose ps
docker exec dev-db mysql -uroot -pyourpass -e "SELECT 1"
docker exec dev-cache redis-cli ping
ι’ζθΎεΊ: both services Up; MySQL prints 1; Redis prints PONG (measured 2026-08-30: cache Up, db Up (health: starting->healthy), PONG/OK/ok all passed)
Note: replace the password with your compose config (example yourpass); docker compose down cleans up, data stays in named volumes.Verification evidence
Every combo is measured in an isolated environment (smoke + write-surface check); unmeasured items are honestly marked in the text, and measurement dates are listed in the verification section below.
Verified 2026-08-30 Β· TTL expires 2027-02-26 (180 days)
- Combo measurement 2026-08-30 (isolated dir /tmp/d8-compose-test + independent project d8test): daocloud pulled mysql:8.0 + redis:7-alpine -> compose config PASS -> up -d -> MySQL ready after ~20s (first-start init) -> mysqladmin ping
mysqld is alive(exit 0) -> create/insert/queryrows_ok=1(exit 0) -> redis PONG + set/get ok (exit 0) -> volumes created (d8test_d8data / d8test_d8cache) -> after down -v: containers/volumes/network zero residue. - Evidence path: local repro log 2026-08-30.
- Not measured (honest): compose file migration across machines (volumes are per-machine); non-daocloud registries (e.g. a company mirror) not verified.
Related problems
β All combos ο½ Tool Catalog ο½ Hit a problem? Submit a helpdesk card