В docker compose volumes — логические тома, которые задаются для каждого контейнера. Это директива в файле, определяющая связь точки монтирования на диске с другой точкой монтирования в контейнере.
Все, что находится в volumes сохраняется на диске после удаления контейнера. Остальные данные хранятся в памяти.
Docker compose volumes
Основное предназначение Docker в быстром разворачивании окружения на любой машине из готовых образов, которые можно дорабатывать. Контейнер — временная структура, все изменения выполненные в нем существуют пока существует сам контейнер. На диске данные не сохраняются если они не вынесены в постоянную структуру — volume.
Для примера возьмем с dockerhub инструкцию для образа с wordpress, в немного измененном виде будем использовать ее.
Проект будет представлять собой сайт на wordpress с базой данных MySQL.
Сразу создадим каталоги под сайт и базу на хост машине. За счет биндинга они будут связаны с контейнерами
mkdir -p /home/site/db
На машине должны быть установлены сам Docker и docker-compose. Создаем docker-compose.yml
cd /home && mcedit docker-compose.yml
version: '2' services: wordpress: image: wordpress restart: always ports: - 8080:80 environment: WORDPRESS_DB_PASSWORD: example links: - mysql:db volumes: - /home/site:/var/www/html mysql: image: mysql:5.7 restart: always environment: MYSQL_ROOT_PASSWORD: example volumes: - /home/site/db:/var/lib/mysql
В файле 2 сервиса. Структура типовая, 80 порт из контейнера пробрасывается на порт 8080 хост машины. Используются стандартные образы с dockerhub.
Для каждого контейнера заданы блоки volumes:
— /home/site:/var/www/html для сайта
— /home/site/db:/var/lib/mysql для базы данных
Они определяют, что данные из временной структуры — контейнера будут сохраняться на хост машине.
Содержимое /var/www/html в /home/site, содержимое /var/lib/mysql в /home/site/db
Эта информация будет изменена при жизни контейнера и останется на хост машине после его удаления.
Запустим контейнеры
docker-compose -f docker-compose.yml up -d
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bf264537c63d wordpress «docker-entrypoint.s…» About a minute ago Up About a minute 0.0.0.0:8080->80/tcp home_wordpress_1
ae9cd7efb0a8 mysql:5.7 «docker-entrypoint.s…» About a minute ago Up About a minute 3306/tcp, 33060/tcp home_mysql_1
Они успешно стартовали, с хоста обращаться к сервису можно только по порту 8080, на который пробрасываются запросы.
netstat -nltp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 851/sshd
...
tcp 0 0 91.226.83.234:10010 0.0.0.0:* LISTEN 31694/docker-contai
tcp6 0 0 :::8080 :::* LISTEN 24286/docker-proxy
tcp6 0 0 :::22 :::* LISTEN 851/sshd
В браузере обратившись к IP адресу серверу и порту 8080 можно запустить установку CMS, затем попасть в административный раздел.
Внесем минимальные изменения в структуру перового поста. Поменяем заголовок 'Hello World' на 'Hello Docker' и единственное существующее по-умолчанию предложение.
Пересоздадим существующую структуру
Останавливаем контейнеры
docker-compose stop
И удаляем их
docker-compose rm
Going to remove home_wordpress_1, home_mysql_1
Are you sure? [yN] y
Removing home_wordpress_1 … done
Removing home_mysql_1 … done
Контейнеров нет, с ключем -a выводятся все контейнеры, в т.ч. незапущенные
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Файлы при этом сохранены на диске
ls /home/site/
db readme.html wp-blog-header.php wp-config-sample.php wp-includes wp-login.php wp-signup.php
index.php wp-activate.php wp-comments-post.php wp-content wp-links-opml.php wp-mail.php wp-trackback.php
license.txt wp-admin wp-config.php wp-cron.php wp-load.php wp-settings.php xmlrpc.php
Также как и содержимое /var/lib/mysql из контейнера
ls /home/site/db/
auto.cnf ca.pem client-key.pem ibdata1 ib_logfile1 performance_schema public_key.pem server-key.pem wordpress
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile0 mysql private_key.pem server-cert.pem sys
При обращении к тому же URL:8080 сейчас будет возникать ошибка — веб-сервер, являющийся частью контейнера не работает.
Запускаем контейнеры через docker-compose вновь
docker-compose -f docker-compose.yml up -d
Creating home_mysql_1
Creating home_wordpress_1
Сейчас можно убедиться в том, что сайт вновь стал открываться и контент отображается в том же виде. При старте информация из docker-compose.yml считалась.
Были задействованы те же каталоги, что использовались ранее, с имеющимися данными.
Читайте про управление контейнерами вручную. При использовании docker compose volumes задаются в файле, при ручном создании контейнера их можно указывать с ключем -v.