Installing MySQL with Docker

Docker gives you a clean, reproducible MySQL environment without modifying your host operating system. Whether you are on Windows, macOS, or Linux, the steps are nearly identical. This chapter covers Docker Desktop on Windows (via WSL2) and macOS. If you are already comfortable with Docker, you will be up and running in minutes.

Prerequisites

  • Windows 10/11 with WSL2, or macOS 10.15+, or Linux
  • Docker Desktop installed and running
  • Approximately 1 GB of free disk space for the MySQL image

Installing MySQL directly on your machine works fine, but Docker offers several advantages for learning and development:

ConcernNative InstallDocker
CleanupUninstallers leave files behinddocker rm removes everything
Multiple versionsDifficultRun different containers side by side
Team consistencyEveryone configures manuallySame image, same command, same result
Host pollutionModifies system PATH and servicesCompletely isolated
ResetComplexOne command to start fresh

For this tutorial, a Docker container running MySQL 8 is the fastest path to a working database.

Installing Docker Desktop

Windows

  1. Install WSL2 if you have not already. Open PowerShell as Administrator and run:
bash
wsl --install
  1. Download Docker Desktop from docker.com and run the installer.
  2. During setup, choose Use WSL 2 instead of Hyper-V when prompted.
  3. After installation, open Docker Desktop and verify it shows "Engine running" in the bottom-left corner.

macOS

  1. Download Docker Desktop for Mac from docker.com.
  2. Drag the Docker icon to your Applications folder and launch it.
  3. Grant any requested permissions. Docker Desktop starts a small VM in the background to run containers.
  4. Verify the whale icon in the menu bar shows "Docker Desktop is running."

Linux

On Debian/Ubuntu:

bash
# Install Docker using the official repository
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
 
# Add your user to the docker group to run without sudo
sudo usermod -aG docker $USER

Log out and back in for the group change to take effect.

Pulling the MySQL Image

Open a terminal (Windows Terminal, iTerm, or your Linux shell) and download the official MySQL 8 image:

bash
# Download the MySQL 8 Docker image
docker pull mysql:8

This downloads approximately 500 MB. Once finished, verify the image is available:

bash
# List local Docker images
docker images | grep mysql

You should see mysql with tag 8 in the output.

Running a MySQL Container

Create and start a container with port mapping, a root password, and the jdbc_demo database pre-created:

bash
# Run a MySQL container with environment variables
docker run -d \
  --name jdbc-mysql \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=rootpass \
  -e MYSQL_DATABASE=jdbc_demo \
  -e MYSQL_USER=jdbc_user \
  -e MYSQL_PASSWORD=jdbcpass \
  mysql:8

Let us break down each flag:

FlagMeaning
-dRun in detached mode (background)
--name jdbc-mysqlAssign a friendly name for easy reference
-p 3306:3306Map host port 3306 to container port 3306
-e MYSQL_ROOT_PASSWORD=rootpassSet the root password
-e MYSQL_DATABASE=jdbc_demoCreate the database on first startup
-e MYSQL_USER=jdbc_userCreate a non-root user
-e MYSQL_PASSWORD=jdbcpassSet the non-root user password
mysql:8The image and tag to use

Wait about 10-20 seconds for MySQL to initialize on its first run. Check the container status:

bash
# Show running containers
docker ps

You should see jdbc-mysql with status Up.

Verifying the Connection

Connect to MySQL inside the container:

bash
# Open an interactive MySQL shell inside the container
docker exec -it jdbc-mysql mysql -u root -p

Enter rootpass when prompted. Run a quick check:

sql
-- List databases to confirm jdbc_demo exists
SHOW DATABASES;
 
-- Verify the jdbc_user exists
SELECT user, host FROM mysql.user WHERE user = 'jdbc_user';
 
-- Exit
EXIT;

You can also connect from your host machine using any MySQL client. From your host terminal:

bash
# Connect from the host (requires mysql client installed locally)
mysql -h 127.0.0.1 -P 3306 -u jdbc_user -p

Enter jdbcpass. If you see the mysql> prompt, the container is accessible from the outside world — which is exactly what your Java application needs.

Tip

Use 127.0.0.1, Not localhost

On some systems, localhost resolves to an IPv6 address while MySQL listens on IPv4. If mysql -h localhost fails but mysql -h 127.0.0.1 works, your JDBC URL should use 127.0.0.1 as well.

Persisting Data with a Volume

By default, container data lives only as long as the container. If you delete the container, your databases disappear. For development, this is often convenient — you can reset to a clean state instantly. But if you want data to survive container recreation, mount a Docker volume:

The -v mysql-jdbc-data:/var/lib/mysql flag tells Docker to store MySQL's data files in a persistent volume named mysql-jdbc-data. Even if you delete and recreate the container, the data remains.

Managing the Container

Here are the commands you will use most often:

Completely Resetting Your Database

One of Docker's biggest advantages is the ability to start over with a single command sequence:

Thirty seconds later, you have a pristine MySQL instance ready for the next chapter.

FAQ

Docker Desktop says "WSL2 installation is incomplete" on Windows.

Install the WSL2 Linux kernel update package from Microsoft's website, then restart Docker Desktop. Alternatively, run wsl --update from PowerShell.

The container starts but I cannot connect from my Java application.

Check three things:

  1. Is the container running? docker ps should show jdbc-mysql.
  2. Is port 3306 mapped correctly? docker port jdbc-mysql should show 3306/tcp -> 0.0.0.0:3306.
  3. Is the JDBC URL using the right host and port? For a local container, it should be jdbc:mysql://127.0.0.1:3306/jdbc_demo.

Can I run multiple MySQL versions at the same time?

Yes. Map them to different host ports:

bash
# MySQL 5.7 on port 3307
docker run -d --name mysql57 -p 3307:3306 -e MYSQL_ROOT_PASSWORD=root mysql:5.7
 
# MySQL 8 on port 3306 (default)
docker run -d --name jdbc-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:8

Adjust your JDBC URL port accordingly (jdbc:mysql://127.0.0.1:3307/...).

How do I view or edit the MySQL configuration inside the container?

Most configuration is handled through environment variables. For advanced tuning, you can mount a custom my.cnf file:

bash
docker run -d \
  --name jdbc-mysql \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=rootpass \
  -v /path/to/my.cnf:/etc/mysql/conf.d/custom.cnf \
  mysql:8

Do I need to install the MySQL client on my host machine?

Not strictly. You can always run docker exec -it jdbc-mysql mysql -u root -p to get a shell inside the container. However, installing the client locally (or using DBeaver) makes ad-hoc queries more convenient.