Офлайн-установка DVT

DVT можно установить на Linux-сервер без доступа к интернету. Для этого на отдельной машине с интернетом подготовьте конфигурацию и архив Docker-образов, перенесите комплект на целевой сервер и запустите контейнеры из локальных образов.

Исходники DVT открыты в GitHub. Лицензионный ключ DVT и авторизация в реестре образов для этой установки не требуются. Условия лицензирования отдельных расширений сохраняются.

Инструкция предназначена для новой установки, а не для переноса существующей базы или обновления работающего DVT.

Что подготовить

Машина с интернетом

Сервер в закрытом контуре

ОС и архитектура

Linux с той же архитектурой процессора, что у целевого сервера

Инструменты

Docker Engine, плагин Docker Compose, Git, Python 3, Bash, tar, sha256sum

Docker Engine, плагин Docker Compose, Python 3, Bash, tar, sha256sum

Доступ

GitHub, публичный реестр cr.distribution.denvic.tech, Docker Hub и сервисы доставки образов

Источники и приёмники данных внутри вашей сети

Права

Возможность запускать Docker через sudo

Возможность запускать Docker и создавать каталог /var/lib/dvt через sudo

На обеих машинах проверьте:

uname -m sudo docker info sudo docker compose version python3 --version

Архитектуры должны совпадать. Все выбранные образы должны поддерживать эту архитектуру. Заранее предусмотрите место для архива, загруженных образов и данных DVT.

Docker и Compose должны быть установлены до запуска DVT. Если их нет в закрытом контуре, подготовьте пакеты вместе с зависимостями для конкретной ОС и её версии. Архив образов DVT не содержит установочных пакетов Docker. Используйте инструкции Docker Engine и Compose либо регламент установки пакетов вашей ОС.

1. Получите Compose-файл из GitHub

Следующие шаги выполняются на машине с интернетом, в одном сеансе Bash. При ошибке команды остановитесь и устраните причину перед продолжением.

Выберите опубликованный релиз в GitHub Releases. Укажите его Git-тег и соответствующий тег Docker-образов. Не используйте latest для подготовки комплекта конкретной версии.

read -r -p 'Git-тег релиза DVT: ' DVT_REF read -r -p 'Тег Docker-образов этого релиза: ' DVT_VERSION export DVT_VERSION git clone --depth 1 --branch "$DVT_REF" https://github.com/Denvic-Tech/dvt.git dvt-source mkdir dvt-offline cp dvt-source/docker-compose.yaml dvt-offline/docker-compose.yaml git -C dvt-source rev-parse HEAD > dvt-offline/source-commit.txt cd dvt-offline

Git-тег выбирает версию Compose-файла, а DVT_VERSION — версию образов DVT. Они должны относиться к одному релизу. В этом сценарии приложение не собирается из исходников, поэтому подмодуль интерфейса загружать не нужно.

Не запускайте install.sh для офлайн-установки: он скачивает файлы и образы. Веб-мастер также использует сетевую загрузку при установке и обновлении.

2. Создайте конфигурацию целевого сервера

Укажите будущий адрес DVT внутри закрытого контура и внешний порт приложения:

read -r -p 'URL DVT в закрытой сети, например http://192.168.1.50:8080: ' DVT_PUBLIC_URL read -r -p 'Внешний порт DVT, например 8080: ' DVT_EXTERNAL_PORT export DVT_PUBLIC_URL DVT_EXTERNAL_PORT umask 077 python3 - <<'PY' import os import secrets from pathlib import Path from urllib.parse import urlsplit version = os.environ['DVT_VERSION'].strip() url = os.environ['DVT_PUBLIC_URL'].strip() port = int(os.environ['DVT_EXTERNAL_PORT']) parsed = urlsplit(url) if not version or version == 'latest': raise SystemExit('Укажите конкретный тег Docker-образов релиза') if parsed.scheme not in ('http', 'https') or not parsed.hostname: raise SystemExit('Укажите полный URL с http:// или https://') if not 1 <= port <= 65535: raise SystemExit('Порт должен быть от 1 до 65535') if Path('.env').exists(): raise SystemExit('.env уже существует: сохраните его, не генерируйте секреты повторно') values = { 'COMPOSE_PROJECT_NAME': 'dvt', 'COMPOSE_PROFILES': '', 'DVT_VERSION': version, 'DVT_LIB_DIR': '/var/lib/dvt', 'DVT_PUBLIC_URL': url, 'DVT_EXTERNAL_PORT': str(port), 'DVT_COOKIE_SECURE': str(parsed.scheme == 'https').lower(), 'DVT_POSTGRES_USER': 'dvt-user', 'DVT_POSTGRES_DB': 'DVT', 'DVT_POSTGRES_PASSWORD': secrets.token_urlsafe(32), 'DVT_VALKEY_PASSWORD': secrets.token_urlsafe(32), 'DVT_VALKEY_DB': '0', 'DVT_GRPC_FORWARD_SERVICE_TOKEN': secrets.token_urlsafe(32), 'DVT_AI_MCP_ENABLED': 'false', 'DVT_AI_MCP_INTERNAL_SECRET': '', 'DVT_ENABLE_AI_ANALYSIS': 'false', 'DVT_AI_SERVICE_URL': '', 'DVT_AI_SERVICE_API_KEY': '', } import base64 values['DVT_FERNET_KEY'] = base64.urlsafe_b64encode(os.urandom(32)).decode() for name in ( 'DVT_JWT_ACCESS_TOKEN_SECRET_KEY', 'DVT_JWT_REFRESH_TOKEN_SECRET_KEY', 'DVT_JWT_ONETIME_TOKEN_SECRET_KEY', 'DVT_JWT_API_TOKEN_SECRET_KEY', 'DVT_CODE_HASH_SALT', ): values[name] = secrets.token_urlsafe(32) Path('.env').write_text(''.join(f'{k}={v}\n' for k, v in values.items()), encoding='utf-8') Path('.env').chmod(0o600) PY

Скрипт создаёт .env с уникальными паролями и ключами для одного экземпляра DVT. Он использует только стандартную библиотеку Python и не устанавливает дополнительные пакеты.

В этом примере внутренние адреса PostgreSQL, Valkey и других сервисов берутся из Compose-файла. Не заменяйте их на 127.0.0.1: внутри контейнера этот адрес указывает на сам контейнер.

Для прямого доступа порт в публичном URL должен совпадать с DVT_EXTERNAL_PORT. Если используется HTTPS, сертификат и обратный прокси с поддержкой WebSocket настраиваются отдельно. AI MCP и внешние AI-функции в данном примере выключены.

Комплект будет содержать .env с секретами. Передавайте и храните его с ограничением доступа. Не используйте один комплект с одинаковыми секретами для разных независимых установок.

3. Скачайте и сохраните образы

Проверьте конфигурацию, получите список образов и загрузите их:

sudo docker compose --env-file .env -f docker-compose.yaml config --quiet sudo docker compose --env-file .env -f docker-compose.yaml config --images \ | sort -u > images.txt sudo docker compose --env-file .env -f docker-compose.yaml pull

Убедитесь, что загрузились все образы. При ошибке manifest unknown проверьте тег версии, при ошибке платформы — поддержку архитектуры. Не переходите к упаковке после неудачного pull.

Список строится из Compose-файла и включает образы инфраструктуры PostgreSQL и Valkey. Образ веб-установщика также может попасть в архив, но в закрытом контуре ниже запускаются только сервисы приложения.

Сохраните образы и сформируйте комплект:

mapfile -t DVT_IMAGES < images.txt sudo docker image save --output images.tar "${DVT_IMAGES[@]}" sudo chown "$(id -u):$(id -g)" images.tar sha256sum docker-compose.yaml .env images.txt images.tar source-commit.txt > SHA256SUMS tar -czf ../dvt-offline.tar.gz \ docker-compose.yaml .env images.txt images.tar source-commit.txt SHA256SUMS

Docker image save сохраняет образы с их тегами. Для переноса используйте save, а не экспорт файловой системы отдельного контейнера.

4. Перенесите комплект в закрытый контур

Перенесите dvt-offline.tar.gz на целевой сервер разрешённым в вашей организации способом.

На целевом сервере распакуйте архив в отдельный рабочий каталог. В команде замените /путь/к/dvt-offline.tar.gz фактическим путём:

mkdir -m 700 dvt-offline-import cd dvt-offline-import tar -xzf /путь/к/dvt-offline.tar.gz sha256sum --check SHA256SUMS

Для каждого файла должно появиться OK. При несовпадении контрольной суммы повторите перенос.

5. Подготовьте данные и загрузите образы

Убедитесь, что /var/lib/dvt не содержит существующую установку. Следующие команды предназначены для нового экземпляра; они не должны заменять .env работающего DVT.

sudo mkdir -p /var/lib/dvt sudo test ! -e /var/lib/dvt/.env

Если последняя команда завершилась ошибкой, остановитесь: конфигурация уже существует.

sudo install -m 600 .env /var/lib/dvt/.env sudo install -m 644 docker-compose.yaml /var/lib/dvt/docker-compose.yaml sudo mkdir -p /var/lib/dvt/data/pgdata /var/lib/dvt/data/valkeydata \ /var/lib/dvt/installation /var/lib/dvt/extensions sudo python3 - <<'PY' from pathlib import Path from uuid import uuid4 path = Path('/var/lib/dvt/installation/instance_id') if not path.exists(): path.write_text(str(uuid4()) + '\n', encoding='utf-8') PY sudo docker image load --input images.tar sudo docker network inspect dvt-net >/dev/null 2>&1 \ || sudo docker network create dvt-net

Docker image load восстанавливает образы и теги из архива без обращения к реестру.

Сохраните .env вместе с резервными копиями данных. При повторном запуске используйте те же секреты, особенно DVT_FERNET_KEY: его замена может сделать зашифрованные настройки недоступными.

6. Запустите DVT без загрузки из сети

cd /var/lib/dvt sudo docker compose --env-file .env -f docker-compose.yaml config --quiet sudo docker compose --env-file .env -f docker-compose.yaml up -d \ --pull never --no-build \ postgres valkey orchestrator task-worker project-scheduler gateway ui proxy

Параметр --pull never запрещает скачивание образов, а --no-build — сборку. Если нужного образа нет локально, команда завершится ошибкой: подготовьте недостающий образ на машине с интернетом и перенесите его повторно.

Веб-установщик installation_manager и AI MCP в этом сценарии не запускаются. Для офлайн-обновления нужно отдельно подготовить образы новой версии и совместимую конфигурацию; кнопки сетевой установки и обновления в закрытом контуре не используются.

7. Проверьте результат

sudo docker compose --env-file .env -f docker-compose.yaml ps sudo docker compose --env-file .env -f docker-compose.yaml logs --tail 100

Дождитесь готовности сервисов. Откройте URL из .env, например http://192.168.1.50:8080. Проверьте, что интерфейс доступен и контейнеры не перезапускаются постоянно. Дальнейшие действия описаны в разделе авторизации и управления пользователями.

Офлайн-установка не предоставляет доступ к внешним источникам данных. Для работы проектов серверу по-прежнему нужен доступ к используемым БД, файловым хранилищам и API. Пакеты расширений и условия их использования в закрытом контуре подготавливаются отдельно.

Если возникла ошибка

Ошибка

Что проверить

Не найден локальный образ

Совпадение тегов в .env, images.txt и результате docker image load

exec format error

Совпадение архитектур машин и загруженных образов

Не задан DVT_FERNET_KEY

Наличие .env и передачу --env-file .env

Сеть dvt-net не найдена

Выполнение команды создания сети перед запуском

Порт занят или интерфейс недоступен

DVT_EXTERNAL_PORT, публичный URL, межсетевой экран и журналы proxy/gateway

Источники

Сценарий подготовлен по публичной конфигурации DVT и документации Docker 24 сентября 2026 года. Используйте Compose-файл выбранного релиза вместе с соответствующими образами.