Настройка cервера с помощью docker для простых проектов. Часть вторая: docker-compose

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Мы продолжаем цикл обучающих статей для начинающих системных администраторов: если вы являетесь опытным админом, можете смело пропустить этот материал. В этой статье мы разберем docker-compose.

Напомню, что цель серии - не показать, как развернуть идеальное окружение, а лишь указать на нюансы в работе и защитить начинающих специалистов от базовых ошибок при настройке.

Ссылки на наши предыдущие статьи:
Настройка LEMP сервера с помощью docker для простых проектов. Часть первая: База

Настройка LEMP сервера для простых проектов. Инструкция для самых маленьких. Часть первая

Итак, в этой статьей рассмотрим следующие пункты:

  1. docker-compose.

    1. Чем удобен docker-compose?

    2. Установка.

    3. Подготовка.

  2. Приступаем к написанию 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

Все установлено и работает.

Подготовка:

Какие сервисы понадобятся?

  1. frontend: nginx.

  2. backend: php8.1-fpm.

  3. База данных: 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
  1. etc - директория с конфигурационными файлами сервисов;

  2. 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/
      Dockerfile

    • nginx/
      Dockerfile

    • php-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
  1. default - название нашей сети. Можете использовать любое название.

  2. driver - драйвер нашей сети. 

  3. 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.

  1. container_name: - название контейнера;

  2. hostname: - hostname в контейнере;

  3. build: - загружаем файл Dockerfile, в котором будут хранится все команды для сборки образа;

  4. extra_hosts: - пункт, в котором мы указываем, какая запись будет в hosts на нашем сервере;

  5. ports: - порты, которые мы хотим прокинуть в контейнер;

  6. volumes: - директории, которые мы хотим прокинуть в контейнер.

    Для чего необходимо пробрасывать директории в контейнер? Каждый раз, когда мы будем пересобирать контейнер, у нас будут удаляться все внутренние директории. Для того, чтобы это не происходило, мы пробрасываем директорию в контейнер. После чего все файлы будут храниться на хост-машине, и после того, как будет пересобран контейнер, файлы будут в целости и сохранности.

    Например: У нас имеется mysql в контейнере. Если мы не пробросим директорию с БД, то все наши БД буду удалены после того, как мы пересоберем контейнер. Поэтому для всех сервисов лучше всего пробрасывать все нужные директории. Это важно!

  7. networks: - ip адрес который мы присвоим нашему контейнеру;

  8. links: - приоритет загрузки контейнеров;

  9. 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. Обязательно необходимо прокинуть:

  1. Файлы площадки. Для работы со статикой.

  2. Конфигурацию nginx. Для быстрого управление в случае необходимости.

  3. Конфигурационные файлы площадки. Для работы площадки.

  4. Директорию с сертификатами ssl. Для быстрого подключения работы по https.

  5. Директорию с 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"

Директории, которые нужно прокинуть:

  1. Директория площадки.

  2. php.ini php-fpm для быстрого изменения конфигурации (в случае необходимости).

  3. Конфигурационный файл площадки.

  4. 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"

Директории, которые нужно прокинуть:

  1. Директория для хранения БД.

  2. Конфигурационный файл mysql.

  3. 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, присоединяйтесь.

Источник: https://habr.com/ru/company/nixys/blog/662698/


Интересные статьи

Интересные статьи

Из предыдущих частей вы уже знаете, на что способна консоль PlayStation 3. Ожидали ли вы, что хакеры будут довольствоваться ограниченными возможностями OtherOS? Думаю, что Sony тоже не ожидала. Компан...
В предыдущей статье 10 Docker anti-patterns мы рассказали о популярных ошибках при создании образов контейнеров. Однако создание образов для вашего приложения - это тольк...
Недавняя статья про опарафиненный детектор нейтронов побудила меня поднять старую тему и написать еще парочку статей на тему радиации. А именно -- про детекторы ионизирую...
О том, что это за зверь такой — Ghidra («Гидра») — и с чем его едят она ест программки, многие уже, наверняка, знают не понаслышке, хотя в открытый доступ сей инструмент попал совсем недавно — в ...
Всем привет! Разработка гексапода продвинулась на еще один шаг. На этот раз реализованы и протестированы траектории движения конечности — очередная часть математики передвижения. В этой статье ...