***************************
Step 2: Configure Volumes
***************************
.. contents:: Table of Contents
**Objective**: Create volumes that move the data from the container
to the host machine. That data is a shared space that both can access,
but it resides on the host and not in the container.
.. |https://hub.docker.com/_/mariadb/| raw:: html
https://hub.docker.com/_/mariadb/
Modify ``docker-compose.yml`` Configuring File
==================================================
Now, let's look at how we can further separate components using Docker. We'll
start with our
:ref:`WordPress project from lab 2 `
and then modify it.
To start, cd (change directory) to the project directory and create a new
``docker-compose.yml`` file.
.. code-block:: bash
cd ~ # Change to your home directory
cd wordpress-docker # Change to the project directory
nano docker-compose.yml # Edit the yml file
We'll start with last week's project and modify it to include volumes.
.. Note:: YAML syntax is particular about indentations. Verify the number of
spaces before the property if you are getting an error.
#. First, let's change from ``mysql:5.7`` to ``mariadb``.
MariaDB is a fork of MySQL that is released under the GNU GPL. MySQL
is owned by Oracle. The SQL structure of the databases is the same.
So, we can simply change the name of the image to use MariaDB instead
of MySQL. Pretty cool!
a. Change ``image: mysql:5.7`` to ``image: mariadb``
#. Docker will then pull the image from hub.docker.com with tag ``mariadb``,
which is this container |https://hub.docker.com/_/mariadb/|.
#. Next, let's modify the **volume** for our database.
Volumes allow us to keep the data outside of the docker container. The
container uses them and has access to the volume data, but
**the data stay on the host machine**. There are some benefits.
a. First, you have easy access to the data. You can back it up easily.
#. Then, the containers become disposable. The containers can stop and even
be deleted without erasing the data.
- Starting the project will create new containers and use the same data.
By default, Docker stores the volume data within the var folder unless
you specify a path.
- The line ``- db_data:/var/lib/mysql`` says the MySQL folder
``/var/lib/mysql`` in the container is stored in the folder
``db-data`` someplace on the host machine. We want to store this
data in our project folder, so let's modify the path.
- **Change** ``db_data:/var/lib/mysql`` to ``./db_data:/var/lib/mysql``
The ``./`` in the path tells Docker to use the current directory store
``db_data``, which is our project folder. The project folder always
contains the `docker-compose.yml` file.
#. Then, we want to configure **named volumes**.
A named volume allows for volume-specific configurations. We won't be using
them, but we'll still define them.
#. Next, let's create volumes for our **Wordpress data**.
The Wordpress container stores the HTML data in ``/var/www/html``.
We will store this data in a directory called ``wordpress`` on the
host machine so we can separate it from the container. It also
allows us to edit it the Wordpress configuration files easily.
a. In the ``wordpress`` section, create a property called ``volumes:``
directly below ``images``.
#. Create a volume that links ``wordpress`` to ``/var/www/html``
#. Add this line: ``- ./wordpress:/var/www/html``
#. Add the named value to the volumes section ``wordpress: {}``
The **wordpress** section should look like this:
.. code-block:: bash
:emphasize-lines: 5,6
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- ./wordpress:/var/www/html
#. Exit and save the file.
Your file should look like this:
.. code-block:: bash
:caption: docker-compose.yml
:linenos:
:emphasize-lines: 5,7,19-20,31,32
version: '3.3'
services:
db:
image: mariadb:latest
volumes:
- ./db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- ./wordpress:/var/www/html
ports:
- "20851:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
wordpress: {}
.. note::
On some systems, you need to use a special command for the database to
connect. Add the following ``command`` below the ``image:mariabb``
directive.
``command: --default-authentication-plugin=mysql_native_password``
.. code-block:: docker
:emphasize-lines: 4
services:
db:
image: mariadb:latest
command: --default-authentication-plugin=mysql_native_password
volumes:
- ./db_data:/var/lib/mysql
#. Let's use ``docker-compose config`` to check our config for syntax errors.
Refer to :ref:`the previous lab `.
.. code-block:: bash
:caption: Expected Output
:emphasize-lines: 1
root@vps298933:~/wordpress-docker# docker-compose config
services:
db:
environment:
MYSQL_DATABASE: wordpress
MYSQL_PASSWORD: wordpress
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_USER: wordpress
image: mariadb
restart: always
volumes:
- /root/wordpress-docker/db_data:/var/lib/mysql:rw
wordpress:
depends_on:
- db
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_USER: wordpress
image: wordpress:latest
ports:
- published: 20851
target: 80
restart: always
volumes:
- /root/wordpress-docker/wordpress:/var/www/html:rw
version: '3.3'
volumes:
db_data: {}
wordpress: {}
Start the Project
==================
#. Now, start the project. Verify that you do not have any errors.
.. code-block:: bash
docker-compose up -d
.. code-block:: bash
:caption: Output
:emphasize-lines: 1
root@vps298933:~/wordpress-docker# docker-compose up -d
Creating network "wordpressdocker_default" with the default driver
Creating volume "wordpressdocker_db-data" with default driver
Creating volume "wordpressdocker_apache" with default driver
Creating volume "wordpressdocker_wordpress" with default driver
Pulling db (mariadb:latest)...
latest: Pulling from library/mariadb
898c46f3b1a1: Pull complete
63366dfa0a50: Pull complete
041d4cd74a92: Pull complete
6e1bee0f8701: Pull complete
0fa9bfc0c84b: Pull complete
8e9b088fe106: Pull complete
af96bccda5c4: Pull complete
0655ee57b408: Pull complete
58e50a9049b1: Pull complete
57cd7839e491: Pull complete
067ff7ef6a22: Pull complete
895af18c21d0: Pull complete
1ab4788d5ff4: Pull complete
a068a53bcb17: Pull complete
Digest: sha256:06dd6d6234977e9231567cc00b9a994f467417e0419efd61f356a0018064d3a0
Status: Downloaded newer image for mariadb:latest
Creating wordpressdocker_db_1 ...
Creating wordpressdocker_db_1 ... done
Creating wordpressdocker_wordpress_1 ...
Creating wordpress-docker_wordpress_1 ... error
ERROR: for wordpress-docker_wordpress_1 Cannot start service wordpress: driver failed programming external connectivity on endpoint wordpress-docker_wordpress_1 (c2ba3b97faa86bdbdac01342dcb848bea84ea1439be9b1bd378a400bafdbe0c9): Bind for 0.0.0.0:80 failed: port is already allocated
ERROR: for wordpress Cannot start service wordpress: driver failed programming external connectivity on endpoint wordpress-docker_wordpress_1 (c2ba3b97faa86bdbdac01342dcb848bea84ea1439be9b1bd378a400bafdbe0c9): Bind for 0.0.0.0:80 failed: port is already allocated
ERROR: Encountered errors while bringing up the project.
#. You can fix the errors and try again. First, stop the project.
Then, make the changes and then try again!
.. code-block:: bash
docker-compose down #Stops the project and removes the containers.
nano docker-compose.yml # Edit the file
docker-compose up -d #Creates and starts the Docker project in daemon mode.
That's better!
.. code-block:: bash
root@vps298933:~/wordpress-docker# docker-compose up -d
Creating network "wordpressdocker_default" with the default driver
Creating volume "wordpressdocker_db_data" with default driver
Creating volume "wordpressdocker_wordpress" with default driver
Creating wordpressdocker_db_1 ...
Creating wordpressdocker_db_1 ... done
Creating wordpressdocker_wordpress_1 ...
Creating wordpressdocker_wordpress_1 ... done
root@vps298933:~/wordpress-docker#
#. Look in the directory. You should see the directories that contain the
volume data.
.. code-block:: bash
ls -lh #Lists the files and folders in the 'current' directory
ls -lh wordpress #Lists the files and folders in the 'wordpress' directory
.. code-block:: bash
:caption: Output
:emphasize-lines: 1,7
root@vps298933:~/wordpress-docker# ls -lh
total 12K
drwxr-xr-x 5 999 root 4.0K Mar 30 10:10 db_data
-rw-r--r-- 1 root root 660 Mar 30 10:10 docker-compose.yml
drwxr-xr-x 5 www-data www-data 4.0K Mar 30 10:10 wordpress
root@vps298933:~/wordpress-docker#
root@vps298933:~/wordpress-docker# ls -lh wordpress/
total 204K
-rw-r--r-- 1 www-data www-data 420 Dec 1 2017 index.php
-rw-r--r-- 1 www-data www-data 20K Jan 2 02:37 license.txt
-rw-r--r-- 1 www-data www-data 7.3K Jan 9 08:56 readme.html
-rw-r--r-- 1 www-data www-data 6.8K Jan 12 12:41 wp-activate.php
drwxr-xr-x 9 www-data www-data 4.0K Mar 13 06:18 wp-admin
-rw-r--r-- 1 www-data www-data 369 Dec 1 2017 wp-blog-header.php
-rw-r--r-- 1 www-data www-data 2.3K Jan 21 07:34 wp-comments-post.php
-rw-r--r-- 1 www-data www-data 3.1K Mar 29 23:10 wp-config.php
-rw-r--r-- 1 www-data www-data 2.8K Mar 29 23:10 wp-config-sample.php
drwxr-xr-x 4 www-data www-data 4.0K Mar 13 06:18 wp-content
-rw-r--r-- 1 www-data www-data 3.8K Jan 9 14:37 wp-cron.php
drwxr-xr-x 19 www-data www-data 12K Mar 13 06:18 wp-includes
-rw-r--r-- 1 www-data www-data 2.5K Jan 16 11:29 wp-links-opml.php
-rw-r--r-- 1 www-data www-data 3.3K Dec 1 2017 wp-load.php
-rw-r--r-- 1 www-data www-data 38K Jan 12 12:41 wp-login.php
-rw-r--r-- 1 www-data www-data 8.3K Dec 1 2017 wp-mail.php
-rw-r--r-- 1 www-data www-data 18K Jan 30 17:01 wp-settings.php
-rw-r--r-- 1 www-data www-data 31K Jan 16 22:51 wp-signup.php
-rw-r--r-- 1 www-data www-data 4.7K Dec 1 2017 wp-trackback.php
-rw-r--r-- 1 www-data www-data 3.0K Aug 17 2018 xmlrpc.php
root@vps298933:~/wordpress-docker#
#. Verify that the Wordpress containers is responding to requests
.. code-block:: bash
curl --head http://localhost:20851
.. code-block:: bash
:caption: Output
:emphasize-lines: 1,2
root@vps298933:~/wordpress-docker# curl --head http://localhost:20851
HTTP/1.1 302 Found
Date: Sat, 30 Mar 2019 03:57:16 GMT
Server: Apache/2.4.25 (Debian)
X-Powered-By: PHP/7.2.16
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
X-Redirect-By: WordPress
Location: http://localhost:20851/wp-admin/install.php
Content-Type: text/html; charset=UTF-8
root@vps298933:~/wordpress-docker#
#. Configure Wordpress using the web installer
a. Open your page in a browser: ``http://blog.example.com``
#. Proceed through the installer
#. Finally, log in using the username and password that you just created.
Reset Wordpress Data
======================
.. caution:: These instructions will reset the Wordpress database and remove
any data in the Wordpress directory.
What do you do if your username or password doesn't work? Destroy the
containers and volume data, then run the installer again. :))
#. Stop the project and remove all volume data
.. code-block:: bash
docker-compose down -v #Stops the project and removes the containers and the volume.
docker-compose up -d #Creates and starts the Docker project in daemon mode.
.. code-block:: bash
:caption: Output
:emphasize-lines: 1
root@vps298933:~/wordpress-docker# docker-compose down -v
Stopping wordpressdocker_wordpress_1 ... done
Stopping wordpressdocker_db_1 ... done
Removing wordpressdocker_wordpress_1 ... done
Removing wordpressdocker_db_1 ... done
Removing network wordpressdocker_default
Removing volume wordpressdocker_db_data
Removing volume wordpressdocker_wordpress
root@vps298933:~/wordpress-docker#
root@vps298933:~/wordpress-docker# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2175f0a86466 nextcloud "/entrypoint.sh apac…" 7 days ago Up 6 days 0.0.0.0:20850->80/tcp condescending_agnesi
root@vps298933:~/wordpress-docker#
root@vps298933:~/wordpress-docker# docker-compose up -d
Creating network "wordpressdocker_default" with the default driver
Creating volume "wordpressdocker_db_data" with default driver
Creating volume "wordpressdocker_wordpress" with default driver
Creating wordpressdocker_db_1 ...
Creating wordpressdocker_db_1 ... done
Creating wordpressdocker_wordpress_1 ...
Creating wordpressdocker_wordpress_1 ... done
root@vps298933:~/wordpress-docker#
root@vps298933:~/wordpress-docker# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
28822cf1444c wordpress:latest "docker-entrypoint.s…" 20 seconds ago Up 19 seconds 0.0.0.0:20851->80/tcp wordpressdocker_wordpress_1
cdc959eb5014 mariadb "docker-entrypoint.s…" 21 seconds ago Up 20 seconds 3306/tcp wordpressdocker_db_1
2175f0a86466 nextcloud "/entrypoint.sh apac…" 7 days ago Up 6 days 0.0.0.0:20850->80/tcp condescending_agnesi
root@vps298933:~/wordpress-docker#
#. You might have to remove the folders manually if docker-compose does not
clear the volume data. If so, use this command
.. code-block:: bash
rm -r db-data && rm -r wordpress # removes the db-data and wordpress folders