docker-compose for MySQL: example file and generator
Run a local MySQL database in Docker with your own user, password and port, and keep the data between restarts.
This docker-compose file starts a MySQL database with one command and keeps your data in a volume. Choose the version, passwords and port below, then run docker compose up -d.
Create your config file
Type your own values. The file below updates as you type, and nothing you type leaves your browser.
services:
db:
image: mysql:8.4
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: change-me-root
MYSQL_DATABASE: appdb
MYSQL_USER: app
MYSQL_PASSWORD: change-me-user
ports:
- "3306:3306"
volumes:
- mysqldata:/var/lib/mysql
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h localhost -uroot -p$$MYSQL_ROOT_PASSWORD"]
interval: 10s
timeout: 5s
retries: 5
volumes:
mysqldata:How this setup works
Step-by-step setup
- Install Docker Desktop (Windows, macOS) or Docker Engine with the Compose plugin (Linux).
- Save the config as docker-compose.yml in an empty folder.
- Start it: docker compose up -d. The first start can take up to a minute.
- Connect: mysql -h 127.0.0.1 -P 3306 -u app -p appdb.
- Read the log if something looks wrong: docker compose logs db.
What the important lines mean
- mysql:8.4 pins the version, so updates do not surprise you.
- mysqldata is a volume. It keeps your databases when the container is removed.
- The MYSQL_ variables create the database appdb and the user app only the first time the container starts.
- Other containers in the same file reach the database at host db, not localhost.
Common errors and how to fix them
- Access denied for user
- The passwords are only applied the first time. After changing them, reset with docker compose down -v. This deletes the data.
- Can’t connect to MySQL server on 127.0.0.1
- The container is still starting. Wait a minute and check docker compose logs db.
- Bind for 0.0.0.0:3306 failed: port is already allocated
- Another MySQL or container uses that port. Pick another port above, such as 3307.
- Container shows unhealthy
- The root password in the health check does not match. Reset the volume as shown above.
Frequently asked questions
- How do I connect to MySQL running in Docker?
- Use host 127.0.0.1, the port you chose, and the user and password from the file.
- Will I lose my data when I stop the container?
- No, as long as the volume stays. Data is lost only if you run docker compose down -v.
- Can I use MariaDB instead?
- Yes. Change the image to mariadb and keep the same MYSQL_ variables.
Free tools that help
- Password generatorCreate a random password with the length and characters you choose. It runs in your browser, uses secure randomness and shows how strong it is.
- Common ports listSearch a list of common TCP and UDP port numbers: SSH 22, HTTP 80, HTTPS 443, MySQL 3306, PostgreSQL 5432 and more, with dev server ports.
Fix a problem with this setup
- Docker port already allocatedFix "port is already allocated" in Docker and Docker Compose: find the container or program that holds the port and free it.
- MySQL access deniedFix error 1045. Default passwords for XAMPP and MAMP, and how to log in on Linux where root uses socket login.
- Docker container cannot reach localhostFix "connection refused" when an app in Docker calls localhost: use host.docker.internal, a Compose service name or host networking.
More container configs
- docker-compose for RedisRun Redis in Docker with a password, saved data and a memory limit.
- docker-compose for WordPressRun WordPress and its database locally in Docker with one command and keep your site between restarts.
- Dockerfile for Node.jsA small, working Dockerfile for a Node.js app, with build step, non-root user and health check options.
- Dockerfile for PythonA working Dockerfile for a Python web app, with Gunicorn, Uvicorn or a plain script.
- Docker Compose for MailpitRun a fake mail server on your computer, so test emails from your app show up in a web page instead of being sent.
- Kubernetes Deployment and ServiceA Deployment and Service YAML for your container image, with replicas, port, resource limits and health checks.