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 и всех его функциях, вы можете обратиться к официальному репозиторию, кроме производственного репозитория.