Повысьте свои навыки с помощью этого руководства по Docker Compose

Если вы задаетесь вопросом, как создать воспроизводимые контейнеры Docker с помощью Docker Compose, вы попали по адресу. В этом пошаговом руководстве по Docker Compose вы узнаете, как создавать простые контейнеры, сопоставлять порты с помощью Docker Compose и переходить к сложным многоконтейнерным сценариям.

Вы готовы? Давайте начнем!

Предварительные требования

Если вы хотите выполнить пошаговое руководство, убедитесь, что у вас есть следующее:

  1. A fresh install of Ubuntu Server LTS with SSH Enabled. This guide will use Ubuntu Server LTS 20.04.1 as the Docker host machine.
  2. A computer with VS Code installed (optional). This guide will use Visual Studio Code 1.52.1 to SSH to the Docker host and run commands.
  3. Официальное расширение SSH для VS Code установлено и подключено к хосту Docker. (необязательно)

Что такое Docker Compose?

В Docker команды могут быть очень длинными. Возьмем в качестве примера следующую команду. Этот пример создает контейнер для программного приложения под названием bookstack.

docker create \
   --name=bookstack \
   -e PUID # UID пользователя, который возьмет на себя владение приложением/файлами \
   -e PGID # GID пользователя, который возьмет на себя владение приложением/файлами \
   -e DB_USER # Пользователь базы данных \
   -e DB_PASS # Пароль базы данных \
   -e DB_HOST # Хост базы данных \
   -e DB_DATABASE # База данных, которая будет использоваться \
   -e APP_URL # URL, по которому будет доступно ваше приложение (необходимо для корректной работы обратного прокси) \
   -v /host/path/to/config:/config # Местоположение загруженных данных \
   -p 80:80/tcp # Порт веб-интерфейса \
   --restart unless-stopped \
   linuxserver/bookstack:version-v0.31.4

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

Docker Compose — это способ создания воспроизводимых контейнеров Docker с использованием файла конфигурации вместо чрезмерно длинных команд Docker. Используя структурированный файл конфигурации, ошибки легче обнаружить, а взаимодействие контейнеров легче определить.

Docker Compose быстро становится неоценимым при работе с зависимостями контейнера или многоконтейнерными средами.

Docker Compose – фантастический способ войти в мир Инфраструктуры как кода без сложности распределенных систем, таких как Kubernetes.

Docker Compose использует структуру файла конфигурации, называемую YAML. YAML подобен JSON или HTML в том смысле, что YAML – структурированный, машинночитаемый язык. YAML специально ориентирован на то, чтобы быть максимально читаемым для человека, сохраняя при этом эту структурированную мощь.

У YAML есть недостаток, где табуляция и другие пробелы имеют значение и должны быть правильно отформатированы. VS Code делает много этой тяжелой работы за вас, и поэтому вы увидите, что многие примеры делаются в VS Code.

Установка Docker Compose

Давайте теперь начнем делать что-то конкретное. Предполагая, что вы подключены к своему хосту Docker, пришло время установить Docker Compose.

Docker Compose – это отдельный пакет от времени выполнения Docker. Но установка Docker Compose также установит время выполнения Docker, так что вы убьете двух зайцев одним выстрелом!

Чтобы установить Docker Compose и время выполнения Docker, выполните следующие две команды.

# обновите список программного обеспечения (известный как репозиторий), а затем установите docker compose
# с любыми необходимыми зависимостями. флаг -y используется для пропуска подтверждения
sudo apt update -y
sudo apt install docker-compose -y
The installation command for Docker Compose

После установки вам следует создать структуру папок для хранения контейнеров.

Создание структуры папок для Docker Compose

Прежде чем вы сможете создать контейнер с помощью Docker Compose, вам следует создать папку для хранения контейнеров. Вы должны не только создать структуру папок для хранения контейнеров, но и обнаружите, что различные команды Docker чувствительны к расположению различных файлов конфигурации; Docker Compose не исключение.

Самый важный компонент Docker Compose – это его файл конфигурации, называемый docker-compose.yaml. Этот файл конфигурации, как уже объяснено выше, определяет, как должно строиться контейнер с помощью Docker runtime.

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

В одной папке может быть только один файл конфигурации Docker Compose.

Для демонстрации создания контейнера Docker с помощью Docker Compose сначала создайте структуру папок для хранения будущего контейнера и его файлов конфигурации с использованием небольшого файлового сервера под названием Caddy.

Caddy – это файловый сервер, аналогичный apache httpd или nginx, но написанный на языке Go. Caddy специально разработан для удобства использования (и будет автоматически генерировать или обслуживать файл index.html) без необходимости конфигурации. Эта комбинация делает Caddy хорошим выбором для начинающих.

Предполагая, что вы вошли в систему на своем хосте Docker, создайте структуру каталогов следующим образом:

  1. В своем домашнем каталоге создайте папку с именем containers. Эта папка будет хорошим заполнителем для этого и других контейнеров.
  2. Внутри папки containers создайте подпапку с именем caddy. Эта папка будет содержать файл конфигурации Docker Compose и сам контейнер Caddy.
  3. Наконец, внутри папки контейнера caddy создайте пустой текстовый файл с именем docker-compose.yaml, который станет файлом конфигурации Docker Compose.

С созданием структуры каталогов и файла конфигурации Docker Compose вы теперь можете начать заполнять этот файл конфигурации Docker Compose.

Создание файла конфигурации Docker Compose

В самой базовой форме файл docker-compose.yaml для контейнера caddy выглядит следующим образом. В вашем любимом текстовом редакторе Linux или с помощью VS Code скопируйте и вставьте код ниже в ранее созданный файл конфигурации Docker Compose.

version: "3.7"
services:
  caddy:
    container_name: "caddy"
    image: "caddy:latest"
    ports:
      - "80:80"

Давайте рассмотрим каждый из показанных параметров:

  • version указывает версию файла docker-compose. Каждая новая версия Docker Compose включает изменения, нарушающие совместимость. Поэтому версия важна, чтобы Docker Compose мог определить, какие функции использовать. Версия 3.7 – последняя версия, которую поддерживает Ubuntu 20.04.1 LTS.

Полную спецификацию Docker Compose 3.x можно найти здесь. Связанная документация упоминает каждую доступную опцию, которую можно использовать в Docker Compose

  • services содержат спецификации для фактических контейнеров. Вы можете определить несколько контейнеров в этом разделе.
  • caddy – это имя первого контейнера (чисто для справки).
  • container_name определяет фактическое имя, заданное контейнеру Docker, и должно быть уникальным.
  • image – это имя образа. В данном случае, caddy с Docker Hub определен. Имя или номер после тега, разделенные двоеточием, обозначает версию.

Отображение портов

Особенно стоит упомянуть последнюю опцию:

ports:
  - "80:80"

В Docker Compose директива ports позволяет устанавливать одно или несколько сопоставлений между хостом и контейнером. Например, вы сопоставили порт 80 на хосте с портом 80 в контейнере. Тем не менее, необязательно совпадение номера порта. В приведенном выше примере порт 8800 на хосте сопоставлен с портом 80 в контейнере.

ports:
  - "8800:80"

Также можно определить несколько портов, как показано ниже.

ports:
  - "80:80"
  - "443:443"

При этом будут сопоставлены и порт 80, и порт 443 с хостом (общая конфигурация для веб-серверов для обслуживания как HTTP, так и HTTPS).

Создатель образа Docker определяет доступные порты в момент создания. Убедитесь в том, что порты, которые вы хотите сопоставить, указаны в документации образа на Docker Hub или на веб-сайте сопровождающего. Нет смысла сопоставлять порт, если он не используется!

Принимая это во внимание, давайте рассмотрим процесс запуска контейнера.

Запуск контейнера

К настоящему моменту у вас должен быть файл docker-compose.yaml в папке ~\containers\caddy. Теперь пришло время создать и запустить контейнер Caddy.

На вашем терминале выполните следующую команду, которая запустит контейнеры Docker, определенные в файле docker-compose.yaml.

# Эта команда должна быть выполнена в той же папке, что и файл. Флаг -d запускает
# команду в *detached* режиме, что запустит контейнер в фоновом режиме
sudo docker-compose up -d

Вы можете заметить, что вам не нужно указывать расположение файла docker-compose.yaml при выполнении sudo docker-compose up -d. Docker Compose ожидает, что вы выполните все команды внутри папки, содержащей файл docker-compose.yaml, так как многие команды относятся к этой папке.

Теперь проверьте, что контейнер работает, перейдя по адресу http://<ваш ip>. В этом руководстве используется http://homelab-docker в качестве примера.

Вы можете видеть этот процесс в VS Code при подключении по SSH к хосту Docker, как показано на анимации ниже:

Demonstrating a container created with Docker Compose

Успех! Теперь вы успешно использовали Docker Compose для запуска контейнера из файла конфигурации. Сделав этот первый важный шаг, давайте рассмотрим, как управлять состоянием вашего контейнера.

Команды для управления отсоединенными контейнерами

В предыдущем разделе вы запустили контейнер Caddy с использованием флага -d. Этот флаг запускает контейнер в отсоединенном режиме. Когда контейнер находится в отсоединенном состоянии, он продолжает работать в фоновом режиме. Однако возникает проблема: как управлять этим контейнером, если у вас больше нет прямого контроля?

Чтобы решить эту проблему, Docker Compose предоставляет серию команд, которые управляют контейнерами, запущенными с использованием файла docker-compose.yaml:

  • docker-compose restart используется для перезапуска контейнера, который в настоящее время работает. Это отличается от фактического повторного запуска docker-compose up -d. Команда restart просто перезапустит существующий контейнер, повторно выполнит команду docker-compose up -d и создаст контейнер заново (если файл конфигурации был изменен).
  • docker-compose stop остановит работающий контейнер, не уничтожая его. Аналогично, docker-compose start снова запустит контейнер.
  • docker-compose down остановит работающие контейнеры и также уничтожит их. Здесь вступают в игру привязанные монтирования томов (читайте подробнее ниже).
  • docker-compose pull загрузит текущую версию образа Docker (или образы) из репозитория. Если используется метка latest, вы можете выполнить docker-compose down && sudo docker-compose up -d, чтобы заменить контейнер на последнюю версию. Использование docker-compose pull — это удобный способ быстро обновить контейнеры с минимальным временем простоя.
  • docker-compose logs покажет журналы работающего (или остановленного) контейнера. Вы также можете обратиться к отдельным контейнерам (если в файле композиции определено несколько контейнеров) с помощью docker-compose logs <имя контейнера>.

A full list of docker-compose commands can be seen by running docker-compose with no additional arguments or referenced here in the documentation.

Теперь, когда у вас есть работающий контейнер, давайте посмотрим, как использовать содержимое, сохраненное локально на вашем компьютере.

Создание привязанных монтирований в Docker Compose

Привязки к точкам монтирования – это способ, с помощью которого Docker отображает важные пользовательские данные на локальное хранилище на вашем сервере. Для начала создайте некоторое содержимое для контейнера:

  1. На хосте Docker, внутри папки ~/containers/caddy создайте новую папку с именем files.

2. Создайте новый файл с именем index.html внутри папки ~/containers/caddy, который будет выглядеть следующим образом. Это будет основной страницей, которую будет обслуживать веб-сервер Caddy.

<body><h2>hello world!</h2></body>

3. Измените файл конфигурации Docker Compose, чтобы он выглядел следующим образом. Приведенный ниже пример добавляет раздел volumes и указывает привязку к точке монтирования к только что созданной папке files, чтобы сделать ее доступной для контейнера.

version: "3.7" services: caddy: container_name: "caddy" image: "caddy:latest" ports: - "80:80" volumes: #./ указывает на папку относительно файла docker-compose - "./files:/usr/share/caddy"

4. Снова запустите docker-compose up -d. Теперь Docker Compose распознает, что файл был изменен, и воссоздаст ваш контейнер.

5. Перейдите на страницу контейнера в браузере, и теперь вы должны увидеть, что он обслуживает страницу “Hello World!”.

Вы можете увидеть следующее в анимации ниже:

Creating a bind mount using Docker Compose

Теперь ваше содержимое хранится локально на вашем компьютере! Однако что, если ваш контент находится на внешнем источнике, например, на сетевом ресурсе?

Использование Docker Compose с томами Docker

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

В демонстрационных целях в данном руководстве будет создан сервер сетевого файлового ресурса (NFS) на хосте Docker. Сервер, предоставляющий локальный контент в виде монтирования NFS, не имеет практического смысла за пределами демонстрации. Если вы собираетесь монтировать NFS-том, обычно это будет делаться из внешнего источника, такого как NAS или удаленный сервер.

Настройка общего ресурса NFS

Если у вас еще нет настроенного общего ресурса NFS, создайте его на хосте Docker для этого руководства. Для этого выполните следующие шаги:

  1. Установите пакет NFS-сервера, выполнив команду apt install nfs-kernel-server -y.

2. Добавьте контейнер в качестве экспорта NFS (аналогично общему ресурсу CIFS в Windows), выполнив следующие команды.

# Добавьте строку в конфигурационный файл /etc/exports для создания NFS-общего ресурса # /home/homelab/containers. Этот ресурс доступен только для localhost (чтобы # предотвратить доступ других компьютеров) echo '/home/homelab/containers localhost(rw,sync,no_root_squash,no_subtree_check)' | sudo tee -a /etc/exports # Перезапустите сервер NFS с новой конфигурацией sudo systemctl restart nfs-kernel-server

3. Теперь убедитесь, что хост открывает NFS-шару, запустив команду showmount -e localhost. Эта команда покажет любые в данный момент открытые NFS-шары и кто имеет к ним доступ.

На скриншоте ниже вы можете видеть, что /home/homelab/containers открыт, но только для локального компьютера (который является тем же сервером, на котором запущен хост Docker).

Creating a NFS share in Ubuntu 20.04

Если вы видите папку /home/<username>/containers в выводе, значит NFS-шара настроена.

Определение именованного тома Docker

После создания NFS-шары вам нужно сказать Docker, как получить к этой шаре доступ. С помощью Docker Compose вы можете сделать это, определив именованный том в файле конфигурации Docker Compose.

A named volume is a way for Docker to abstract network-based file shares. Network file sharing comes in all sorts of shapes and sizes these days: CIFS (windows) shares, NFS (Linux) shares, AWS S3 Buckets, and more. By creating a Named Volume, Docker does the hard part of figuring out how to talk to the network share and lets the container just treat the share as if it is local storage.

Для создания именованного тома:

  1. Откройте файл конфигурации Docker Compose (docker-compose.yaml). Если вы следуете за мной, файл должен находиться в папке ~/containers/caddy.

2. Внутри файла конфигурации Docker Compose добавьте секцию volumes после секции services. Ваш файл конфигурации должен выглядеть так, как показано ниже. Секция volumes создает именованный том с именем MyWebsite. Внутри этого именованного тома указываются необходимые параметры (такие как IP, настройки NFS и путь). Параметр volumes внутри секции services также модифицируется, чтобы указывать на именованный том, а не на локальную папку.

version: "3.7"
 services:
   caddy:
     container_name: "caddy"
     image: "caddy:latest"
     ports:
       - "80:80"
     volumes:
       - "MyWebsite:/usr/share/caddy"
 volumes:
   MyWebsite:
     driver_opts:
       type: "nfs"
       o: "addr=localhost,nolock,soft,rw"
       device: ":/home/homelab/containers/caddy/files"

3. После того как вы определили именованный том, указывающий на NFS-шару в файле конфигурации Docker Compose, выполните docker-compose up -d, чтобы создать и запустить контейнер. Если все пройдет успешно, контейнер и веб-сайт должны снова запуститься.

Setting NFS client settings within Docker Compose in VS Code

4. Перейдите на страницу контейнера снова. Содержимое index.html должно появиться так же, как если бы файл монтировался локально. Однако этот файл монтируется через NFS-сервер, настроенный в сети.

Demonstrating access to the index.html file through an NFS share in Docker

Теперь, когда вы можете монтировать внешние Docker-тома в Docker Compose, вы можете привносить в свои контейнеры все виды сетевого хранилища. Однако Docker Compose может делать не только определение отдельных контейнеров или томов. Давайте погрузимся в более сложные, многосоставные сценарии.

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

Определение нескольких контейнеров в Docker Compose

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

Используя Docker Compose, вы можете объединить контейнеры, определенные в одном файле. Определяя несколько контейнеров в одном файле, контейнеры могут взаимодействовать между зависимыми службами и упростить организацию сложных контейнерных компоновок.

Чтобы продемонстрировать такой сценарий, давайте настроим популярное приложение для вики-страниц, называемое BookStack.

BookStack – это популярное программное обеспечение вики, известное своей простотой использования и иерархической структурой (в отличие от плоской структуры, такой как mediawiki).

BookStack, как и многие веб-приложения, требует отдельной базы данных для правильного функционирования, а также информации, необходимой для взаимодействия с базой данных. Установка такой конфигурации – это то, где блестит Docker Compose.

Создайте файл конфигурации Docker Compose

У BookStack нет внутреннего обслуживаемого образа Docker, однако linuxserver.io поддерживает репутационный образ Docker Hub от имени BookStack. В то время как в документации на сайте Docker Hub есть рекомендуемый файл конфигурации Docker Compose, этот учебник создаст новый файл конфигурации, объясняя при этом концепции.

На хосте Docker:

  1. Во-первых, создайте папку для BookStack. Если вы следовали предыдущим разделам учебника, у вас должна быть папка ~/containers. Создайте в ней папку с именем bookstack.

2. Затем создайте пустой файл конфигурации Docker Compose с именем docker-compose.yaml внутри папки bookstack.

Creating the folder structure for Bookstack in VS Code

3. Теперь откройте файл конфигурации Docker Compose и определите два контейнера: контейнер bookstack и контейнер bookstack_db (mariadb).

version: "3.7"
 services:
   bookstack:
     container_name: "bookstack"
     image: "ghcr.io/linuxserver/bookstack"
     ports:
       - "8080:80"
     volumes:
       - "./files:/usr/share/caddy"
     depends_on:
       - "bookstack_db"
   bookstack_db:
     container_name: "bookstack_db"
     image: "mariadb"
     volumes:
       - "./db:/var/lib/mysql"

До сих пор этот файл docker-compose.yaml в основном использует уже представленные концепции: у вас есть два сервиса (bookstack и bookstack_db), оба с образами и привязанными точками монтирования. Контейнер bookstack имеет отображение порта с хост-порта 8080 на внутренний порт 80.

Учитывая крайне низкую нагрузку контейнеров Docker, распространено практика определения отдельного контейнера базы данных для каждого веб-приложения. Это отличается от традиционных настроек базы данных, где одна установка базы данных может обслуживать сотни веб-приложений.

Одна новая опция, которую вы можете увидеть в приведенном выше файле, это команда depends_on. Эта команда сообщает Docker порядок запуска контейнеров. Определение команды depends_on говорит Docker, что контейнер bookstack_db должен запуститься первым.

Настройка обмена данными между контейнерами с помощью переменных окружения

Этот файл конфигурации, созданный в последнем разделе, еще не завершен. Хотя вы определили два сервиса (контейнера), они не взаимодействуют друг с другом! Контейнер bookstack не знает, как взаимодействовать с контейнером bookstack_db. Давайте решим эту проблему с помощью переменных окружения.

Переменные окружения – это наиболее распространенный способ предоставления переменных контейнерам Docker. Это переменные, задаваемые во время выполнения (или определенные в файле конфигурации docker-compose.yaml), чтобы предоставить информацию о том, что контейнер должен делать.

Переменные среды определяются тем, кто создает образ Docker. Они будут различаться в зависимости от используемого вами образа Docker, и вам необходимо обратиться к документации от создателя относительно того, какие переменные среды использовать.

Существуют два способа определения переменных среды: непосредственно в файле docker-compose.yaml или как отдельный файл.

A separate file is, typically, the recommended method, especially if variables contain sensitive data such as passwords. A docker-compose.yaml file is designed to be shared or even uploaded to a public-facing GitHub repo. Having a separate file for sensitive data reduces the chance of an accidental security breach.

На хосте Docker теперь создайте две переменные среды: одну для контейнера bookstack и одну для контейнера bookstack_db.

  1. Создайте новый файл в папке ~/containers/bookstack с названием bookstack.env со следующим содержимым:
APP_URL is the IP address or hostname of your server. This article is using homelab-docker
 APP_URL=http://homelab-docker:8080
 DB_HOST is the container name you gave your container
 DB_HOST=bookstack_db
 DB_USER is defined in the bookstack_DB environment file
 DB_USER=bookstack_user
 DB_PASS is also defined in the bookstack_DB environment file
 DB_PASS=MySecurePassword
 DB_DATABASE is the name of the database within mariadb
 DB_DATABASE=bookstack

2. Создайте новый файл в папке ~/containers/bookstack с названием bookstack_db.env и добавьте следующее содержимое:

The root password for our database, keep it secret, keep it safe
 MYSQL_ROOT_PASSWORD=MySecureRootPassword
 The database bookstack will be using
 MYSQL_DATABASE=bookstack
 the user bookstack will be using
 MYSQL_USER=bookstack_user
 the password bookstack will be using
 MYSQL_PASSWORD=MySecurePassword

3. Как лучшая практика, убедитесь, что оба файлы env нечитаемы для других пользователей.

chmod 600 bookstack.env bookstack_db.env

Вы должны изменить права на чтение, потому что оба файла bookstack.env и bookstack_db.env содержат в себе чувствительные данные.

4. Обновите файл Docker Compose ~/containers/bookstack/docker-compose.yaml, чтобы ссылаться на эти два файлы среды, показанные ниже.

version: "3.7"
 services:
   bookstack:
     container_name: "bookstack"
     image: "ghcr.io/linuxserver/bookstack"
     ports:
       - "8080:80"
     volumes:
       - "./files:/usr/share/caddy"
     depends_on:
       - "bookstack_db"
     env_file:
       - "./bookstack.env"
   bookstack_db:
     container_name: "bookstack_db"
     image: "mariadb"
     volumes:
       - "./db:/var/lib/mysql"
     env_file:
       - "./bookstack_db.env"

5. Теперь запустите контейнеры bookstack и bookstack_db с помощью Docker Compose.

sudo docker-compose up -d

Вы можете видеть каждый из упомянутых выше шагов в этом разделе выполненным в VS Code ниже.

Setting up environment variables and the Docker Compose file with VS Code

Мониторинг журналов Docker Compose

Движок Docker работает с Docker Compose для выполнения различных задач в фоновом режиме. Было бы полезно иметь возможность отслеживать происходящее, особенно при работе с несколькими контейнерами одновременно.

Чтобы отслеживать контейнер bookstack, например, используйте команду logs. В этом руководстве, когда вы увидите, что в журналах отображается [services.d] done, вы сможете перейти по URL книжной стопки.

sudo docker-compose logs bookstack
Using the docker-compose logs command
The bookstack welcome screen. Default login is [email protected]/password

На этом этапе у вас должен быть полностью функциональный вики, работающий в собственном контейнере, с собственной базой данных, полностью в рамках Docker!

Пока у вас есть папки bookstack и bookstack_db, вы можете воссоздать свою среду bookstack с нуля.

Docker Compose и сетевое взаимодействие

До этого момента вы не узнали слишком много о коммуникации и сетевом взаимодействии контейнеров. Давайте это исправим.

Когда вы создаете несколько контейнеров в одном файле docker-compose.yaml, как вы делали в предыдущих разделах, они все назначаются одной и той же сети (обычно называемой имя-родительской-папки_default).

Вы можете увидеть созданную для контейнеров сеть, когда запускаете docker-compose up -d, как показано ниже.

The default network created with docker-compose comes up

Когда все контейнеры назначаются в одну сеть, Docker создает внутренние DNS-записи для них. Вот почему в предыдущем примере вы обращались к своей базе данных как к bookstack_db в переменных среды. Это имя bookstack_db на самом деле является DNS-записью, которая указывает на IP-адрес контейнера базы данных.

Вы также не обязаны полагаться на Docker Compose для автоматического создания сетей. Вы можете вручную определить внутренние или внешние сети. Вручную определять сети полезно, когда вам нужно, чтобы контейнер общался с другим контейнером в отдельном файле docker-compose.yaml. Вы можете открыть порты, или создать сеть, к которой они оба могут присоединиться!

Обратите внимание, что когда вы начинаете явно определять сети, вам также нужно явно определить сеть по умолчанию. Docker Compose перестанет автоматически создавать эту сеть, как только вы начнете определять сети

Теперь измените docker-compose.yaml для bookstack, чтобы включить внешне созданную сеть.

  1. Создайте внешнюю сеть с помощью docker network create my_external_network.

2. Определите внешнюю сеть в файле docker-compose.yaml:

version: "3.7"
 services:
   bookstack:
     container_name: "bookstack"
     image: "ghcr.io/linuxserver/bookstack"
     ports:
       - "8080:80"
     volumes:
       - "./files:/usr/share/caddy"
     depends_on:
       - "bookstack_db"
     env_file:
       - "./bookstack.env"
     networks:
       - "my_external_network"
       - "bookstack_default"
   bookstack_db:
     container_name: "bookstack_db"
     image: "mariadb"
     volumes:
       - "./db:/var/lib/mysql"
     env_file:
       - "./bookstack_db.env"
     networks:
       - "bookstack_default"
 networks:
   bookstack_default:
   my_external_network:
     external: true

3. Запустите docker-compose up -d, чтобы пересоздать контейнеры. Ваши два контейнера теперь присоединены к двум сетям, как показано ниже.

A highlight of the networks defined within a docker-compose file

Контейнер bookstack теперь также присоединен к внешне определенной сети. Это позволяет вам создать еще один контейнер, который преобразует HTTP-трафик bookstack в HTTPS, прежде чем он покинет Docker (называется обратным прокси).

Установка определенного пользователя для запуска контейнера.

По умолчанию все контейнеры Docker работают от имени изолированного root-пользователя. Это эквивалентно запуску виртуальной машины с входом в систему от имени администратора по умолчанию. В целом это не проблема, но есть проблемы безопасности, если песочница подвергается вмешательству.

Другая проблема с запуском от имени root – это права на файлы. Вы можете заметить, что если вы попытаетесь удалить папку db внутри папки bookstack, вы на самом деле не можете это сделать, так как содержимое принадлежит root.

Хотя большинство образов не против запуска от нерутового пользователя, образы linuxserver.io в частности предлагают переменную среды для установки пользователя, который работает внутри контейнера. Вы можете сделать это, добавив UID=1000 и GID=1000 в файл конфигурации bookstack.env.

1000:1000 – это идентификатор пользователя и группы по умолчанию для первого пользователя в Ubuntu (которым вы можете и не быть). Вы можете узнать больше о идентификаторах пользователей и групп по ссылке Связано: A Windows Guy in a Linux World: Users and File Permissions)

Также вы можете принудительно установить UID и GID, используя параметр user в файле docker-compose, но это не рекомендуется, так как большинство контейнеров плохо ведут себя, когда им принудительно устанавливают другого пользователя

Настройка политики перезапуска

Если вы хотите, чтобы контейнеры, созданные с использованием Docker Compose, перезапускались в случае сбоя, используйте политику restart, добавив параметр restart: <option> в настройки контейнера в файле docker-compose.yaml.

restart: "no"
restart: always
restart: on-failure
restart: unless-stopped

Добавление этого параметра приведет к автоматическому перезапуску контейнеров в случае сбоя, что поможет поддерживать доступность в случае неожиданных сбоев в электропитании.

Ручная настройка DNS-записей для контейнеров

Как и в Windows и Linux, у Docker также есть “файл hosts”. Используя параметр extra_hosts в файле конфигурации, вы можете принудительно привязать хост к определенному IP. Это может быть полезно, когда есть ограничения DNS, такие как разделенный DNS или временный тестовый сервер, с которым вы хотите взаимодействовать.

extra_hosts:
  - "somehost:x.x.x.x"
  - "otherhost:x.x.x.x"

Запуск команд

После запуска контейнера вы можете выполнять команды внутри контейнера с использованием команды docker-compose run. Например, возможно, вам захочется запустить терминал Bash внутри вашего контейнера bookstack. Для этого выполните следующую команду.

docker-compose run web bash

Заключение

На этом этапе у вас должно быть достаточно информации, чтобы следовать большинству уроков по использованию docker-compose в сети. Знание этого может существенно расширить ваши возможности в области Docker и создания веб-приложений в виде кода инфраструктуры.

Source:
https://adamtheautomator.com/docker-compose-tutorial/