Files
relay/docs/DOCKER_INSTALLATION_RU.md
Keonik1 3826de8c60 Add installation via docker compose (MVP 1)
- Add markdown tabs blocks
- Fix [Issue 604](https://github.com/chatmail/relay/issues/604)
- Add `--skip-dns-check` argument to `cmdeploy run` command
- Add `--force` argument to `cmdeploy init` command
- Add startup for `fcgiwrap.service`
- Add extended check when installing `unbound.service`
- Add configuration parameters (`is_development_instance`, `use_foreign_cert_manager`, `acme_email`, `change_kernel_settings`, `fs_inotify_max_user_instances_and_watchers`)
2025-08-09 15:55:37 +03:00

14 KiB
Raw Blame History

Известные проблемы и ограничения

  • Установка с помощью acmetool (docker-compose-default.yaml) может НЕ работать. В таком случае используйте установку через traefik (docker-compose-traefik.yaml). Лично у меня при тестах ошибка была could not install DNS challenge, no hooks succeeded;, которую исправить не удалось.
  • Chatmail будет переустановлен при каждом запуске контейнера (при первом - долго, при последующих быстрее). Так устроен изначальный установщик, потому что он не был заточен под docker. В конце документации представлено возможное решение
  • Требуется настроенный в системе cgroups v2. Работа с cgroups v1 не тестировалась.
  • Да, понятно дело что systemd использовать в контейнере костыль и надо это всё разнести на несколько сервисов, но это MVP и в первом приближении оказалось сделать проще так, чем переписывать всю систему развертывания.
  • docker образ подходит только для amd64, если нужно запустить на другой архитектуре, попробуйте изменить dockerfile (конкретно ту часть что ответсвенна за установку dovecot)

Docker installation

Здесь представлена инструкция по установке chatmail с помощью docker-compose.

Предварительная настройка

We use chat.example.org as the chatmail domain in the following steps. Please substitute it with your own domain.

  1. Настройте начальные записи DNS.Ниже приведен пример в привычном формате файла зоны BIND сTTL 1 час (3600 секунд). Замените домен и IP-адреса на свои.

     chat.example.com. 3600 IN A 198.51.100.5
     chat.example.com. 3600 IN AAAA 2001:db8::5
     www.chat.example.com. 3600 IN CNAME chat.example.com.
     mta-sts.chat.example.com. 3600 IN CNAME chat.example.com.
    
  2. Склонируйте репозиторий на свой сервер.

     git clone https://github.com/chatmail/relay
     cd relay
    

Installation

При установке через docker есть несколько вариантов:

  • использовать встроенный в chatmail контейнер nginx и acmetool для хостинга чата и управления сертификатами.
  • использовать сторонние инструменты для менеджмента сертификатов

В качестве примера для стороннего менеджера сертификатов будет использоваться traefik, но вы можете использовать то что удобнее вам.

  1. Скопировать файл ./docker/docker-compose-default.yaml или ./docker/docker-compose-traefik.yaml и переименовать в docker-compose.yaml. Это нужно потому что docker-compose.yaml находится в .gitignore и не будет создавать конфликты при обновлении гит репозитория.
cp ./docker/docker-compose-default.yaml docker-compose.yaml
## or
# cp ./docker/docker-compose-traefik.yaml docker-compose.yaml
  1. Скопировать ./docker/example.env и переименовать в .env. Здесь хранятся переменные, которые используятся в docker-compose.yaml. Нужен только для установки совместно с traefik, если используется default - можно пропустить
cp ./docker/example.env .env
  1. Настроить параметры ядра, потому что внутри контейнера их нельзя изменить, а конкретно fs.inotify.max_user_instances и fs.inotify.max_user_watches. Для этого выполнить следующее:
echo "fs.inotify.max_user_instances=65536" | sudo tee -a /etc/sysctl.d/99-inotify.conf
echo "fs.inotify.max_user_watches=65536" | sudo tee -a /etc/sysctl.d/99-inotify.conf
sudo sysctl --system
  1. Настроить переменные окружения контейнера. Ниже перечислен список переменных учавствующих при развертывании.
  • MAIL_DOMAIN - Доменное имя будущего сервера. (required)
  • DEBUG_COMMANDS_ENABLED - Выполнить debug команды перед установкой. (default: false)
  • FORCE_REINIT_INI_FILE - Пересоздавать ini файл конфигурации при запуске. (default: false)
  • USE_FOREIGN_CERT_MANAGER - Использовать сторонний менеджер сертификатов. (default: false)
  • INI_FILE - путь к ini файлу конфигурации. (default: ./chatmail.ini)
  • PATH_TO_SSL_CONTAINER - Путь где располагаются сертификаты. (default: /var/lib/acme/live/${MAIL_DOMAIN})
  • ENABLE_CERTS_MONITORING - Включить мониторинг сертификатов, если USE_FOREIGN_CERT_MANAGER=true. Если сертфикаты изменятся сервисы будут автоматически перезапущены. (default: false)
  • CERTS_MONITORING_TIMEOUT - Раз во сколько секунд проверять что изменились сертификаты. (default: '60')

Также могут быть использованы все переменные из ini файла конфигурации, они обязаны быть в uppercase формате.

Ниже перечислены переменные, которые обязательны быть выставлены при развертывании через docker:

  • CHANGE_KERNEL_SETTINGS - Менять настройки ядра (fs.inotify.max_user_instances и fs.inotify.max_user_watches) при запуске. При запуске в контейнере смена настроек ядра не может быть выполнена! (default: False)
  1. Настроить переменные окружения в .env файле. Эти переменные используются в docker-compose.yaml файле, чтобы передавать повторяющиеся значения.

  2. Собрать docker образ

docker compose build chatmail
Дополнительные шаги для конфигурации работы с traefik

Note

Если вы используете default установку, без использования traefik - пропустите эти шаги и переходите к шагу 7 (запуск docker compose)

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

Сначала выполните эти команды в консоли, заменив значения в них на корректные.

export YOUR_EMAIL=your_email@gmail.com
mkdir -p "./data/traefik"
cd "./data/traefik"
  1. Создать файл конфигурации traefik
cat > config.yaml << EOF
log:
  level: TRACE

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          permanent: true
  websecure:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
  file:
    directory: /dynamic/conf
    watch: true

serverstransport:
  insecureskipverify: true

certificatesResolvers:
  letsEncrypt:
    acme:
      email: $YOUR_EMAIL
      storage: /acme.json
      caServer: "https://acme-v02.api.letsencrypt.org/directory"
      tlschallenge: true
      httpChallenge:
        entryPoint: web
EOF
  1. Создать post-hook скрипт
cat > post-hook.sh << 'EOF'
CERTS_DIR=${CERTS_DIR:-"/data/letsencrypt/certs"}

for dir in "$CERTS_DIR"/*/; do
    cd "$dir"
    if [ -f "certificate.crt" ]; then
        ln -sf certificate.crt fullchain
    fi
    if [ -f "privatekey.key" ]; then
        ln -sf privatekey.key privkey
    fi
    cd -
done
EOF
  1. Создать acme.json файл
touch acme.json
sudo chown 0:0 ./acme.json # это обязательно
sudo chmod 600 ./acme.json # это обязательно
  1. Создать insecure config
mkdir dynamic-configs
cat > ./dynamic-configs/insecure.yaml << 'EOF'
http:
  serversTransports:
    insecure:
      insecureSkipVerify: true
EOF
cd ../..
  1. Запустить docker compose и дождаться завершения установки
docker compose up -d # запуск сервиса
docker compose logs -f chatmail # просмотр логов контейнера. Для выхода нажать CTRL+C
  1. По окончанию установки можно открыть в браузер https://<your_domain_name>

Использование кастомных файлов

При использовании docker есть возможность использовать измененые файлы конфигурации, чтобы сделать установку более персонализированной. Обычно это требуется для секции www/src, чтобы ознакомительная страница Chatmail была сделана на ваш вкус. Но также это можно использовать и для любых других случаев.

Для того чтобы корректно выполнить подмену файлов необходимо

  1. создать каталог ./custom, он находится в .gitignore, поэтому при обновлении не вызовет конфликтов.
mkdir -p ./custom
  1. Изменить нужный файл. Для примера возьмем index.md
mkdir -p ./custom/www/src
nano ./custom/www/src/index.md
  1. В docker-compose.yaml добавить монтирование файла с помощью секции volumes
services:
  chatmail:
    volumes:
      ...
      ## custom resources
      - ./custom/www/src/index.md:/opt/chatmail/www/src/index.md
  1. Перезапустить сервис
docker compose down
docker compose up -d

Фиксирование версии Chatmail

Note

Это опциональные шаги, их делать требуется только если вас не устраивает что сервис устанавливается каждый раз при запуске

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

  1. Зафиксировать текущее состояние сконфигурированного контейнера
docker container commit chatmail configured-chatmail:$(date +'%Y-%m-%d')
docker image ls | grep configured-chatmail
  1. Изменить entrypoint для контейнера в docker-compose.yaml на
services:
  chatmail:
    image: <image name from step 1>
    volumes:
      ...
      ## custom resources
      - ./custom/setup_chatmail_docker.sh:/setup_chatmail_docker.sh
  1. Создать файл ./custom/setup_chatmail_docker.sh с новым файлом конфигурации
mkdir -p ./custom
cat > ./custom/setup_chatmail_docker.sh << 'EOF'
#!/bin/bash

set -eo pipefail

export ENABLE_CERTS_MONITORING="${ENABLE_CERTS_MONITORING:-true}"
export CERTS_MONITORING_TIMEOUT="${CERTS_MONITORING_TIMEOUT:-60}"
export PATH_TO_SSL_CONTAINER="${PATH_TO_SSL_CONTAINER:-/var/lib/acme/live/${MAIL_DOMAIN}}"

calculate_hash() {
    find "$PATH_TO_SSL_CONTAINER" -type f -exec sha1sum {} \; | sort | sha1sum | awk '{print $1}'
}

monitor_certificates() {
    if [ "$ENABLE_CERTS_MONITORING" != "true" ]; then
        echo "Certs monitoring disabled."
        exit 0
    fi

    current_hash=$(calculate_hash)
    previous_hash=$current_hash

    while true; do
        current_hash=$(calculate_hash)
        if [[ "$current_hash" != "$previous_hash" ]]; then
        # TODO: add an option to restart at a specific time interval 
            echo "[INFO] Certificate's folder hash was changed, restarting nginx, dovecot and postfix services."
            systemctl restart nginx.service
            systemctl reload dovecot.service
            systemctl reload postfix.service
            previous_hash=$current_hash
        fi
        sleep $CERTS_MONITORING_TIMEOUT
    done
}

monitor_certificates &
EOF
  1. Перезапустить сервис
docker compose down
docker compose up -d