Skip to content

Развёртывание ​

Перед установкой ознакомьтесь с системными требованиями и подготовьте 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 поэтапно:

  1. Скачайте архив:

    bash
    curl -fL https://download.legionsecurity.ru/releases/1ltp/1ltp-deploy/v1/l1-support-release.zip \
      -o /tmp/l1-support-release.zip
  2. Распакуйте архив:

    bash
    unzip /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-support

1. Настройка окружения ​

При первой ручной установке создайте .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.org
  • DOCKER_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, frontendUp и healthy.
migrate, garage-initExited (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.orghttps://s3.l1.example.org80, 443
Одно DNS-имя, разные портыhttps://l1.example.orghttps://l1.example.org:944380, 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.

Первоначальная настройка ​

  1. Откройте FRONTEND_PUBLIC_URL в браузере.
  2. Создайте первого администратора на начальной странице.
  3. Войдите в систему.
  4. Загрузите и скачайте тестовый файл.
  5. Настройте почту и используемые провайдеры аутентификации.
  6. Проверьте внешнее резервное копирование PostgreSQL и Garage.

Дальнейшие процедуры приведены в руководстве по эксплуатации.

Логотип ЛЕГИОНЛЕГИОН