Глава 2.1: Анатомия docker-compose.yml и магия .env.
В предыдущем разделе мы запускали тестовый контейнер командой docker run. Это удобно для быстрых тестов, но если у вас десяток сервисов, у каждого из которых свои порты, папки данных и пароли, то запускать их вручную командами из консоли станет невозможно.
Для этого существует Docker Compose. Это инструмент, который позволяет описать всю вашу ИТ-инфраструктуру (все сервисы, сети и диски) в одном простом текстовом файле формата YAML — docker-compose.yml. Вы один раз прописываете правила игры, а затем запускаете всю экосистему одной короткой командой.
1. Магия .env файлов (Безопасность)
Главная ошибка при составлении конфигов — писать секретные пароли, ключи и домены прямо внутри кода docker-compose.yml. Если вы захотите поделиться своим конфигом с другом или выложить его на GitHub, вам придется вручную вырезать оттуда личные данные.
Правильный подход: Разделять структуру и данные. Всю структуру мы пишем в docker-compose.yml, а все переменные (пароли, пути, часовой пояс) выносим в отдельный скрытый файл .env, который лежит в той же папке.
Давайте подготовим рабочее пространство для нашей Wiki. Создадим нужную папку внутри нашего каталога стеков и перейдем в нее:
mkdir -p /stacks/bookstack
cd /stacks/bookstack
Теперь создадим скрытый файл конфигурации .env с помощью редактора nano:
nano .env
Вставьте в него следующие строки (придумайте свои надежные пароли вместо дефолтных!):
# Настройки приложения BookStack
APP_URL=http://wiki.myserver.ru
TZ=Europe/Moscow
# Секреты для базы данных
DB_ROOT_PASSWORD=super_secret_root_pass_123
DB_USER=bookstack_user
DB_PASSWORD=secure_db_password_456
Сохраните файл (нажмите Ctrl+O, затем Enter) и выйдете (Ctrl+X).
2. Создание и анатомия docker-compose.yml
Теперь создадим рядом основной манифест:
nano docker-compose.yml
Вставьте туда следующий готовый код. Обратите внимание, как вместо реальных паролей мы используем конструкции вида ${DB_PASSWORD} — Docker автоматически подставит туда значения из созданного нами файла .env.
services:
# Сервис №1: База данных MariaDB
bookstack-db:
image: lscr.io/linuxserver/mariadb:latest
container_name: bookstack_db
environment:
- PUID=1000
- PGID=1000
- TZ=${TZ}
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
- MYSQL_DATABASE=bookstackapp
- MYSQL_USER=${DB_USER}
- MYSQL_PASSWORD=${DB_PASSWORD}
volumes:
- ./db_data:/config
restart: unless-stopped
# Сервис №2: Само веб-приложение BookStack
bookstack:
image: lscr.io/linuxserver/bookstack:latest
container_name: bookstack_app
environment:
- PUID=1000
- PGID=1000
- TZ=${TZ}
- APP_URL=${APP_URL}
- DB_HOST=bookstack-db
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_DATABASE=bookstackapp
volumes:
- ./app_data:/config
ports:
- "8080:80"
restart: unless-stopped
depends_on:
- bookstack-db
3. Разбор конфигурации «по косточкам»
Давайте поймем, что делает ключевой блок каждой директивы, чтобы вы могли легко читать любые чужие конфиги из интернета:
- services: С этого слова начинается описание всех контейнеров, которые входят в наш стек. В нашем случае это два независимых сервиса:
bookstack-db(база) иbookstack(веб-интерфейс). - image: Из какого чертежа (образа) разворачивать контейнер. Мы используем великолепные, чистые и регулярно обновляемые образы от сообщества LinuxServer.io.
- container_name: Какое имя дать запущенному контейнеру в системе, чтобы его было удобно администрировать. Если его не указать, Docker сам сгенерирует имя вида
bookstack-bookstack-1. - environment: Переменные окружения. Это "ручки настройки" внутри контейнера. Сюда мы передаем часовой пояс, секреты бд, а также параметры
PUIDиPGID(о них мы детально поговорим в следующей главе). - volumes: Связка папок (монтирование). Директива вида
./app_data:/configозначает: "Возьми локальную папкуapp_dataпрямо здесь, на сервере, и свяжи её с внутренней папкой/configв контейнере". Всё, что контейнер запишет туда, сохранится на нашем жестком диске. - ports: Проброс портов. Запись
"8080:80"расшифровывается какВНЕШНИЙ_ПОРТ:ВНУТРЕННИЙ_ПОРТ. Внутри контейнера приложение работает на стандартном 80 порту, а мы "вытаскиваем" его наружу на порт 8080 нашего сервера Debian, чтобы оно не конфликтовало с другими будущими сайтами. - restart: unless-stopped: Политика перезапуска. Говорит Docker'у: "Если сервер перезагрузится, или контейнер упадет из-за ошибки — немедленно подними его автоматически. Не трогай его только в том случае, если я сам вручную его остановил".
- depends_on: Очередь запуска. Логично, что сайт BookStack не сможет работать без базы данных. Эта строка указывает Docker'у сначала полностью запустить контейнер с СУБД, и только после этого стартовать само приложение.
⚠️ Важнейшее правило синтаксиса YAML:
Файлы конфигурации Compose невероятно чувствительны к пробелам и отступам. В них нельзя использовать клавишу Tab — только обычные пробелы. Каждый уровень вложенности сдвигается строго на 2 или 4 пробела относительно родительского. Ошибка в один лишний пробел приведет к тому, что Docker откажется запускать конфиг.
Запуск стека
Убедитесь, что вы находитесь в папке /stacks/bookstack и выполните магическую команду запуска:
docker compose up -d
Флаг -d (detached) означает запустить контейнеры в фоновом режиме, чтобы они не блокировали консоль. Docker сам скачает образы из сети, настроит связи и запустит сервисы.
После завершения процесса вы можете открыть браузер на основном компьютере и ввести IP-адрес вашего сервера с указанием нашего порта: http://ip_сервера:8080. Вы увидите стартовое окно вашей новой корпоративной Wiki!
📌 Что дальше? Контейнеры запущены и работают, но прямо сейчас в папке проекта автоматически создались новые директории app_data и db_data. Кто их владелец? Что с правами? П ереходим к Главе 2.2, чтобы разобраться с правами пользователей и не сломать систему.
Нет комментариев для отображения
Нет комментариев для отображения