Развертывание форума Talkyard под Ngnix с помощью Docker

Talkyard — это программное обеспечение для форумов с открытым исходным кодом, которое объединяет основные функции StackOverflow, Discourse, Slack, HackerNews, Reddit и Disqus.
Вы можете использовать его для создания форума для своих студентов, доски вопросов и ответов для ваших команд и клиентов, доски обсуждений для мозгового штурма. Вы также можете использовать его для публичного чата поддержки. В конечном итоге вы можете использовать его в качестве системы комментариев в своем блоге Ghost, Hugo или Jekyll.
Установка Talkyard с Docker в режиме гибридной контейнеризации
Этот документ основан на руководстве по развертыванию Talkyard в производственной среде, но ориентирован на его развертывание в контейнере Nginx с основными функциями и использует упрощенный подход за счет тщательного пересмотра сетевых параметров docker-compose.yml.
В официальном руководстве упоминается использование Nginx, но оно основано на установке на стороне хоста.
Предпосылки
Это не обязательно, но вам будет намного проще следовать руководству, если у вас есть:
- Некоторые знания о Docker.
- Понимание docker-compose.
Вы будете развертывать Talkyard за обратным прокси-контейнером с субдоменом с поддержкой SSL.
Помимо вышеупомянутых актуальных знаний, вам потребуются следующие требования к инфраструктуре:
- Общедоступный сервер Ubuntu Linux. Вы можете использовать поставщика облачных услуг. Для этого развертывания будет достаточно нано-сервера с 1 ГБ ОЗУ.
- Доступ к домену и его настройкам DNS
- Docker и docker-compose установлены на вашем сервере Linux.
- Обратный прокси-сервер Nginx уже настроен
В качестве примера будем использовать talkyard.domain.ru. При необходимости измените его на соответствующее доменное имя.
Шаг 1. Измените настройки DNS
На панели управления вашего DNS-провайдера убедитесь, что записи A/AAAA вашего домена указывают на IP-адрес вашего сервера Linux.
Допустим, вы хотите разместить Talkyard в домене talkyard.example.ru, вам следует добавить следующую запись A, заменив xxx.xxx.xxx.xxx IP-адресом вашего сервера.
| Тип | Хост | Ценность | TTL |
|---|---|---|---|
| Запись | talkyard | xxx.xxx.xxx.xxx | 5 мин. |
Шаг 2. Загрузите Talkyard для производства
Перед тем, как подготовить файл создания для контейнера Nginx, вы должны загрузить Talkyard с помощью git.
Для работы сценариев резервного копирования необходимо выполнить установку /opt/talkyard/.
Используйте git, чтобы загрузить Talkyard и поместить его в каталог opt:
sudo git clone https://github.com/debiki/talkyard-prod-one.git /opt/talkyard
Теперь переключитесь в этот каталог:
cd /opt/talkyard
Вы будете использовать следующие образы докеров:
- debiki/talkyard-web
- debiki/talkyard-app
- debiki/talkyard-rdb
- debiki/talkyard-cache
- debiki/talkyard-search
Шаг 3. Подготовьте Ubuntu к установке Talkyard
Установите инструменты, включите автоматические обновления безопасности, упростите устранение неполадок и заставьте ElasticSearch работать. Все это можно сделать с помощью скрипта prepare-ubuntu.sh, доступного в папке скриптов.
sudo ./scripts/prepare-ubuntu.sh 2>&1 | sudo tee -a talkyard-maint.log
Далее следует помнить о следующих важных моментах:
- Этот контейнер должен использовать ту же сеть, что и Talkyard, чтобы они могли взаимодействовать друг с другом. Поскольку Talkyard будет использовать сеть net, как и ваш обратный прокси-контейнер, он будет использовать то же самое. Если у вас настроена другая сеть, убедитесь, что вы ее используете.
- Вы должны установить политику перезапуска «always».
- Вы должны защитить постоянные данные, используя тома (на стороне хоста ниже /opt/talkyard), которые смонтированы в соответствующих местах внутри контейнера.
Шаг 4. Определение службы Talkyard
Контейнеры нуждаются в том, чтобы переменные среды были установлены вне файла docker-compose. Это важные значения, которые считываются со стороны хоста, поэтому Talkyard является прекрасным примером настройки гибридной докеризации.
sudo nano conf/play-framework.conf
Шаг 5. Измените значения конфигурации
Введите свой адрес электронной почты. Позже подпишитесь с этим адресом электронной почты, чтобы стать владельцем сайта:
talkyard.becomeOwnerEmailAddress="email@address.com"
Введите адрес своего веб-сайта, например «your.website.org». Этот адрес используется при создании обратных ссылок на сайт и для того, чтобы знать, что входящие запросы действительно предназначены для этого сайта:
talkyard.hostname="talkyard.domain.ru"
Прочтите в docs/setup-https.md о том, как создать сертификат HTTPS. Однако вы могли бы использовать контейнер Let’s Encrypt для HTTPS. Установим это значение true:
talkyard.secure=true
Замените change_this, скажем, 80 случайными символами. Значение секретно. Сервер откажется запускаться, пока вы не измените его на что-то вроде этого:
play.http.secret.key="kjvsoh3i2VB37*&^8Oy&awI7^@tkuAYau&tkjhgkjgjhgcf3kgkKGkjgKghXW@K#GKtHlk@Kj@H@Kll2"
Если вы используете поставщика услуг электронной почты, вы также можете обновить следующие переменные. Здесь мы использовали в качестве примера SendGrid :
talkyard.smtp.host="smtp.sendgrid.net" talkyard.smtp.user="apikey" talkyard.smtp.password="api-key-pass" talkyard.smtp.fromAddress="noreply@domain.ru" talkyard.smtp.tlsPort="465" talkyard.smtp.connectWithTls=true
Здесь мы напрямую использовали TLS. Пожалуйста, не пытайтесь установить STARTTLS и TLS одновременно. Поэтому не забудьте прокомментировать/раскомментировать разделы соответственно.
Используя следующую команду, найдите значение доверенных прокси для нашей сети, называемой netнашим контейнером Nginx (при необходимости вам, возможно, придется установить jq с помощью sudo apt update && sudo apt install jq):
docker inspect -f '{{ json .IPAM.Config }}' net | jq .[].Subnet
Теперь обновите файл .env:
sudo nano .env
Установите новое значение пароля базы данных для POSTGRES_PASSWORD и обновите значением INTERNAL_NET_SUBNET, полученным с помощью приведенной выше команды.
Также обновите указанные ниже IP-адреса внутри файла .env на основе того же диапазона. Это необходимо для того, чтобы скрипты продолжали работать правильно.
Примечание для play-framework.conf и .env:
- Если вы не указали сервер play.http.secret.key в play-framework.conf не запустится.
- Пользователь базы данных PostgreSQL с именем talkyard создается автоматически контейнером rdb Docker с паролем, который вы вводите в файл .env.
Шаг 6. Измените файл Docker Compose
И последнее и самое важное изменение, которое очень необходимо в этом разделе, — это обновить официальный docker-compose.ymlфайл, чтобы наш контейнер Nginx мог легко распознавать контейнеры Talkyard.
sudo nano docker-compose.yml
В следующей обновленной версии соответствующим образом изменены параметры сети, чтобы это стало возможным. Обратите внимание на параметры сети в вашем файле.
# Dockerfiles for the Docker images are in another Git repo:
# https://github.com/debiki/talkyard, at: images/(image-name)/Dockerfile
#
# There's an image build script: https://github.com/debiki/talkyard/blob/master/Makefile,
# the `prod-images` and `tag-and-push-latest-images` targets.
version: '3.7'
networks:
# This netw name get prefixed with COMPOSE_PROJECT_NAME = 'talkyard_' by Docker, from .env.
net:
external: true
services:
web:
image: ${DOCKER_REPOSITORY}/talkyard-web:${VERSION_TAG}
# dockerfile: https://github.com/debiki/talkyard/blob/master/images/web/Dockerfile
restart: always
volumes:
- ./conf/sites-enabled-manual/:/etc/nginx/sites-enabled-manual/:ro
- ./data/sites-enabled-auto-gen/:/etc/nginx/sites-enabled-auto-gen/:ro
- ./data/certbot/:/etc/certbot/:ro
- ./data/certbot-challenges/.well-known/:/opt/nginx/html/.well-known/:ro
- ./data/uploads/:/opt/talkyard/uploads/:ro
# Mount here so standard monitoring tools looking for Nginx logs will work.
- ./logs/talkyard-nginx/:/var/log/nginx/
environment:
- VIRTUAL_HOST=talkyard.domain.ru
- LETSENCRYPT_HOST=talkyard.domain.ru
networks:
- net
depends_on:
- app
#environment:
# # Max uploaded file size, e.g. uploaded images or backups to restore:
# TY_NGX_LIMIT_REQ_BODY_SIZE: '25m'
# X_PULL_KEY: '...'
# CDN_PULL_KEY: '...'
#
# SECURITY COULD drop capabilities, see: http://rhelblog.redhat.com/2016/10/17/secure-your-containers-with-this-one-weird-trick/
# Ask at Hacker News: which caps can I drop for an Nginx container? A JVM appserver?
# Asked here about Nginx:
# https://stackoverflow.com/questions/43467670/which-capabilities-can-i-drop-in-a-docker-nginx-container
# For all containers, not just 'web'.
#cap_drop:
# - DAC_OVERRIDE
# ... many more?
app:
image: ${DOCKER_REPOSITORY}/talkyard-app:${VERSION_TAG}
# dockerfile: https://github.com/debiki/talkyard/blob/master/images/app/Dockerfile.prod
restart: always
stdin_open: true # otherwise Play Framework exits
volumes:
- ./conf/play-framework.conf:/opt/talkyard/app/conf/app-prod-override.conf:ro # see [4WDKPU2] in debiki/talkyard
- ./data/uploads/:/opt/talkyard/uploads/
# So backups can be downloaded via the admin web interface. But read-only,
# so evil bugs cannot destroy all backups.
- /opt/talkyard-backups/:/opt/talkyard-backups/:ro
# Mount here so log monitoring agents like fluentd can access the log.
- ./logs/talkyard/:/var/log/talkyard/
networks:
- net
depends_on:
- cache
- rdb
- search
environment:
- PLAY_SECRET_KEY
- TALKYARD_SECURE
- POSTGRES_PASSWORD
- TALKYARD_HOSTNAME
- BECOME_OWNER_EMAIL_ADDRESS
cache:
image: ${DOCKER_REPOSITORY}/talkyard-cache:${VERSION_TAG}
# dockerfile: https://github.com/debiki/talkyard/blob/master/images/cache/Dockerfile
restart: always
volumes:
- ./data/cache/:/data/
- ./logs/redis/:/var/log/redis/
networks:
- net
sysctls:
net.core.somaxconn: 511
rdb:
image: ${DOCKER_REPOSITORY}/talkyard-rdb:${VERSION_TAG}
# dockerfile: https://github.com/debiki/talkyard/blob/master/images/rdb/Dockerfile
restart: always
volumes:
- ./data/rdb/:/var/lib/postgresql/data/
# Mount here so standard monitoring tools configured to find Postgres logs here will work.
# (Inside the container, we don't mount in /var/lib/postgresql/data/pg_log/ because
# then Postgres would refuse to create a db in data/, because data/ wouldn't be empty.)
- ./logs/postgresql/:/var/log/postgresql/
networks:
- net
environment:
POSTGRES_PASSWORD: '$POSTGRES_PASSWORD'
# Optionally, streaming replication peer:
# (but you'll need to rename ./postgres-data/recovery.conf.disabled first — and
# that file isn't created until you start Postgres)
# PEER_HOST: 'postgres2'
# PEER_PORT: '5432'
# PEER_PASSWORD: '...'
search:
image: ${DOCKER_REPOSITORY}/talkyard-search:${VERSION_TAG}
# dockerfile: https://github.com/debiki/talkyard/blob/master/images/search/Dockerfile
restart: always
volumes:
# COULD_OPTIMIZE Maybe use a Docker volume contanier here instead? What does the docs mean when
# they say "Always use a volume bound on /usr/share/elasticsearch/data" — is mapping
# a directory from the OS okay then? (that's using (parts of) a host's device/volume.
# https://www.elastic.co/guide/en/elasticsearch/reference/5.5/docker.html#docker-cli-run-prod-mode
- ./data/search/:/usr/share/elasticsearch/data/
- ./logs/elasticsearch/:/usr/share/elasticsearch/logs/
networks:
- net
environment:
bootstrap.memory_lock: 'true'
ES_JAVA_OPTS: '-Xms512m -Xmx512m'
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
# vim: et ts=2 sw=2
Обратите внимание, что настройка все равно будет работать, закомментировав следующие строки volumes в службе web. Но чтобы скрипты работали правильно, оставим их без комментариев.
- ./conf/sites-enabled-manual/:/etc/nginx/sites-enabled-manual/:ro
- ./data/sites-enabled-auto-gen/:/etc/nginx/sites-enabled-auto-gen/:ro
- ./data/certbot/:/etc/certbot/:ro
- ./data/certbot-challenges/.well-known/:/opt/nginx/html/.well-known/:ro
Также обратите внимание, что наиболее важным дополнением, которое мы сделали здесь в рамках той же службы web, является:
environment: - VIRTUAL_HOST=talkyard.domain.ru - LETSENCRYPT_HOST=talkyard.domain.ru
Это обеспечивает доступ к нашему новому форуму Talkyard в вашем браузере на основе наших предварительно назначенных контейнеров Nginx.
В рамках службы app считываются следующие переменные play-framework.conf, /opt/talkyard/conf/ о которых уже говорилось выше:
environment:
- PLAY_SECRET_KEY
- TALKYARD_SECURE
- POSTGRES_PASSWORD
- TALKYARD_HOSTNAME
- BECOME_OWNER_EMAIL_ADDRESS
Если вам немного любопытно и вы хотите изучить больше, чтобы лучше понять, вы можете сравнить рассмотренные выше изменения с официальным файлом docker-compose.yml.
Шаг 7: конфигурация памяти
В зависимости от того, сколько оперативной памяти у вашего сервера (запустите free -mh, чтобы узнать), выберите один из этих файлов: mem/1.7g.yml, mem/2g.yml, mem/3.6g.yml, … и так далее, и скопируйте это в ./docker-compose.override.yml.
Например, для сервера с 2 ГБ ОЗУ:
sudo cp mem/2g.yml docker-compose.override.yml
Шаг 8: гибридная установка
Установите и запустите последнюю версию. В первый раз это может занять несколько минут (для загрузки образов Docker). Этот сценарий также выполняет установку в первый раз, хотя и называется «upgrade –…».
sudo ./scripts/upgrade-if-needed.sh 2>&1 | sudo tee -a talkyard-maint.log
Это не приведет к созданию новой сети Docker, поскольку мы изменили настройки сети.
Шаг 9: Планирование сценариев обслуживания
Запланируйте удаление старых файлов журналов, ежедневное резервное копирование и удаление старых резервных копий и автоматические обновления:
sudo ./scripts/schedule-logrotate.sh 2>&1 | sudo tee -a talkyard-maint.log sudo ./scripts/schedule-daily-backups.sh 2>&1 | sudo tee -a talkyard-maint.log sudo ./scripts/schedule-automatic-upgrades.sh 2>&1 | sudo tee -a talkyard-maint.log
Шаг 10. Доступ к развертыванию Talkyard
Подождите несколько минут и укажите в браузере только что настроенный поддомен Talkyard, например talkyard.domain.ru.
В браузере нажмите « Продолжить» и создайте учетную запись администратора с адресом электронной почты, который вы указали при редактировании play-framework.conf ранее (см. Выше).
Следуйте руководству по началу работы …
Все будет автоматически перезагружено при перезагрузке сервера.
Следующие шаги (на основе официального документа):
- Не включайте HTTP2, в настоящее время не работает с Nginx + модуль Lua (видимо, эта ошибка происходит).
- Включите HTTPS, см. Docs/setup-https.md.
- Подпишитесь на рассылку электронной почты
- Отправьте электронное письмо по адресу hello at talkyard.io, чтобы разработчики получили ваш адрес и могли сообщить вам о проблемах с безопасностью и основных обновлениях программного обеспечения, которые могут потребовать от вас действий вручную.
- Регулярно копируйте резервные копии за пределы сайта. См. Раздел «Резервные копии».
- Настройте вход в Gmail, Facebook, Twitter, GitHub, создав приложения OpenAuth на своих сайтах и добавив ключи и секреты API в файлы play-framework.conf. В настоящее время официальная документация для этого находится в стадии разработки.
Остановка контейнеров
Если вы хотите отключить контейнеры, вы можете сделать это, перейдя в каталог, в который вы загрузили Talkyard с Git, и используя эту команду:
docker-compose down
Чтобы снова начать развертывание, убедитесь, что вы работаете в том же каталоге /opt/talkyard/, и запустите:
docker-compose up -d
Чтобы получить полную информацию о приложении Talkyard и всех его функциях, вы можете обратиться к официальному репозиторию, кроме производственного репозитория.
Редактор: AndreyEx