ИТ Блог. Администрирование серверов на основе Linux (Ubuntu, Debian, CentOS, openSUSE)

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

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

Talkyard – это программное обеспечение для форумов с открытым исходным кодом, которое объединяет основные функции StackOverflow, Discourse, Slack, HackerNews, Reddit и Disqus.

Вы можете использовать его для создания форума для своих студентов, доски вопросов и ответов для ваших команд и клиентов, доски обсуждений для мозгового штурма. Вы также можете использовать его для публичного чата поддержки. В конечном итоге вы можете использовать его в качестве системы комментариев в своем блоге Ghost, Hugo или Jekyll.

 

Установка Talkyard с Docker в режиме гибридной контейнеризации

Этот документ основан на руководстве по развертыванию Talkyard в производственной среде, но ориентирован на его развертывание в контейнере Nginx с основными функциями и использует упрощенный подход за счет тщательного пересмотра сетевых параметров docker-compose.yml.

В официальном руководстве упоминается использование Nginx, но оно основано на установке на стороне хоста.

Предпосылки

Это не обязательно, но вам будет намного проще следовать руководству, если у вас есть:

Вы будете развертывать Talkyard за обратным прокси-контейнером с субдоменом с поддержкой SSL.

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

В качестве примера будем использовать 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

 

Вы будете использовать следующие образы докеров:

 

Шаг 3. Подготовьте Ubuntu к установке Talkyard

Установите инструменты, включите автоматические обновления безопасности, упростите устранение неполадок и заставьте ElasticSearch работать. Все это можно сделать с помощью скрипта prepare-ubuntu.sh, доступного в папке скриптов.

sudo ./scripts/prepare-ubuntu.sh 2>&1 | sudo tee -a talkyard-maint.log

 

Далее следует помнить о следующих важных моментах:

 

Шаг 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:

 

Шаг 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 ранее (см. Выше).

Следуйте руководству по началу работы …

Все будет автоматически перезагружено при перезагрузке сервера.

Следующие шаги (на основе официального документа):

 

Остановка контейнеров

Если вы хотите отключить контейнеры, вы можете сделать это, перейдя в каталог, в который вы загрузили Talkyard с Git, и используя эту команду:

docker-compose down

 

Чтобы снова начать развертывание, убедитесь, что вы работаете в том же каталоге /opt/talkyard/, и запустите:

docker-compose up -d

 

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

Exit mobile version