In this tutorial, you will learn how to create persistent volumes with Docker Compose and use them with MySQL.
Containers are ephemeral by design, meaning they do not retain their state once they stop. For apps that have no state or manage their state through external services, such as Redis, this perfectly fine. However, database services like MySQL need to maintain state. Otherwise, its database would be purged every time its container is stopped.
Docker instroduced a feature named volumes to address the persistent data problem. Volumes allows us to mount a volume into a running container image and store data. Volumes persist longer than the Docker container they are mounted to, meaning when the container stops and new container takes its place the volume and its data will be available to the new container.
By default, MySQL stores its data files in the
/var/lib/mysql directory. In order to persist data with a MySQL service we must mount a persistent volume into that directory.
Volumes are added to containers using the
-v flag with the
docker run command. The syntax of the a the
-v value is:
source value is the path on the Docker host that will be mounted in the container. The
target value is where the volume will be mounted inside of the container.
The following is an example of mounting a volume in a MySQL Docker container. It mounts the relative path of
./mysql-data from the host to the path
/var/lib/mysql in the container.
docker run -p -d 3306:3306 -v ./mysql-data:/var/lib/mysql mysql:latest
Docker Compose Volumes
Mounting a volume in Docker Compose is similar to doing so with Docker. Both set a
source and a
target. The difference between Docker and Docker compose is the latter uses a two step process. A volume must be defined outside of your services in order to be mounted in a service.
The are two major ways of accomplishing this task: a short form and a long form. The short is very similiar to regular Docker, but the long form provides more control over how a volume is mounted.
The simplist, carefree way of adding volumes to a server is to use the short form.
In the example snippet below, we’ve defined a volume named
data-volume and mounted it to the
mysql service. The syntax for the shortform method of adding volumes to a container uses the following:
volume-name references a volume defined in the top-level
volumes key. The
target is the path inside of the container the volume is mounted to.
version: "3.8" services: mysql: image: mysql:5.7.31 volumes: - data-volume:/var/lib/mysql volumes: data-volume:
The long form method of adding volumes allows you to define specific parameters for it. Let’s explore these in the examples below.
In the the example snippet below, one volumes has been defined with the name
mysql-data. Notice it’s position within a
docker-compose.yaml file. We define volumes in the top-level
version: "3.8" services: mysql: ... volumes: mysql-data:
With the volumes defined under the
volumes key, we can mount them to our services with the
version: "3.8" services: wordpress: ... mysql: image: mysql:5.7.31 volumes: - type: volume source: mysql-data target: /var/lib/mysql volumes: mysql-data:
typesets the volumes mount type
sourcethe source of the mount. This could be the path on the host for a bind mount, or the name of a volume defined in the top-level
targetthe path in the container where the volume is mounted.
For more information regarding the topics covered in this tutorial, use following resources.