Офлайн-установка DVT
DVT можно установить на Linux-сервер без доступа к интернету. Для этого на отдельной машине с интернетом подготовьте конфигурацию и архив Docker-образов, перенесите комплект на целевой сервер и запустите контейнеры из локальных образов.
Исходники DVT открыты в GitHub. Лицензионный ключ DVT и авторизация в реестре образов для этой установки не требуются. Условия лицензирования отдельных расширений сохраняются.
Инструкция предназначена для новой установки, а не для переноса существующей базы или обновления работающего DVT.
Что подготовить
На обеих машинах проверьте:
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. Пакеты расширений и условия их использования в закрытом контуре подготавливаются отдельно.
Если возникла ошибка
Источники
Сценарий подготовлен по публичной конфигурации DVT и документации Docker 24 сентября 2026 года. Используйте Compose-файл выбранного релиза вместе с соответствующими образами.