content/guides/databases.md
Using a local containerized database offers flexibility and ease of setup, letting you mirror production environments closely without the overhead of traditional database installations. Docker simplifies this process, enabling you to deploy, manage, and scale databases in isolated containers with just a few commands.
In this guide, you'll learn how to:
This guide uses the MySQL image for examples, but the concepts can be applied to other database images.
To follow along with this guide, you must have Docker installed. To install Docker, see Get Docker.
Most popular database systems, including MySQL, PostgreSQL, and MongoDB, have a Docker Official Image available on Docker Hub. These images are a curated set images that follow best practices, ensuring that you have access to the latest features and security updates. To get started, visit Docker Hub and search for the database you're interested in. Each image's page provides detailed instructions on how to run the container, customize your setup, and configure the database according to your needs. For more information about the MySQL image used in this guide, see the Docker Hub MySQL image page.
To run a database container, you can use either the Docker Desktop GUI or CLI.
{{< tabs group="ui" >}} {{< tab name="CLI" >}}
To run a container using the CLI, run the following command in a terminal:
$ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb -d mysql:latest
In this command:
--name my-mysql assigns the name my-mysql to your container for easier
reference.-e MYSQL_ROOT_PASSWORD=my-secret-pw sets the root password for MySQL to
my-secret-pw. Replace my-secret-pw with a secure password of your choice.-e MYSQL_DATABASE=mydb optionally creates a database named mydb. You can
change mydb to your desired database name.-d runs the container in detached mode, meaning it runs in the background.mysql:latest specifies that you want to use the latest version of the MySQL
image.To verify that your container is running, run docker ps in a terminal
{{< /tab >}} {{< tab name="GUI" >}}
To run a container using the GUI:
In the Docker Desktop Dashboard, select the global search at the top of the window.
Specify mysql in the search box, and select the Images tab if not already
selected.
Hover over the mysql image and select Run.
The Run a new container modal appears.
Expand Optional settings.
In the optional settings, specify the following:
my-mysqlMYSQL_ROOT_PASSWORD:my-secret-pwMYSQL_DATABASE:mydbSelect Run.
Open the Container view in the Docker Desktop Dashboard to verify that your container is running.
{{< /tab >}} {{< /tabs >}}
When you have a database running inside a Docker container, you may need to
access its shell to manage the database, execute commands, or perform
administrative tasks. Docker provides a straightforward way to do this using the
docker exec command. Additionally, if you prefer a graphical interface, you
can use Docker Desktop's GUI.
If you don't yet have a database container running, see Run a local containerized database.
{{< tabs group="ui" >}} {{< tab name="CLI" >}}
To access the terminal of a MySQL container using the CLI, you can use the
following docker exec command.
$ docker exec -it my-mysql bash
In this command:
docker exec tells Docker you want to execute a command in a running
container.-it ensures that the terminal you're accessing is interactive, so you can
type commands into it.my-mysql is the name of your MySQL container. If you named your container
differently when you ran it, use that name instead.bash is the command you want to run inside the container. It opens up a bash
shell that lets you interact with the container's file system and installed
applications.After executing this command, you will be given access to the bash shell inside
your MySQL container, from which you can manage your MySQL server directly. You
can run exit to return to your terminal.
{{< /tab >}} {{< tab name="GUI" >}}
In this terminal you can access to the shell inside your MySQL container, from which you can manage your MySQL server directly.
{{< /tab >}} {{< /tabs >}}
Once you've accessed the container's terminal, you can run any tools available
in that container. The following example shows using mysql in the container to
list the databases.
# mysql -u root -p
Enter password: my-secret-pw
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
Connecting to a containerized database from your host machine involves mapping a port inside the container to a port on your host machine. This process ensures that the database inside the container is accessible via the host machine's network. For MySQL, the default port is 3306. By exposing this port, you can use various database management tools or applications on your host machine to interact with your MySQL database.
Before you begin, you must remove any containers you previously ran for this guide. To stop and remove a container, either:
docker rm --force my-mysql to remove the container
named my-mysql.Next, you can use either the Docker Desktop GUI or CLI to run the container with the port mapped.
{{< tabs group="ui" >}} {{< tab name="CLI" >}}
Run the following command in a terminal.
$ docker run -p 3307:3306 --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb -d mysql:latest
In this command, -p 3307:3306 maps port 3307 on the host to port 3306 in the container.
To verify the port is mapped, run the following command.
$ docker ps
You should see output like the following.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6eb776cfd73c mysql:latest "docker-entrypoint.s…" 17 minutes ago Up 17 minutes 33060/tcp, 0.0.0.0:3307->3306/tcp my-mysql
{{< /tab >}} {{< tab name="GUI" >}}
To run a container using the GUI:
In the Docker Desktop Dashboard, select the global search at the top of the window.
Specify mysql in the search box, and select the Images tab if not already
selected.
Hover over the mysql image and select Run.
The Run a new container modal appears.
Expand Optional settings.
In the optional settings, specify the following:
my-mysql3307MYSQL_ROOT_PASSWORD:my-secret-pwMYSQL_DATABASE:mydbSelect Run.
In the Containers view, verify that the port is mapped under the Port(s) column. You should see 3307:3306 for the my-mysql container.
{{< /tab >}} {{< /tabs >}}
At this point, any application running on your host can access the MySQL service in the container at localhost:3307.
Connecting to a containerized database from another container is a common scenario in microservices architecture and during development processes. Docker's networking capabilities make it easy to establish this connection without having to expose the database to the host network. This is achieved by placing both the database container and the container that needs to access it on the same Docker network.
Before you begin, you must remove any containers you previously ran for this guide. To stop and remove a container, either:
docker rm --force my-mysql to remove the container
named my-mysql.To create a network and run containers on it:
Run the following command to create a Docker network named my-network.
$ docker network create my-network
Run your database container and specify the network using the --network
option. This runs the container on the my-network network.
$ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb --network my-network -d mysql:latest
Run your other containers and specify the network using the --network
option. For this example, you'll run a phpMyAdmin container that can connect
to your database.
Run a phpMyAdmin container. Use the --network option to specify the
network, the -p option to let you access the container from your host
machine, and the -e option to specify a required environment variable
for this image.
$ docker run --name my-phpmyadmin -d --network my-network -p 8080:80 -e PMA_HOST=my-mysql phpmyadmin
Verify that the containers can communicate. For this example, you'll access phpMyAdmin and verify that it connects to the database.
root as the username and my-secret-pw as the password.
You should connect to the MySQL server and see your database listed.At this point, any application running on your my-network container network
can access the MySQL service in the container at my-mysql:3306.
Persisting database data in a Docker volume is necessary for ensuring that your data survives container restarts and removals. A Docker volume lets you store database files outside the container's writable layer, making it possible to upgrade the container, switch bases, and share data without losing it. Here’s how you can attach a volume to your database container using either the Docker CLI or the Docker Desktop GUI.
Before you begin, you must remove any containers you previously ran for this guide. To stop and remove a container, either:
docker rm --force my-mysql to remove the container
named my-mysql.Next, you can use either the Docker Desktop GUI or CLI to run the container with a volume.
{{< tabs group="ui" >}} {{< tab name="CLI" >}}
To run your database container with a volume attached, include the -v option
with your docker run command, specifying a volume name and the path where the
database stores its data inside the container. If the volume doesn't exist,
Docker automatically creates it for you.
To run a database container with a volume attached, and then verify that the data persists:
Run the container and attach the volume.
$ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb -v my-db-volume:/var/lib/mysql -d mysql:latest
This command mounts the volume named my-db-volume to the /var/lib/mysql directory in the container.
Create some data in the database. Use the docker exec command to run
mysql inside the container and create a table.
$ docker exec my-mysql mysql -u root -pmy-secret-pw -e "CREATE TABLE IF NOT EXISTS mydb.mytable (column_name VARCHAR(255)); INSERT INTO mydb.mytable (column_name) VALUES ('value');"
This command uses the mysql tool in the container to create a table named
mytable with a column named column_name, and finally inserts a value of
value.
Stop and remove the container. Without a volume, the table you created would be lost when removing the container.
$ docker rm --force my-mysql
Start a new container with the volume attached. This time, you don't need to specify any environment variables as the configuration is saved in the volume.
$ docker run --name my-mysql -v my-db-volume:/var/lib/mysql -d mysql:latest
Verify that the table you created still exists. Use the docker exec command
again to run mysql inside the container.
$ docker exec my-mysql mysql -u root -pmy-secret-pw -e "SELECT * FROM mydb.mytable;"
This command uses the mysql tool in the container to select all the
records from the mytable table.
You should see output like the following.
column_name
value
{{< /tab >}} {{< tab name="GUI" >}}
To run a database container with a volume attached, and then verify that the data persists:
Run a container with a volume attached.
In the Docker Desktop Dashboard, select the global search at the top of the window.
Specify mysql in the search box, and select the Images tab if not
already selected.
Hover over the mysql image and select Run. The Run a new container modal appears.
Expand Optional settings.
In the optional settings, specify the following:
my-mysqlMYSQL_ROOT_PASSWORD:my-secret-pwMYSQL_DATABASE:mydbmy-db-volume:/var/lib/mysqlHere, the name of the volume is my-db-volume and it is mounted in the
container at /var/lib/mysql.
Select Run.
Create some data in the database.
In the Containers view, next to your container select the Show container actions icon, and then select Open in terminal.
Run the following command in the container's terminal to add a table.
# mysql -u root -pmy-secret-pw -e "CREATE TABLE IF NOT EXISTS mydb.mytable (column_name VARCHAR(255)); INSERT INTO mydb.mytable (column_name) VALUES ('value');"
This command uses the mysql tool in the container to create a table
named mytable with a column named column_name, and finally inserts a
value of value`.
In the Containers view, select the Delete icon next to your container, and then select Delete forever. Without a volume, the table you created would be lost when deleting the container.
Run a container with a volume attached.
In the Docker Desktop Dashboard, select the global search at the top of the window.
Specify mysql in the search box, and select the Images tab if not
already selected.
Hover over the mysql image and select Run. The Run a new container modal appears.
Expand Optional settings.
In the optional settings, specify the following:
my-mysqlMYSQL_ROOT_PASSWORD:my-secret-pwMYSQL_DATABASE:mydbmy-db-volume:/var/lib/mysqlSelect Run.
Verify that the table you created still exists.
In the Containers view, next to your container select the Show container actions icon, and then select Open in terminal.
Run the following command in the container's terminal to verify that table you created still exists.
# mysql -u root -pmy-secret-pw -e "SELECT * FROM mydb.mytable;"
This command uses the mysql tool in the container to select all the
records from the mytable table.
You should see output like the following.
column_name
value
{{< /tab >}} {{< /tabs >}}
At this point, any MySQL container that mounts the my-db-volume will be able
to access and save persisted data.
Customizing your database image lets you include additional configuration, scripts, or tools alongside the base database server. This is particularly useful for creating a Docker image that matches your specific development or production environment needs. The following example outlines how to build and run a custom MySQL image that includes a table initialization script.
Before you begin, you must remove any containers you previously ran for this guide. To stop and remove a container, either:
docker rm --force my-mysql to remove the container
named my-mysql.To build and run your custom image:
Create a Dockerfile.
Create a file named Dockerfile in your project directory. For this
example, you can create the Dockerfile in an empty directory of your
choice. This file will define how to build your custom MySQL image.
Add the following content to the Dockerfile.
# syntax=docker/dockerfile:1
# Use the base image mysql:latest
FROM mysql:latest
# Set environment variables
ENV MYSQL_DATABASE mydb
# Copy custom scripts or configuration files from your host to the container
COPY ./scripts/ /docker-entrypoint-initdb.d/
In this Dockerfile, you've set the environment variable for the MySQL
database name. You can also use the COPY instruction to add custom
configuration files or scripts into the container. In this
example, files from your host's ./scripts/ directory are copied into the
container's /docker-entrypoint-initdb.d/ directory. In this directory,
.sh, .sql, and .sql.gz scripts are executed when the container is
started for the first time. For more details about Dockerfiles, see the
Dockerfile reference.
Create a script file to initialize a table in the database. In the
directory where your Dockerfile is located, create a subdirectory named
scripts, and then create a file named create_table.sql with the
following content.
CREATE TABLE IF NOT EXISTS mydb.myothertable (
column_name VARCHAR(255)
);
INSERT INTO mydb.myothertable (column_name) VALUES ('other_value');
You should now have the following directory structure.
├── your-project-directory/
│ ├── scripts/
│ │ └── create_table.sql
│ └── Dockerfile
Build your image.
In a terminal, change directory to the directory where your Dockerfile
is located.
Run the following command to build the image.
$ docker build -t my-custom-mysql .
In this command, -t my-custom-mysql tags (names) your new image as
my-custom-mysql. The period (.) at the end of the command specifies the
current directory as the context for the build, where Docker looks for the
Dockerfile and any other files needed for the build.
Run your image as you did in Run a local containerized
database. This time, specify your
image's name instead of mysql:latest. Also, you no longer need to specify
the MYSQL_DATABASE environment variable as it's now defined by your
Dockerfile.
$ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d my-custom-mysql
Verify that your container is running with the following command.
$ docker ps
You should see output like the following.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f74dcfdb0e59 my-custom-mysql "docker-entrypoint.s…" 2 hours ago Up 51 minutes 3306/tcp, 33060/tcp my-mysql
Verify that your initialization script was ran. Run the following command in
a terminal to show the contents of the myothertable table.
$ docker exec my-mysql mysql -u root -pmy-secret-pw -e "SELECT * FROM mydb.myothertable;"
You should see output like the following.
column_name
other_value
Any container ran using your my-custom-mysql image will have the table
initialized when first started.
Docker Compose is a tool for defining and running multi-container Docker applications. With a single command, you can configure all your application's services (like databases, web apps, etc.) and manage them. In this example, you'll create a Compose file and use it to run a MySQL database container and a phpMyAdmin container.
To run your containers with Docker Compose:
Create a Docker Compose file.
Create a file named compose.yaml in your project directory. This file
will define the services, networks, and volumes.
Add the following content to the compose.yaml file.
services:
db:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: my-secret-pw
MYSQL_DATABASE: mydb
ports:
- 3307:3306
volumes:
- my-db-volume:/var/lib/mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
environment:
PMA_HOST: db
PMA_PORT: 3306
MYSQL_ROOT_PASSWORD: my-secret-pw
ports:
- 8080:80
depends_on:
- db
volumes:
my-db-volume:
For the database service:
db is the name of the service.image: mysql:latest specifies that the service uses the latest MySQL
image from Docker Hub.environment lists the environment variables used by MySQL to
initialize the database, such as the root password and the database
name.ports maps port 3307 on the host to port 3306 in the container,
allowing you to connect to the database from your host machine.volumes mounts my-db-volume to /var/lib/mysql inside the container
to persist database data.In addition to the database service, there is a phpMyAdmin service. By
default Compose sets up a single network for your app. Each container for
a service joins the default network and is both reachable by other
containers on that network, and discoverable by the service's name.
Therefore, in the PMA_HOST environment variable, you can specify the
service name, db, in order to connect to the database service. For more details about Compose, see the Compose file reference.
Run Docker Compose.
Open a terminal and change directory to the directory where your
compose.yaml file is located.
Run Docker Compose using the following command.
$ docker compose up
You can now access phpMyAdmin at
http://localhost:8080 and connect to your
database using root as the username and my-secret-pw as the password.
To stop the containers, press ctrl+c in the terminal.
Now, with Docker Compose you can start your database and app, mount volumes, configure networking, and more, all with a single command.
This guide introduced you to the essentials of using containerized databases, specifically focusing on MySQL, to enhance flexibility, ease of setup, and consistency across your development environments. The use-cases covered in this guide not only streamline your development workflows but also prepare you for more advanced database management and deployment scenarios, ensuring your data-driven applications remain robust and scalable.
Related information: