Тема
Развёртывание
Перед установкой ознакомьтесь с системными требованиями и подготовьте DNS, сетевые доступы и диски.
Предупреждение. Быстрый мастер
install.shпока не поддерживает закрытый контур. Для закрытого контура используйте ручную установку из архивов образов, описанную ниже. Параметр--offlineу быстрого мастера недоступен.
1. Получение комплекта поставки
Архив содержит каталог верхнего уровня l1-support:
text
l1-support
├── install.sh
├── docker-compose.yaml
├── garage.toml
└── .env.exampleТакже должны быть предоставлены точные версии образов backend и frontend. Для установки через Container Registry нужны учётные данные, если registry требует авторизацию. Для закрытого контура отдельно запросите у поставщика архивы всех образов из docker-compose.yaml, включая PostgreSQL, Redis, Garage и AWS CLI для настройки CORS.
Архив комплекта поставки: скачать l1-support-release.zip.
Архив содержит установочные файлы для сценария с Container Registry; образы для закрытого контура в него не входят.
Команды установки выполняются от sudo или root поэтапно:
Скачайте архив:
bashcurl -fL https://download.legionsecurity.ru/releases/1ltp/1ltp-deploy/v1/l1-support-release.zip \ -o /tmp/l1-support-release.zipРаспакуйте архив:
bashunzip /tmp/l1-support-release.zip -d /opt
Архив уже содержит каталог l1-support, поэтому его распаковывают в /opt. Каталог и файлы остаются во владении root. Если архив скачан через браузер на другом компьютере, перенесите его на сервер по пути /tmp/l1-support-release.zip и пропустите команду curl.
Проверьте, что в рабочем каталоге есть install.sh, docker-compose.yaml, garage.toml и .env.example:
bash
ls -laПосле подготовки каталога выберите один из двух способов установки ниже.
Быстрая установка
Быстрый интерактивный мастер доступен для серверов с доступом к Container Registry.
Важно. Быстрый установщик не настраивает DNS, TLS-сертификаты и reverse proxy. При выборе HTTPS подготовьте их заранее в соответствии с разделом «Публикация через HTTPS».
В HTTPS-режиме мастер предложит выбрать два DNS-имени на стандартном порту 443 либо одно DNS-имя с отдельным S3-портом, по умолчанию 9443. Локальные порты frontend и Garage при этом привязываются к 127.0.0.1. В режиме прямого HTTP-доступа они привязываются к 0.0.0.0 и должны быть ограничены сетевыми правилами сервера.
Сервер с доступом к Container Registry
Если на сервере ещё нет действующих учётных данных, выполните авторизацию в Container Registry. Используйте выделенную учётную запись:
- логин:
robot$l1-support+trial-license; - пароль:
CYcAL6USeE2cH4JNOOAoTWJyKklLN7zX.
Чтобы пароль не сохранился в истории команд, запустите авторизацию без указания пароля в командной строке:
bash
docker login registry.legionsecurity.ruПосле запроса Username введите выданный логин, а после запроса Password — пароль или Deploy Token.
Запустите установку от root:
bash
cd /opt/l1-support
sudo bash install.shУстановщик запускается через bash, так как файл install.sh в архиве не имеет права на исполнение. После успешного завершения откройте показанный мастером Web-адрес и перейдите к первоначальной настройке.
Ручная установка
Ручной сценарий подходит как для Container Registry, так и для закрытого контура. Выполняйте команды этого раздела в сеансе root:
bash
sudo -i
cd /opt/l1-support1. Настройка окружения
При первой ручной установке создайте .env из шаблона и ограничьте доступ к нему:
bash
cp .env.example .env
chmod 600 .envПри обновлении существующий
.envне заменяется шаблоном из новой поставки. Новые и изменённые параметры нужно переносить вручную после сравнения файлов.
Полный перечень параметров приведён в справочнике конфигурации. До первого запуска обязательно настройте следующие группы в .env.
Версии образов
Укажите пути и точные неизменяемые версии:
dotenv
BACKEND_IMAGE=registry.legionsecurity.ru/l1-support/l1-server
BACKEND_VERSION=v1.9.3
FRONTEND_IMAGE=registry.legionsecurity.ru/l1-support/l1-client
FRONTEND_VERSION=v1.10.0Тег latest в промышленной установке не используется.
Публичные адреса
Укажите адреса, по которым frontend и файловое хранилище будут доступны с рабочих мест пользователей.
Для временного запуска без reverse proxy замените 192.168.1.10 на IP-адрес сервера:
dotenv
FRONTEND_BIND_ADDRESS=0.0.0.0
FRONTEND_PUBLIC_URL=http://192.168.1.10:9090
GARAGE_S3_BIND_ADDRESS=0.0.0.0
S3_PUBLIC_ENDPOINT=http://192.168.1.10:9104Порты 9090 и 9104 должны быть доступны с рабочих мест пользователей.
Для промышленной установки с двумя DNS-именами укажите:
dotenv
FRONTEND_BIND_ADDRESS=127.0.0.1
FRONTEND_PUBLIC_URL=https://l1.example.org
GARAGE_S3_BIND_ADDRESS=127.0.0.1
S3_PUBLIC_ENDPOINT=https://s3.l1.example.orgЕсли заказчик выделил только одно DNS-имя, используйте разные HTTPS-порты:
dotenv
FRONTEND_BIND_ADDRESS=127.0.0.1
FRONTEND_PUBLIC_URL=https://l1.example.org
GARAGE_S3_BIND_ADDRESS=127.0.0.1
S3_PUBLIC_ENDPOINT=https://l1.example.org:9443В этом варианте reverse proxy принимает веб-интерфейс на стандартном порту 443, а S3 API — на отдельном порту 9443. Один TLS-сертификат для l1.example.org действует на обоих портах: номер порта не входит в сертификат.
DNS-имена должны разрешаться в IP-адрес reverse proxy, а указанные порты — быть доступны с рабочих мест пользователей. Не настраивайте HTTPS frontend вместе с HTTP-адресом S3: браузер может заблокировать загрузку и скачивание файлов как mixed content.
S3_PUBLIC_ENDPOINT должен быть доступен из браузеров пользователей. Укажите только базовый адрес — без имени бакета и дополнительного пути. Backend использует этот адрес при формировании подписанных URL, по которым браузеры напрямую загружают и скачивают файлы.
Не используйте
localhostили127.0.0.1: для пользователя они указывают на его собственный компьютер, а не на сервер.
Секреты
Для генерации секретов на сервере должен быть установлен openssl.
Сгенерируйте независимые значения для каждого секрета:
bash
printf 'JWT_SECRET=%s\n' "$(openssl rand -hex 32)"
printf 'APP_SECRETS_KEY=%s\n' "$(openssl rand -base64 32)"
printf 'DB_PASSWORD=%s\n' "$(openssl rand -hex 24)"
printf 'REDIS_PASSWORD=%s\n' "$(openssl rand -hex 24)"
printf 'GARAGE_RPC_SECRET=%s\n' "$(openssl rand -hex 32)"
printf 'GARAGE_ADMIN_TOKEN=%s\n' "$(openssl rand -base64 32)"
printf 'GARAGE_METRICS_TOKEN=%s\n' "$(openssl rand -base64 32)"
printf 'S3_ACCESS_KEY=GK%s\n' "$(openssl rand -hex 16)"
printf 'S3_SECRET_KEY=%s\n' "$(openssl rand -hex 32)"Перенесите полученные значения в .env.
Сохраните
.envиAPP_SECRETS_KEYв защищённом хранилище. При потереAPP_SECRETS_KEYранее зашифрованные настройки интеграций станут недоступны.
Корпоративный DNS
Этот раздел требуется, если для авторизации используется LDAP/Active Directory и контейнеру backend необходимо разрешать корпоративные доменные имена.
Замените значения на параметры корпоративной сети:
dotenv
DOCKER_DNS_SERVER=192.168.20.100
DOCKER_DNS_SEARCH=corp.example.orgDOCKER_DNS_SERVER— IP-адрес корпоративного DNS-сервера.DOCKER_DNS_SEARCH— домен, который будет автоматически добавляться при обращении по короткому имени, напримерdc01→dc01.corp.example.org.
DNS-сервер и контроллеры домена должны быть доступны с Docker-сервера и из контейнера backend. Если LDAP/Active Directory не используется или корпоративные имена уже разрешаются без дополнительной настройки, эти параметры можно не указывать.
Проверка конфигурации
bash
grep -n 'CHANGE_ME' .env
ENVFILE=.env docker compose --env-file .env config --quietСтроки в выводе grep означают, что соответствующие параметры необходимо заполнить. Команда docker compose config не должна возвращать ошибок.
2. Загрузка образов
Перед выполнением команд перейдите в каталог развёртывания /opt/l1-support или в каталог, выбранный при установке. В нём должны находиться docker-compose.yaml и настроенный файл .env.
Сервер с доступом к Container Registry
Если на сервере ещё нет действующих учётных данных, выполните авторизацию в Container Registry. Используйте выделенную учётную запись:
- логин:
robot$l1-support+trial-license; - пароль:
CYcAL6USeE2cH4JNOOAoTWJyKklLN7zX.
Чтобы пароль не сохранился в истории команд, запустите авторизацию без указания пароля в командной строке:
bash
docker login registry.legionsecurity.ruПосле запроса Username введите выданный логин, а после запроса Password — пароль или Deploy Token.
Загрузите образы приложения:
bash
docker compose pullПовторная авторизация перед каждым запуском не требуется. Выполните docker login повторно, только если текущие учётные данные перестали действовать.
Закрытый контур: ручная загрузка образов
Быстрый мастер install.sh для этого сценария не используется. Запросите архивы образов у поставщика, передайте их на сервер разрешённым способом и загрузите каждый архив вручную:
bash
for archive in /path/to/images/*.tar; do
docker load --input "$archive"
doneУбедитесь, что загружены все образы и их теги совпадают со значениями в .env и docker-compose.yaml:
bash
docker image ls
ENVFILE=.env docker compose --env-file .env config --imagesВ закрытом контуре не выполняйте docker compose pull. Если хотя бы один образ отсутствует или его тег не совпадает, запуск завершится ошибкой получения образа.
3. Запуск
bash
docker compose up -d
docker compose ps -aОжидаемое состояние:
| Сервис | Статус |
|---|---|
postgres, redis, garage, backend, frontend | Up и healthy. |
migrate, garage-init | Exited (0). |
migrate и garage-init являются одноразовыми сервисами. Их завершение с кодом 0 является штатным. garage-init автоматически применяет CORS к бакету Garage для адреса FRONTEND_PUBLIC_URL; вручную создавать cors.json при новой установке не требуется.
Если запуск не завершился успешно:
bash
docker compose ps -a
docker compose logs --tail=200 migrate garage garage-init backendПосле исправления причины повторите docker compose up -d.
4. Проверка на Docker-сервере
bash
curl -f http://127.0.0.1:9100/api/v1/system/bootstrap/status
curl -fI http://127.0.0.1:9090
curl -f http://127.0.0.1:9103/healthЕсли локальные проверки проходят, а система недоступна с рабочего места, проверьте DNS, межсетевой экран, маршрутизацию и reverse proxy.
Публикация через HTTPS
Быстрый мастер записывает публичные адреса в .env, но не устанавливает и не настраивает DNS, TLS-сертификаты, межсетевой экран или reverse proxy. Эти компоненты настраиваются отдельно.
Варианты публикации
| Вариант | Веб-интерфейс | S3 API | Входящие порты |
|---|---|---|---|
| Два DNS-имени | https://l1.example.org | https://s3.l1.example.org | 80, 443 |
| Одно DNS-имя, разные порты | https://l1.example.org | https://l1.example.org:9443 | 80, 443, 9443 |
Порт 80 нужен для перенаправления на HTTPS и проверки HTTP-01 при выпуске и автоматическом продлении сертификата Let's Encrypt. Если используется другой способ проверки сертификата, например DNS-01, необходимость внешнего порта 80 определяется инфраструктурой заказчика.
Для варианта с одним DNS настройте NAT или внешний firewall:
text
PUBLIC_IP:80 -> DOCKER_SERVER_IP:80
PUBLIC_IP:443 -> DOCKER_SERVER_IP:443
PUBLIC_IP:9443 -> DOCKER_SERVER_IP:9443Порты приложения 9090, 9100, 9101, 9102, 9103 и 9104 не публикуйте во внешнюю сеть. Reverse proxy на Docker-сервере обращается к ним локально.
Установка Nginx и Certbot
Этот пример предназначен для Ubuntu/Debian, когда Nginx установлен на том же сервере, что и Docker:
bash
sudo apt-get update
sudo apt-get install -y nginx certbot python3-certbot-nginxДо запроса сертификата создайте HTTP-конфигурацию /etc/nginx/sites-available/l1-support:
nginx
server {
listen 80;
listen [::]:80;
server_name l1.example.org;
location / {
proxy_pass http://127.0.0.1:9090;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Активируйте конфигурацию и убедитесь, что домен доступен извне по HTTP:
bash
sudo ln -s /etc/nginx/sites-available/l1-support /etc/nginx/sites-enabled/l1-support
sudo nginx -t
sudo systemctl enable --now nginx
sudo systemctl reload nginxПолучите сертификат. Для одного DNS-имени:
bash
sudo certbot certonly --nginx -d l1.example.orgДля двух DNS-имён выпустите один сертификат с обоими именами:
bash
sudo certbot certonly --nginx -d l1.example.org -d s3.l1.example.orgПеред этой командой добавьте s3.l1.example.org в server_name временной HTTP-конфигурации. После выпуска проверьте фактические пути сертификата командой sudo certbot certificates. Если Certbot добавил суффикс, например -0001, используйте показанные им пути в итоговой конфигурации Nginx.
Если HTTP-01 завершается с timeout или connection refused, проверьте DNS, NAT и доступность входящего 80/TCP.
Готовая конфигурация Nginx для одного DNS
После выпуска сертификата замените конфигурацию l1-support следующим содержимым. В примере API и WebSocket направляются непосредственно в backend, веб-интерфейс — во frontend, S3 API — в Garage:
nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name l1.example.org;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name l1.example.org;
ssl_certificate /etc/letsencrypt/live/l1.example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/l1.example.org/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location /api/ {
proxy_pass http://127.0.0.1:9100;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Sec-WebSocket-Protocol $http_sec_websocket_protocol;
proxy_buffering off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
location / {
proxy_pass http://127.0.0.1:9090;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
server {
listen 9443 ssl;
listen [::]:9443 ssl;
server_name l1.example.org;
ssl_certificate /etc/letsencrypt/live/l1.example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/l1.example.org/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Значение должно быть не меньше FILES_MAX_SIZE_BYTES.
client_max_body_size 1g;
location / {
proxy_pass http://127.0.0.1:9104;
proxy_http_version 1.1;
# Для подписанных S3 URL важно сохранить исходный Host вместе с :9443.
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_request_buffering off;
proxy_buffering off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}Для схемы с двумя DNS измените последний блок: используйте listen 443 ssl, укажите server_name s3.l1.example.org и пути к сертификату, содержащему оба DNS-имени.
Проверьте и примените конфигурацию:
bash
sudo nginx -t
sudo systemctl reload nginx
sudo ss -lntp | grep -E ':(443|9443)[[:space:]]'Настройка приложения и проверка
Для одного DNS укажите в .env:
dotenv
FRONTEND_BIND_ADDRESS=127.0.0.1
FRONTEND_PUBLIC_URL=https://l1.example.org
GARAGE_S3_BIND_ADDRESS=127.0.0.1
S3_PUBLIC_ENDPOINT=https://l1.example.org:9443Примените изменения:
bash
docker compose up -d --force-recreate backend frontend
docker compose ps -aПроверьте HTTPS и автоматическое продление сертификата:
bash
curl -fI https://l1.example.org
curl -sS -o /dev/null -w '%{http_code}\n' https://l1.example.org:9443/
sudo certbot renew --dry-runДля неподписанного запроса к S3 ожидается код 403: Garage доступен, но анонимный доступ запрещён.
В браузере дополнительно проверьте:
- WebSocket
/api/v1/notifications/liveвозвращает101 Switching Protocols; - загрузка файла выполняется методом
PUTпо адресу изS3_PUBLIC_ENDPOINTи возвращает200 OK; - скачивание ранее загруженного файла работает;
- URL загрузки и скачивания начинается с
https://, а не с внутреннего IP-адреса.
Публичные адреса reverse proxy должны в точности совпадать со значениями FRONTEND_PUBLIC_URL и S3_PUBLIC_ENDPOINT.
Первоначальная настройка
- Откройте
FRONTEND_PUBLIC_URLв браузере. - Создайте первого администратора на начальной странице.
- Войдите в систему.
- Загрузите и скачайте тестовый файл.
- Настройте почту и используемые провайдеры аутентификации.
- Проверьте внешнее резервное копирование PostgreSQL и Garage.
Дальнейшие процедуры приведены в руководстве по эксплуатации.