Apps: "Nginx", "Docker", "Docker Compose".
Задача: развернуть в среде исполнения "Docker" написанное на Java web-приложение управления задачами "YouTrack", производства "JetBrains".
Последовательность дальнейших действий такова:
1. Подготовка системного окружения (отдельная инструкция);
2. Установка системы контейнеризации "Docker" (отдельная инструкция);
3. Установка сопутствующего ПО и подготовка конфигурации;
4. Установка и настройка фронтального web-прокси "Nginx";
5. Формирование YAML-конфигурации "Docker Compose";
6. Настройка web-приложения "YouTrack".
2. Установка системы контейнеризации "Docker" (отдельная инструкция);
3. Установка сопутствующего ПО и подготовка конфигурации;
4. Установка и настройка фронтального web-прокси "Nginx";
5. Формирование YAML-конфигурации "Docker Compose";
6. Настройка web-приложения "YouTrack".
Подготовка несущей файловой структуры для приложения "YouTrack".
Распределение файлов приложения внутри docker-контейнера оставим разработчикам "JetBrains", а конфигурационные файлы, загружаемые пользователями данные и журналы событий вынесем в файловую систему несущей системы:
# mkdir -p /var/opt/youtrack/conf
# mkdir -p /var/opt/youtrack/data
# mkdir -p /var/opt/youtrack/logs
# mkdir -p /var/opt/youtrack/backups
# mkdir -p /var/opt/youtrack/data
# mkdir -p /var/opt/youtrack/logs
# mkdir -p /var/opt/youtrack/backups
Создание пользователей и условий для усечения привилегий приложения "YouTrack".
Для синхронизации GID и UID несущей системы и контейнеров при создании пользователя задаём явно их численные значения (подсмотренные на этапе предварительных тестовых запусков):
# groupadd --system --gid 13001 youtrack
# useradd --system --home-dir /var/opt/youtrack --shell /bin/false --gid youtrack --uid 13001 youtrack
# useradd --system --home-dir /var/opt/youtrack --shell /bin/false --gid youtrack --uid 13001 youtrack
Передадим директории файловых ресурсов приложения выделенному для этого пользователю:
# chown -R youtrack:youtrack /var/opt/youtrack
Оптимизация работы "YouTrack" с дисковой подсистемой.
Для приложения, активно создающего и уничтожающего временные файлы, выгодно вынести эту работу в файловую систему, смонтированную в область памяти ОЗУ:
# mkdir -p /var/opt/youtrack/temp
# chown -R youtrack:youtrack /var/opt/youtrack/temp
# chmod -R go-rwx /var/opt/youtrack/temp
# chown -R youtrack:youtrack /var/opt/youtrack/temp
# chmod -R go-rwx /var/opt/youtrack/temp
Добавляем в системный перечень монтируемых файловых систем нашу:
# vi /etc/fstab
....
# Tuning the location of JetBrains YouTrack temporary files
tmpfs /var/opt/youtrack/temp tmpfs rw,nosuid,nodev,size=2G,uid=youtrack,gid=youtrack,mode=0750 0 0
....
# Tuning the location of JetBrains YouTrack temporary files
tmpfs /var/opt/youtrack/temp tmpfs rw,nosuid,nodev,size=2G,uid=youtrack,gid=youtrack,mode=0750 0 0
....
Монтируем или перемонтируем нашу файловую систему:
# mount /var/opt/youtrack/temp
Я бы выделил под эту файловую систему до 10% от объёма ОЗУ (она не заблокирует всё заявленное место, а будет выбирать блоки памяти по мере появления необходимости).
Установка фронтального web-сервера "Nginx".
Встроенный в развёртываемые приложение web-сервер предназначен не только для запуска java-сервлетов, но и выступает в роли web-сервера. Однако на практике для приёма и первичной обработки клиентских подключений удобнее использовать более легковесный web-сервер. Воспользуемся "Nginx":
# aptitude install nginx-light
Для последующего включения в "Nginx" современного SSL/TLS и HTTPv2 генерируем DH-файл:
# mkdir -p /etc/ssl/nginx && chown -R root:root /etc/ssl/nginx
# openssl dhparam -out /etc/ssl/nginx/dhparam.2048.pem 2048
# openssl dhparam -out /etc/ssl/nginx/dhparam.2048.pem 2048
Слегка преднастроим web-сервер:
# vi /etc/nginx/nginx.conf
user www-data www-data;
worker_processes auto;
....
http {
....
server_tokens off;
client_max_body_size 0;
....
worker_processes auto;
....
http {
....
server_tokens off;
client_max_body_size 0;
....
Конфигурация принимающего подключения пользователей web-сервера "Nginx" проста и сводится к описанию параметров "проксирования" всех запросов нижележащему web-сервису, запущенному внутри docker-контейнера:
# vi /etc/nginx/sites-available/youtrack.example.net.conf
server {
listen 80;
server_name youtrack.example.net;
location / { rewrite ^(.+)$ https://$host$1 permanent; }
#include /etc/nginx/snippets/letsencrypt.conf;
}
server {
listen 443 ssl http2;
server_name youtrack.example.net;
access_log /var/log/nginx/youtrack.example.net_access.log;
error_log /var/log/nginx/youtrack.example.net_error.log;
# Описываем параметры установления соединений SSL/TLS
ssl_dhparam /etc/ssl/nginx/dhparam.2048.pem;
ssl_certificate /etc/ssl/nginx/wildcard.example.net.crt;
ssl_certificate_key /etc/ssl/nginx/wildcard.example.net.key.decrypt;
ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Отправляем все запросы в docker-контейнер
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme https;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-NginX-Proxy true;
# (HTTPv1.1 & WebSocket)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_connect_timeout 240;
proxy_send_timeout 240;
proxy_read_timeout 240;
}
}
listen 80;
server_name youtrack.example.net;
location / { rewrite ^(.+)$ https://$host$1 permanent; }
#include /etc/nginx/snippets/letsencrypt.conf;
}
server {
listen 443 ssl http2;
server_name youtrack.example.net;
access_log /var/log/nginx/youtrack.example.net_access.log;
error_log /var/log/nginx/youtrack.example.net_error.log;
# Описываем параметры установления соединений SSL/TLS
ssl_dhparam /etc/ssl/nginx/dhparam.2048.pem;
ssl_certificate /etc/ssl/nginx/wildcard.example.net.crt;
ssl_certificate_key /etc/ssl/nginx/wildcard.example.net.key.decrypt;
ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Отправляем все запросы в docker-контейнер
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme https;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-NginX-Proxy true;
# (HTTPv1.1 & WebSocket)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_connect_timeout 240;
proxy_send_timeout 240;
proxy_read_timeout 240;
}
}
Удаляем конфигурацию "по умолчанию", активируем новую, проверяем и запускаем в работу:
# rm /etc/nginx/sites-enabled/default
# ln -s /etc/nginx/sites-available/youtrack.example.net.conf /etc/nginx/sites-enabled/youtrack.example.net.conf
# nginx -t && nginx -s reload
# ln -s /etc/nginx/sites-available/youtrack.example.net.conf /etc/nginx/sites-enabled/youtrack.example.net.conf
# nginx -t && nginx -s reload
Об установке web-приложения "YouTrack".
Команда "JetBrains" сама собирает docker-контейнер с "YouTrack" и публикует их на общеизвестном сервисе "Docker Hub". Не вижу причин не воспользоваться этим.
Не совсем удобно, что у "YouTrack" нет явно отмеченной "последней стабильной версии" и придётся самому выбирать, какой релиз использовать, по "тегу".
Налаживаем запуск посредством "Docker Compose".
Создаём директорию для размещения конфигурационных файлов "Docker Compose":
# mkdir /usr/local/etc/compose
# cd /usr/local/etc/compose
# cd /usr/local/etc/compose
Воспользуемся для единственного в нашей схеме конфигурационного файла именем "по умолчанию":
# vi ./docker-compose.yml
version: "3"
services:
jetbrains-youtrack:
container_name: jetbrains-youtrack
image: jetbrains/youtrack:2020.x.yyyy
#command: configure -J-Xmx8g
networks:
youtrack:
aliases:
- "jetbrains-youtrack"
ports:
- "127.0.0.1:8080:8080"
dns:
- 10.20.30.45
working_dir: "/var/opt/youtrack"
volumes:
- "/var/opt/youtrack/conf:/opt/youtrack/conf:rw"
- "/var/opt/youtrack/data:/opt/youtrack/data:rw"
- "/var/opt/youtrack/logs:/opt/youtrack/logs:rw"
- "/var/opt/youtrack/backups:/opt/youtrack/backups:rw"
- "/var/opt/youtrack/temp:/opt/youtrack/temp:rw"
networks:
youtrack:
driver: bridge
internal: false
ipam:
driver: default
config:
- subnet: 100.127.255.0/24
services:
jetbrains-youtrack:
container_name: jetbrains-youtrack
image: jetbrains/youtrack:2020.x.yyyy
#command: configure -J-Xmx8g
networks:
youtrack:
aliases:
- "jetbrains-youtrack"
ports:
- "127.0.0.1:8080:8080"
dns:
- 10.20.30.45
working_dir: "/var/opt/youtrack"
volumes:
- "/var/opt/youtrack/conf:/opt/youtrack/conf:rw"
- "/var/opt/youtrack/data:/opt/youtrack/data:rw"
- "/var/opt/youtrack/logs:/opt/youtrack/logs:rw"
- "/var/opt/youtrack/backups:/opt/youtrack/backups:rw"
- "/var/opt/youtrack/temp:/opt/youtrack/temp:rw"
networks:
youtrack:
driver: bridge
internal: false
ipam:
driver: default
config:
- subnet: 100.127.255.0/24
Запускаем контейнер, указывая явно имя конфигурационного файла:
# docker-compose up --remove-orphans --build --force-recreate -d
Останавливаем docker-контейнер, описанный в конфигурации "Docker Compose":
# docker-compose down
Подход к настройке параметров запуска "YouTrack" несколько странный. Например, для задания лимита ОЗУ java-машине, в которой работает "YouTrack", нужно запустить его с опцией "configure -J-Xmx8g" - сервис отработает пару секунд и завершится, после чего нужно будет его снова запустить, уже без опции конфигурирования.
Настройка автозагрузки "Docker Compose" посредством "Systemd".
Создаём файл описания параметров запуска и остановки docker-контейнера посредством "Docker Compose" посредством короткоживущего сервиса "Systemd":
# vi /etc/systemd/system/jetbrains-youtrack-docker.service
[Unit]
Description=JetBrains YouTrack in Docker Compose Service
Requires=network.target docker.service containerd.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/usr/local/etc/compose
ExecStartPre=-/bin/bash -c 'chown -R youtrack:youtrack /var/opt/youtrack'
ExecStartPre=/usr/local/bin/docker-compose -f docker-compose.yml down --remove-orphans
ExecStart=/usr/local/bin/docker-compose -f /usr/local/etc/compose/docker-compose.yml up --remove-orphans --build --force-recreate --detach
#
ExecStop=/usr/local/bin/docker-compose -f /usr/local/etc/compose/docker-compose.yml down
[Install]
WantedBy=multi-user.target
Description=JetBrains YouTrack in Docker Compose Service
Requires=network.target docker.service containerd.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/usr/local/etc/compose
ExecStartPre=-/bin/bash -c 'chown -R youtrack:youtrack /var/opt/youtrack'
ExecStartPre=/usr/local/bin/docker-compose -f docker-compose.yml down --remove-orphans
ExecStart=/usr/local/bin/docker-compose -f /usr/local/etc/compose/docker-compose.yml up --remove-orphans --build --force-recreate --detach
#
ExecStop=/usr/local/bin/docker-compose -f /usr/local/etc/compose/docker-compose.yml down
[Install]
WantedBy=multi-user.target
Указываем "Systemd" перечитать и принять новую конфигурацию, а потом явно активируем и запускаем новый сервис:
# systemctl daemon-reload
# systemctl enable jetbrains-youtrack-docker.service
# systemctl start jetbrains-youtrack-docker
# systemctl enable jetbrains-youtrack-docker.service
# systemctl start jetbrains-youtrack-docker
Смотрим журнал событий "Systemd" если "что-то пошло не так":
# systemctl status jetbrains-youtrack-docker.service
# journalctl -xe
# journalctl -xe
Первоначальная настройка web-приложения.
При первом запуске ещё не настроенного "YouTrack" в web-интерфейсе потребуется ввести секретный "ключ", технически доступный только системному администратору несущего сервера:
# tail /var/opt/youtrack/logs/docker-output-youtrack.log
....
* JetBrains YouTrack 2020.x Configuration Wizard will listen inside container on {0.0.0.0:8080}/ after start and can be accessed by URL .../?wizard_token=Gd..wuM]
* JetBrains YouTrack 2020.x Configuration Wizard will listen inside container on {0.0.0.0:8080}/ after start and can be accessed by URL .../?wizard_token=Gd..wuM]
Далее последует ряд простых вопросов, вроде предпочитаемого FQDN, пароля пользователя для администрирования и способа лицензирования. Кстати, "YouTrack" бесплатен и почти неограничен в функционале для команд до 10 (десяти) пользователей. Стоимость лицензий существенно ниже ближайшего конкурента "Atlassian Jira", а политика расширения по количеству пользователей очень простая и честная.
Явная установка часового пояса (автоматически он задаётся в соответствии с системным):
Settings -> Global Settings -> Visual:
Time zone: Asia/Krasnoyarsk
Time zone: Asia/Krasnoyarsk
Для уведомлений пользователей о событиях в "тикетах" обязательно настраиваем связь с почтовым сервисом:
Settings -> Global Settings -> Notifications:
Email: on
SMTP host: mail.example.net
SMTP port: 25
Mail protocol: SMTP+StartTLS
SMTP login: youtrack@example.net
SMTP password: ***
Email: on
SMTP host: mail.example.net
SMTP port: 25
Mail protocol: SMTP+StartTLS
SMTP login: youtrack@example.net
SMTP password: ***
В "YouTrack" имеется подсистема автоматического создания и ротации файлов резервных копий конфигурации и "базы данных" (noSQL):
Settings -> Database Backup:
Enable regular backup: on
Backup Interval: Every 12 hours
Backup Files Rotation: 7
Enable regular backup: on
Backup Interval: Every 12 hours
Backup Files Rotation: 7
Явно укажем, на каких языках общаются пользователи, чтобы "YouTrack" создавал поисковые индексы для них:
Settings -> Text Index Settings:
Stemmed languages:
English, Русский
Stemmed languages:
English, Русский
Настройка подключения к внешнему LDAP/AD для аутентификации.
В "YouTrack" весьма удобная интеграция с внешними сервисами аутентификации. Типичная первая и единственная проблема - отказ соединяться с LDAP-сервисом по SSL с сертификатом, подлинность которого невозможно проверить ("самоподписанным", например). Решается добавлением корневого сертификата в перечень доверенных:
Settings -> SSL Certificates -> Import trusted certificate...
Соединение с LDAP-сервисом описывается просто и незамысловато:
Settings -> Auth Modules -> New module -> LDAP:
Name: ldap0.example.net
Server URL: ldaps://ldap0.example.net:636/ou=People,dc=example,dc=net
SSL key: No keys
Bind account: Fixed
Bind DN: uid=youtrack0,ou=Accounts,ou=Services,dc=example,dc=net
Filter: (&(uid=%u)(objectclass=person)(memberOf=cn=youtrackusers,ou=groups,dc=example,dc=net))
LDAP referral: Ignore
Attribute Mapping:
Login: uid
Full Name: cn
Email: mail
Groups: none
User creation: Enabled
Name: ldap0.example.net
Server URL: ldaps://ldap0.example.net:636/ou=People,dc=example,dc=net
SSL key: No keys
Bind account: Fixed
Bind DN: uid=youtrack0,ou=Accounts,ou=Services,dc=example,dc=net
Filter: (&(uid=%u)(objectclass=person)(memberOf=cn=youtrackusers,ou=groups,dc=example,dc=net))
LDAP referral: Ignore
Attribute Mapping:
Login: uid
Full Name: cn
Email: mail
Groups: none
User creation: Enabled
Добавление FQDN в дополнение к основному.
Сам web-сервис "YouTrack" не различает, с указанием какого доменного имени к нему обращаются клиенты - то есть, можно настроить фронтальный web-сервер принимать запросы на любом количестве FQDN.
Однако встроенная в "YouTrack" подсистема аутентификации между модулями посредством "OAuth 2.0" требует явной регистрации каждого нового FQDN в списке доверенных. Это в некотором роде "сакральное" действие, скрытое от пользователей и даже администраторов web-сервиса. Добраться до нужного раздела web-панели управления можно по прямой ссылке вроде "https://youtrack.example.net/admin/hub/services".
В перечне управляемых выбираем основной web-сервис, названный по умолчанию "YouTrack", и в блоке "Redirect URIs" добавляем необходимые для работы дополнительного домена адреса, с которых мы разрешаем аутентификацию:
./admin/hub
./oauth
....
http://localhost:8080
....
https://youtrack.example.net
https://youtrack.example.net/admin/hub
https://youtrack.example.net/oauth
....
https://youtrack.example.com
https://youtrack.example.com/admin/hub
https://youtrack.example.com/oauth
./oauth
....
http://localhost:8080
....
https://youtrack.example.net
https://youtrack.example.net/admin/hub
https://youtrack.example.net/oauth
....
https://youtrack.example.com
https://youtrack.example.com/admin/hub
https://youtrack.example.com/oauth