Мы продолжаем цикл обучающих статей для начинающих системных администраторов: если вы являетесь опытным админом, можете смело пропустить этот материал. В этой статье мы разберем docker-compose.
Напомню, что цель серии - не показать, как развернуть идеальное окружение, а лишь указать на нюансы в работе и защитить начинающих специалистов от базовых ошибок при настройке.
Ссылки на наши предыдущие статьи:
Настройка LEMP сервера с помощью docker для простых проектов. Часть первая: База
Настройка LEMP сервера для простых проектов. Инструкция для самых маленьких. Часть первая
Итак, в этой статьей рассмотрим следующие пункты:
-
docker-compose.
Чем удобен docker-compose?
Установка.
Подготовка.
-
Приступаем к написанию yml-файла.
Пункт 1. Указание версии.
Пункт 2. Объявляем сервисы.
Пункт 3. Объявляем контейнеры.
Пункт 4. Локальная сеть контейнеров.
Пункт 4.1. Основные конфигурации и ключи файла docker-compose.
Пункт 5. Пишем nginx.
Пункт 6. Пишем php-fpm.
Пункт 7. Пишем mysql.
Пункт 8. Общий итог docker-compose.yml.
docker-compose.
Чем удобен docker-compose?
docker-compose позволяет управлять всеми контейнерами из одного файла (файл - формата yml). Теперь не нужно будет писать кучу docker run и длинные команды для запуска контейнеров: достаточно будет лишь запустить одну команду docker-compose up, после чего все контейнеры будут подняты без нашего вмешательства, причем со всеми настройками, которые будут прописаны в yml-файле. Также docker-compose позволяет взаимодействовать с системой управления репозиториями программного кода. Например: gitlab.
Установка.
Для начала установим инструмент. Загружаем текущую стабильную версию:
сurl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
Делаем скачанный файл исполняемым:
chmod +x /usr/local/bin/docker-compose
Проверяем:
#:/# docker-compose --version
docker-compose version 1.29.2, build 5becea4c
Все установлено и работает.
Подготовка:
Какие сервисы понадобятся?
frontend: nginx.
backend: php8.1-fpm.
База данных: mysql.
Первым делом подготовим директории для работы. Для начала создадим директорию, где будет лежать docker-compose.yml. Мы приняли за стандарт, что в нашей компании все файлы docker-compose находится в директории /var/apps/. Создаем директорию и переходим в нее:
mkdir /var/apps
cd /var/apps
Создаем директорию проекта:
mkdir DOMAIN_NAME
cd DOMAIN_NAME/
Создаем файл docker-compose.yml:
touch docker-compose.yml
Теперь создадим директорию где будут хранится наши конфигурационные файлы площадок, конфигурации php.ini и так далее:
mkdir volumes
Давайте заранее создадим все директории и конфигурации наших сервисов:
cd volumes/
mkdir etc build
etc - директория с конфигурационными файлами сервисов;
build - директория с файлами Dockerfile в котором будут хранится все команды для сборки образа.
Далее:
mkdir etc/nginx etc/mysql etc/php-fpm8.1
mkdir etc/nginx/sites-enabled etc/nginx/ssl etc/mysql/conf.d etc/php-fpm8.1/fpm.pool.d
touch etc/nginx/nginx.conf etc/nginx/sites-enabled/DOMAIN_NAME.conf etc/mysql/conf.d/config-file.cnf etc/php-fpm8.1/php.ini etc/php-fpm8.1/fpm.pool.d/DOMAIN_NAME.conf
mkdir build/nginx build/php-fpm8.1 build/mysql
touch build/nginx/Dockerfile build/php-fpm8.1/Dockerfile build/mysql/Dockerfile
Получилась такая структура директорий:
app/
volumes/ (директория с конфигурационным файлами)
-
build/ (директория c Dockerfile для наших контейнеров)
mysql/
Dockerfilenginx/
Dockerfilephp-fpm8.1/
Dockerfile
-
etc/ (директория с конфигурационными файлами для наших сервисов)
-
mysql/
config-file.cnf
-
nginx/
-
sites-enabled/
DOMAIN_NAME.conf
nginx.conf
-
-
php-fpm8.1/
-
fpm.pool.d/
DOMAIN_NAME.conf
php.ini
-
-
docker-compose.yml
Ну или так:
В ./app/volumes/etc/mysql/config-file.cnf можно указывать все необходимые настройки для mysql. В нашем случае мы добавим:
[mysqld]
port = 3310
wait_timeout = 9000000
max_allowed_packet = 1024M
innodb_buffer_pool_size = 512M
innodb_log_buffer_size = 256M
innodb_log_file_size = 1G
innodb_write_io_threads = 16
innodb_flush_log_at_trx_commit = 0
net_read_timeout=500
net_write_timeout=500
interactive_timeout=600
connect_timeout=500
skip-log-bin
# Slow query settings:
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=2
# Error query settings:
log_error=/var/log/mysql/mysql_error.log
general_log_file=/var/log/mysql/mysql.log
general_log=1
В ./app/volumes/etc/nginx/nginx.conf можно указывать все необходимые настройки для nginx и площадки. В этом случае мы добавим:
nginx.conf:
user nginx;worker_processes 6;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 16384;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
### gzip gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
client_body_buffer_size 1m;
client_max_body_size 75m;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
sendfile on;
#tcp_nopush on;
#gzip on;
include /etc/nginx/sites-enabled/*.conf;
}
Файл площадки ./app/volumes/etc/nginx/sites-enabled/DOMAIN_NAME.conf можно взять из предыдущей статьи.
В ./app/volumes/etc/php-fpm8.1/fpm.pool.d/DOMAIN_NAME.conf добавляем настройки для php-fpm площадки:
[DOMAIN_NAME]
listen = 172.16.1.5:9010 ;ip адрес и порт на котором будет находится php-fpm площадки.
listen.mode = 0666
user = DOMAIN_NAME ;Пользователь площадки.
group = DOMAIN_NAME ;Группа пользователя площадки.
pm = dynamic
pm.max_children = 50
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 35
pm.max_requests = 500
request_terminate_timeout = 5m
request_slowlog_timeout = 2s
slowlog = /var/log/php/php-fpm.slow.log
php_admin_value[opcache.max_accelerated_files] = 20000
php_admin_value[realpath_cache_size] = 4096K
php_admin_value[realpath_cache_ttl] = 600
php_admin_flag[display_errors] = off;
php_admin_value[error_log] = /var/www/DOMAIN_NAME/log/php-fpm/fpm-php.log
php_admin_flag[log_errors] = on
php_admin_value[open_basedir] = /var/www/DOMAIN_NAME
php_admin_value[upload_tmp_dir] = /var/www/DOMAIN_NAME/upload
php_admin_value[session.save_path] = /var/www/DOMAIN_NAME/sess
В ./app/volumes/etc/php-fpm8.1/php.ini можно добавлять все настройки для php. В нашем случае мы добавим:
upload_max_filesize = 500
Mmax_file_uploads = 20
post_max_size = 500
Mmemory_limit = 4096
Mdate.timezone = Europe/Moscow
Перед дальнейшими работами очистим все образы, собранные ранее в предыдущей статье. Для этого действия подойдет команда:
docker system prune --volumes --all
Эта команда очищает все образы не запущенных контейнеров. Важное уточнение - именно не запущенных!
Смотрим запущенные контейнеры:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5f3353afe4fc nginx:stable "/docker-entrypoint.…" 4 months ago Up About a minute 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp nginx
88c83f238c5c php-fpm "/docker-entrypoint.…" 4 months ago Up About a minute 9000/tcp php-fpm
Для остановки всех контейнеров можно использовать команду:
docker stop $(docker ps -a -q)
docker stop $(docker ps -a -q)
5f3353afe4fc
88c83f238c5c
Далее очищаем образы командой docker system prune --volumes --all:
:~# docker system prune --volumes --all
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all volumes not used by at least one container
- all images without at least one container associated to them
- all build cache
Are you sure you want to continue? [y/N] y
Deleted Containers:
d25fadd1ace48b1e1d7285c79c924928fd2df54395f3cab9d1184bf25745404f
a156787f2e2d20585272f90b86fbfd82c6ff28fd6bd3e17785be1530e0dcf433
034a89f5322498cd272436515a43a9d82e0f32cdbd2da230a8211f1af7134619
c422454c2b997aec3e473998b3f51cbe5b322c00c094de9bfc20aba3af403830
5f3353afe4fc381fb2aa554700fb0a37ef378e923b5662241549722b243f84ea
88c83f238c5cfe7c71293793d54149e5e6aaf9db92dce9f0f1c9ac2e5e35be3c
77f498f59e80623dd325f6297dcc1c0b068c0fc0b373ca5c137d49052f71276f
Deleted Networks:
default
docker_default
Deleted Volumes:
171304f87cde0dbe4142c80e10e30076acfdae1c9d1ac0ed73125e8938bd13af
65e26f00da5308b81afe3d870d63243716df4935445b25648c5c69392151fefe
a016235f662b38c657f5e04283fc54d779d18c6e9d778c04e2a5fc264fec428b
a20375ceb893d7ae95c2b5ffd10c8557b49f02896a456c22a9015d17f34bd490
untagged: nginx:stable
untagged: nginx@sha256:74fb4c9d7e4fe6a8ab699d66fb5ffbf3daf1025bbb6f65a3217dde6e8f4d6e56
deleted: sha256:50fe74b50e0d0258922495297efbb9ebc3cbd5742103df1ca54dc21c07d24575
deleted: sha256:5c89b8cf56a58aa2a96ab1ed19ffd8e0630355776b1db7082fd897f8a5d285d4
deleted: sha256:e45a683cc5d56e842fc90c7ad0535abb1e909f733c2c0c29f4cf43f7247f8438
deleted: sha256:7ffdf2d40e75d1028ecbdba3cd5c548dc7a2b6c6b6598c2ff0af1f864df662e8
deleted: sha256:43828a7cbba35611955d78d1849ba6e48f176c96795ea881a7a9adcf5eb23bfa
deleted: sha256:e6ffc9b8132b8380efc5dd578d3e369890abaa492863968a5c41bdf9a8e5070e
deleted: sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f
untagged: php-fpm:latest
deleted: sha256:cac496cb3198354a8bf68188c5cec929ba149e4f8f331c32f38e45ecc0bd0e67
deleted: sha256:21c4defd66f2e9e64c7b331a7580466403d4e2008d12864f2a29790ff1473a76
deleted: sha256:90f506af9c6530b6cc3c27ad661a9f4c4bfe64a57f313bad65ab67064ca7a880
deleted: sha256:45e703bc20b6aa77dd834ae2c81d1889be7a8b025d7570aa6034569210f25612
deleted: sha256:0f9ac9b1acec55805e6a2cb53b85406b39b07c5154bea03dc575f632e860cff9
deleted: sha256:5e1a9584d37f2f438eb4f9719591b72d9113d0b93e9fd336ee61e9653faaf156
deleted: sha256:bf23cc62c0e983ea1ed5b3b38bd78a86d26ab85de691802a81a800475a1a4e75
deleted: sha256:adf7df76ecb09fcd0fb8c283c8ac1aada505ed57bfa733461cc555d8ca23a816
deleted: sha256:2e09cf02796f006bde367ee89fcfd0053abbf080ef240e715343d6ead0b44851
deleted: sha256:c41477d2876d165d26869efd878a6e3b2fee7fafa10e51c5246909b6622d3b2c
deleted: sha256:9f0f98eb9fa7bd5d06653241253eda67fd08326b2634e903bb66dea0e2fb5139
deleted: sha256:4442cb52388be2f9a3ba0e6d6682e87d4586677d94c31af9064fc9315d0370cc
deleted: sha256:7ea425a7c077487583d85343140c2200a35bf98839a7228a789c74d4419c708f
deleted: sha256:cf3704308d18d0e52028613a7795a39658b02f345c647cf6aa0d82ec6dd51908
deleted: sha256:d943dbca5ecfa509906e2644be6e918c1c5961914271a320b895923c5324014f
deleted: sha256:ffc6430b96530f2b7d3f53e1cc64ec24852d9a1a826f687d87e0f6e4eec54869
deleted: sha256:8e32d40714a5cca10289b3fc0ded459b05320abc120bee3525f17c696c4bdb2e
deleted: sha256:3c4d7d6769cd7accbd1ccf61175010a1dfabbe435dab26ec2d771daba9de6f86
deleted: sha256:49143d13ba872d32b27bb2765beb496ac60d6b85414cd371a518c9946ec90b25
deleted: sha256:4883d13c15029dd0eab0e9fb7b3e00d8b0139e0d643e4c6e4bc144228e9e7e8f
deleted: sha256:2004464b54089dd15804882cb4803381532e0589d38f47f9729f7fb6ef169c34
deleted: sha256:c71714a613ec902f20bf8dce9866f62702302994af53bdd104331c19c7339da4
deleted: sha256:b1783cc83184509d3fffd30ba119ea1f11ec8602fdc50ba2c3e062e02df56e80
deleted: sha256:3e84bd99827c4963eab48a3e54bd088f7a206adb3aacd45361027327d5ca8443
deleted: sha256:d10560a7f2e4534ce146753b0748f1e73ce1b50f458f1e12385e19222b221b69
deleted: sha256:9c84657b917192c0490faf836824a113e6c397146db7a73fc2dc47755224c026
deleted: sha256:c13bd6861c9c7576cb27df56517347b5b7b28e68ce93e69a6ff25d8f1b4b4f6e
deleted: sha256:ced7cbb4abb893d33743c81fcbe3caf9c64da09a6fd9fa2f75efdfa0fd6efd6b
deleted: sha256:32f19a4eb0921d3b110352c4bdcdc7b64bd47092e1e15fe918e94cf6039037d8
deleted: sha256:054e2126fd90e29711637456090b61fc9b883eeb95ccf94430026ab7d5d14541
deleted: sha256:e8f41b5970d0e2b904babde28c490135b83b0a0be9ff7101171c203cc23af5fb
deleted: sha256:e022aa4b2c5f34b58acd5050d77cc23c087395010ab525ae9802ddc0ea52559c
deleted: sha256:ebdafce0fbc3adbde2ec9308930be55d3df801a2f62b31bd5b0b1162a54fea7e
deleted: sha256:c3744e7ff118e96f517ff1b4f97ee8ee62695d7cf97aec267b9bd73df77581ee
deleted: sha256:3b56d7cccfcf2579595d9d21f0788129276743ea2957f05cd9e49317fefd852f
deleted: sha256:d204f4d10e96af88215de15a6b47de64668572bfe9f143bc17f0adf0285c02bd
deleted: sha256:8c5518abda1bc707b21cc845ea17ebf5dcb4d05f8b5b5164d863255ea59390d4
deleted: sha256:9321ff862abbe8e1532076e5fdc932371eff562334ac86984a836d77dfb717f5
Total reclaimed space: 1.813GB
Все контейнеры и образы были удалены с сервера.
Базовая настройка завершена.
Приступаем к написанию нашего yml-файла.
ВНИМАНИЕ! Важное уточнение: так как это файл формата yml, в нем очень строго необходимо следить за пробелами и отступами и никогда не использовать TAB. В противном случае вы можете получить синтаксическую ошибку - например, лишний пробел где-нибудь в 80-ой строке, на поиск которого у вас может уйти не один час =).
Итак, открываем docker-compose.yml.
Пункт 1. Указание версии.
Для начала указываем, какую версию docker-compose будем использовать. В нашем случае мы используем версию 2.4 - её нам будет вполне достаточно.
Для ознакомления со всеми версиями, и для чего они нужны, можете перейти на официальный мануал по этому поводу: version.
Добавляем:
version: '2.4'
Пункт 2. Объявляем сервисы.
Добавляем:
services:
Мы объявляем, что далее будут идти наши контейнеры.
Пункт 3. Объявляем наши контейнеры.
Не забываем про формат yml, поэтому делаем два пробела и добавляем:
nginx:
php-fpm8.1:
mysql:
Выглядит это так:
version: '2.4'
services:
nginx:
php-fpm8.1:
mysql:
Пункт 4: Локальная сеть контейнеров.
Давайте заранее обьявим нашу сеть, чтобы больше к ней не возвращаться. За сеть у нас отвечает ключ networks.
Добавляем такие строки:
networks:
default:
driver: bridge
ipam:
config:
- subnet: 172.16.1.0/24
default - название нашей сети. Можете использовать любое название.
driver - драйвер нашей сети.
ipam - конфигурация сети. В данном случае мы указываем нашу локальную подсеть 172.16.1.0/24
Получаем:
version: '2.4'
services:
nginx:
php-fpm8.1:
mysql:
networks:
default:
driver: bridge
ipam:
config:
- subnet: 172.16.1.0/24
Пункт 4.5. Основные конфигурации и ключи нашего файла docker-compose.
container_name: - название контейнера;
hostname: - hostname в контейнере;
build: - загружаем файл Dockerfile, в котором будут хранится все команды для сборки образа;
extra_hosts: - пункт, в котором мы указываем, какая запись будет в hosts на нашем сервере;
ports: - порты, которые мы хотим прокинуть в контейнер;
-
volumes: - директории, которые мы хотим прокинуть в контейнер.
Для чего необходимо пробрасывать директории в контейнер? Каждый раз, когда мы будем пересобирать контейнер, у нас будут удаляться все внутренние директории. Для того, чтобы это не происходило, мы пробрасываем директорию в контейнер. После чего все файлы будут храниться на хост-машине, и после того, как будет пересобран контейнер, файлы будут в целости и сохранности.
Например: У нас имеется mysql в контейнере. Если мы не пробросим директорию с БД, то все наши БД буду удалены после того, как мы пересоберем контейнер. Поэтому для всех сервисов лучше всего пробрасывать все нужные директории. Это важно!
networks: - ip адрес который мы присвоим нашему контейнеру;
links: - приоритет загрузки контейнеров;
restart: - частота перезагрузка контейнера в случае ошибки.
Пункт 5. Пишем nginx.
Переходим к строчке nginx и делаем отступ 4 пробела. Формат yml (да, не устану это повторять:)).
Указываем название контейнера container_name:
container_name: DOMAIN_NAME-nginx
Указываем hostname:
hostname: DOMAIN_NAME-nginx
Указываем местонахождение нашего Dockerfile для сборки build:
build: ./volumes/build/nginx
Указываем директории, которые необходимо прокинуть в контейнер с помощью volumes. Обязательно необходимо прокинуть:
Файлы площадки. Для работы со статикой.
Конфигурацию nginx. Для быстрого управление в случае необходимости.
Конфигурационные файлы площадки. Для работы площадки.
Директорию с сертификатами ssl. Для быстрого подключения работы по https.
Директорию с log-файлом nginx. Для удобства анализа в дальнейшем.
Указываем volumes и прокидываем директории через дефис:
volumes:
- ./var/log/nginx:/var/log/nginx #log файлы.
- ./volumes/etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro #Конфигурация nginx.
- ./volumes/etc/nginx/sites-enabled:/etc/nginx/sites-enabled:ro #Конфигурация площадок.
- ./volumes/etc/nginx/ssl:/etc/nginx/ssl:ro #сертификаты
- /var/www/DOMAIN_NAME:/var/www/DOMAIN_NAME #Домашняя директория
Ключ :ro означает read only. Он добавлен для безопасности, чтобы внутри контейнера нельзя было изменить конфигурационные файлы.
Указываем порты ports:
Открываем порты 80 и 443 на хосте и пробрасываем их в контейнер.
ports:
- "80:80"
- "443:443"
Указываем приоритет загрузки links:
links:
- php-fpm
Контейнер nginx не будет загружен быстрее чем контейнер с php-fpm. Делается для того, чтоб пользователя не видели 502 код ответа, в случае перегрузки контейнеров.
Указываем как часто можно перезагружаться контейнеру в случае ошибки:
restart:
always
Присваиваем ip адрес контейнеру с помощью networks:
networks:
default:
ipv4_address: 172.16.1.4
В итоге получается у так:
nginx:
container_name: DOMAIN_NAME-nginx
hostname: DOMAIN_NAME-nginx
build: ./volumes/build/nginx
volumes:
- ./var/log/nginx:/var/log/nginx #log файлы.
- ./volumes/etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro #Конфигурация nginx.
- ./volumes/etc/nginx/sites-enabled:/etc/nginx/sites-enabled:ro #Конфигурация площадок.
- ./volumes/etc/nginx/ssl:/etc/nginx/ssl:ro #сертификаты
- /var/www/DOMAIN_NAME:/var/www/DOMAIN_NAME #Домашняя директория
ports:
- "80:80"
- "443:443"
links:
- php-fpm
restart:
always
networks:
default:
ipv4_address: 172.16.1.4
Анализируем:
У нас имеется контейнер nginx:
С названием DOMAIN_NAME-nginx
hostname в контейнере DOMAIN_NAME-nginx
Собирающийся из нашего Dockerfile по адресу ./volumes/build/nginx
С прокинутыми директориями и файлами ./var/log/nginx, ./volumes/etc/nginx/nginx.conf, ./volumes/etc/nginx/sites-enabled/, ./volumes/etc/nginx/ssl/, /var/www/DOMAIN_NAME/
Работающий на 80 и 443 портах хост машины
Запускающийся только после контейнера php-fpm
Часто перезагружаемый в случае ошибки и с ip адресом 172.16.1.4.
Пункт 6. Пишем php-fpm.
Переходим к строке php-fpm.
Название:
container_name: DOMAIN_NAME-php-fpm
Hostname:
hostname: DOMAIN_NAME-php-fpm
Расположение Dockerfile:
build: ./volumes/php-fpm/build
Приоритет загрузки links: указывать не нужно.
Порты:
ports:
- "9000:9010"
Директории, которые нужно прокинуть:
Директория площадки.
php.ini php-fpm для быстрого изменения конфигурации (в случае необходимости).
Конфигурационный файл площадки.
log файл php.
Прокидываем:
volumes:
- ./volumes/etc/php/fpm.pool.d/DOMAIN_NAME.conf:/usr/local/etc/php-fpm.d/DOMAIN_NAME.conf:ro #Конфигурация площадки
- ./volumes/etc/php/nxs-std.ini:/usr/local/etc/php/conf.d/nxs-std.ini:ro #Конфигурация php для php-fpm
- /var/log/php:/var/log/php #log файлы
- /var/www/DOMAIN_NAME:/var/www/DOMAIN_NAME #Домашняя директория
IP адрес:
networks:
default:
ipv4_address: 172.16.1.5
Добавляем права на все изменения в докере php:
cap_add:
- SYS_NICE
- DAC_READ_SEARCH
Для чего это нужно? Например php-fpm необходимо будет сменить приоритет процесса. Если данная строка будет отсутствовать, то получим ошибку:
mbind: Operation not permitted
Или, например, площадка у нас работает от пользователя DOMAIN_NAME. Для того, чтобы площадка работала в контейнере, php-fpm необходимо добавить пользователя в систему. Если строки не будет, то будет выдаваться аналогичная ошибка.
Перезагрузка контейнера:
restart: always
Итог:
php-fpm:
container_name: DOMAIN_NAME-php-fpm
hostname: DOMAIN_NAME-php-fpm
build: ./volumes/php-fpm/build
ports:
- "9000:9010"
volumes:
- ./volumes/etc/php/fpm.pool.d/DOMAIN_NAME.conf:/usr/local/etc/php-fpm.d/DOMAIN_NAME.conf:ro #Конфигурация площадки
- ./volumes/etc/php/php.ini:/usr/local/etc/php/conf.d/nxs-std.ini:ro #Конфигурация php для php-fpm
- /var/log/php:/var/log/php #log файлы
- /var/www/DOMAIN_NAME:/var/www/DOMAIN_NAME #Домашняя директория
cap_add:
- SYS_NICE
- DAC_READ_SEARCH
restart: always
networks:
default:
ipv4_address: 172.16.1.5
У нас имеется контейнер php-fpm:
С названием DOMAIN_NAME-php-fpm;
hostname в контейнере DOMAIN_NAME-php-fpm;
Собирающийся из нашего Dockerfile по адресу ./volumes/php-fpm/build. С прокинутыми директориями и файлами ./volumes/etc/php/fpm.pool.d/DOMAIN_NAME.conf, ./volumes/etc/php/php.ini, /var/log/php, /var/www/DOMAIN_NAME/;
Работающий на 9000 порте хост машины;
Часто перезагружаемый в случае ошибки и с ip адресом 172.16.1.5.
Пункт 7. Пишем mysql.
Переходим к строке mysql.
Название:
container_name: DOMAIN_NAME-mysql
Hostname:
hostname: DOMAIN_NAME-mysql
Расположение Dockerfile:
build: ./volumes/mysql/build
Приоритет загрузки links: указывать не нужно.
Порты:
ports:
- "3310:3310"
Директории, которые нужно прокинуть:
Директория для хранения БД.
Конфигурационный файл mysql.
log файл mysql.
Прокидываем:
volumes:
- /var/lib/mysql:/var/lib/mysql #Директория БД.
- /var/log/mysql:/var/log/mysql #log файл
- ./volumes/mysql/conf.d:/etc/mysql/conf.d:ro #Конфигурация mysql.
IP адрес:
networks:
default:
ipv4_address: 172.16.1.6
Перезагрузка контейнера:
restart: always
Итог:
mysql:
container_name: DOMAIN_NAME-mysql
hostname: DOMAIN_NAME-mysql
build: ./volumes/mysql/build
ports:
- "3310:3310"
volumes:
- /var/lib/mysql:/var/lib/mysql #Директория БД.
- /var/log/mysql:/var/log/mysql #log файл
- ./volumes/mysql/conf.d:/etc/mysql/conf.d:ro #Конфигурация mysql.
networks:
default:
ipv4_address: 172.16.1.6
У нас имеется контейнер mysql:
С названием DOMAIN_NAME-mysql;
hostname в контейнере DOMAIN_NAME-mysql;
Собирающийся из нашего Dockerfile по адресу ./volumes/mysql/build;
С прокинутыми директориями и файлами /var/lib/mysql, /var/log/mysql:/var/log/mysql, ./volumes/mysql/conf.d;
Работающий на 3010 порте хост машины;
Часто перезагружаемый в случае ошибки и ip адресом 172.16.1.6.
Пункт 8. Общий итог нашего docker-compose.yml:
version: '2.4'
services:
nginx:
container_name: DOMAIN_NAME-nginx
hostname: DOMAIN_NAME-nginx
build: ./volumes/build/nginx
volumes:
- ./var/log/nginx:/var/log/nginx #log файлы.
- ./volumes/etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro #Конфигурация nginx.
- ./volumes/etc/nginx/sites-enabled:/etc/nginx/sites-enabled:ro #Конфигурация площадок.
- ./volumes/etc/nginx/ssl:/etc/nginx/ssl:ro #сертификаты
- /var/www/DOMAIN_NAME:/var/www/DOMAIN_NAME #Домашняя директория
ports:
- "80:80"
- "443:443"
links:
- php-fpm
restart:
always
networks:
default:
ipv4_address: 172.16.1.4
php-fpm:
container_name: DOMAIN_NAME-php-fpm
hostname: DOMAIN_NAME-php-fpm
build: ./volumes/php-fpm/build
ports:
- "9000:9010"
volumes:
- ./volumes/etc/php/fpm.pool.d/DOMAIN_NAME.conf:/usr/local/etc/php-fpm.d/DOMAIN_NAME.conf:ro #Конфигурация площадки
- ./volumes/etc/php/nxs-std.ini:/usr/local/etc/php/conf.d/nxs-std.ini:ro #Конфигурация php для php-fpm
- /var/log/php:/var/log/php #log файлы
- /var/www/DOMAIN_NAME:/var/www/DOMAIN_NAME #Домашняя директория
cap_add:
- SYS_NICE
- DAC_READ_SEARCH
restart: always
networks:
default:
ipv4_address: 172.16.1.5
mysql:
container_name: DOMAIN_NAME-mysql
hostname: DOMAIN_NAME-mysql
build: ./volumes/mysql/build
ports:
- "3310:3310"
volumes:
- /var/lib/mysql:/var/lib/mysql #Директория БД.
- /var/log/mysql:/var/log/mysql #log файл
- ./volumes/mysql/conf.d:/etc/mysql/conf.d:ro #Конфигурация mysql.
networks:
default:
ipv4_address: 172.16.1.6
networks:
default:
driver: bridge
ipam:
config:
- subnet: 172.16.1.0/24
Итак, мы разобрали базовые ключи и команды для написание docker-compose. Теперь вы можете самостоятельно писать yml, а самое главное понимать, что именно вы написали! Но перед запуском необходимо написать Dockerfile, и в следующей статье мы с вами разберем, что это такое, для чего Dockerfile нужен, и как его красиво писать. После чего запустим наш docker-compose, накатим WordPress и проверим его работу.
Спасибо за уделенное нам время. Надеемся, статья была для вас познавательной. Если остались вопросы - задавайте в комментариях, мы с радостью на них ответим. Всем удачного администрирования и чтоб ваш PROD никогда не падал!
P.S.: Еще больше полезной информации - в телеграм-канале DevOps FM, присоединяйтесь.
Комментарии (7)
sswwssww
25.04.2022 23:12+2При описании nginx docker-compose файла, у блока network неправильный уровень вложенности(хотя в конечно варианте все ок), подправьте.
stralex7
26.04.2022 10:17+2Не совсем разобрался зачем присваиваются статические адреса контейнерам?
thisprogame Автор
27.04.2022 07:40Привет!
Если у контейнера не статический ip. То:
Когда контейнер пересобирается (Например: необходимо открыть новые порты) ip адрес может измениться, после чего необходимо будет заново настраивать проксирование в nginx, либо указывать новый ip адрес в коде площадки. Все это время площадка будет возвращать ошибку, пока не будет указан новый ip адрес. Также, при переносе на другой сервер ip адреса будут всегда разные и из-за этого необходимо будет всегда править конфигурационные файлы и вписывать правильный ip адрес. Для того, чтоб контейнеры, сервисы могли между собой общаться.
Этого всего можно избежать, просто указав статический ip адрес. После чего у контейнера всегда будет один и тот же ip даже если перенести его на другой сервер. Это очень удобно!stralex7
27.04.2022 10:28+1Мне кажется вы можете обращаться внутри по имени контейнера. Внешнее подключение от него на зависит, так как у вас проброс портов во внешнюю сеть через NAT -ports:
В ситуации в которой вам надо поменять подсеть в случае пересечения по тем или иным причинам, то придётся только сменить определение сети
thisprogame Автор
28.04.2022 07:24Да, все верно можно так делать.
Но, по нашему опыту обучения стажеров. Лучше на первых этапах обучения работать именно с ip адресами. Для того, чтоб понять весь смысл работы docker.
nikweter
Еще бы осветить настройку проксирования с фронта на бэк. Когда на на фронте не голый nginx, а что-то вроде react-vue-etc, то возникают некоторые неочевидные тонкости.