Docker и 1С:Предприятие на Linux: проброс лицензий HASP и .lic в CI/CD, не ломая привязку к железу
Попытка запустить Конфигуратор в Docker-контейнере без лицензии заканчивается немедленной ошибкой и падением сборщика. Самый частый неверный ход - попытаться "докеризовать" сам USB-ключ HASP: виртуальный USB-слой в контейнерах чувствителен к любой задержке, при первом же сбое пайплайн падает, а использование эмуляторов ключей защиты прямо запрещено лицензионным соглашением 1С. Рабочий путь другой: ключ и лицензия остаются на хосте, а платформа внутри контейнера обращается к ним штатными сетевыми механизмами.
1. Два способа проброса и один, которого лучше избегать
Контейнеризация сборки и тестирования 1С требует бесперебойного доступа к коммерческим лицензиям, и в зависимости от типа защиты (программная или аппаратная) применяются разные подходы.
- Аппаратные ключи: ключ остаётся на хосте, на нём работает служба HASP License Manager, контейнеры обращаются к ней по UDP-порту 475 через файл
nethasp.ini. - Программные лицензии: файл
*.licактивируется на хосте и монтируется в контейнер в режиме Read-Only; чтобы параметры железа совпали, контейнер запускается с--net=host.
1.1. Сетевая аппаратная защита (HASP License Manager) - рекомендуемый способ
Аппаратная защита стабильнее для Docker-окружения, так как ключи HASP не привязаны к изменяемым характеристикам самого контейнера.
- На физическом сервере (или выделенной стабильной ВМ в локальной сети) разворачивается служба HASP License Manager, к которой подключаются многопользовательские USB-ключи.
- Взаимодействие платформы 1С с License Manager идёт по сети, по UDP-порту 475 - этот порт задан протоколом и не меняется через конфигурацию.
- Внутри Docker-образа настраивается
nethasp.ini(обычно в каталогеconfустановленной платформы, например/opt/1cv8/x86_64/conf/nethasp.ini) с явным IP-адресом менеджера лицензий и отключённым широковещательным поиском.
1.2. Программная защита (файлы *.lic) и монтирование тома
Этот подход годится, если сборочный раннер работает на том же физическом сервере, где активирована лицензия.
- Лицензия активируется на самом хост-сервере Linux; файл
*.licсохраняется в каталоге лицензий платформы. - Каталогу назначаются права: владелец -
root, группа -grp1cv8, чтение и запись для владельца и группы, только чтение для остальных. - При запуске контейнера каталог монтируется в режиме Read-Only:
-v /var/1C/licenses:/var/1C/licenses:ro - Чтобы платформа внутри контейнера сопоставила лицензию с оборудованием, контейнер запускается с общим сетевым стеком хоста:
--net=host --hostname=ваш-хост-сервер. Тогда MAC-адреса и сетевое имя внутри контейнера совпадают с хостом, и лицензия признаётся действительной.
2. Как платформа проверяет привязку к оборудованию
Чтобы не сломать привязку случайным изменением инфраструктуры, полезно понимать, по каким параметрам 1С сверяет "отпечаток" компьютера и какие изменения он допускает.
2.1. Что входит в отпечаток
При активации программной лицензии платформа шифрует в файле лицензии уникальный набор характеристик компьютера: сетевое имя, модель материнской платы, тип и версию BIOS, объём ОЗУ, список процессоров, список контроллеров дисков, список сетевых адаптеров с MAC-адресами (кроме Bluetooth, внешних USB/IEEE1394-адаптеров и виртуальных WAN/RAS-адаптеров), а под Windows - ещё и версию, серийный номер и дату установки ОС (кроме Windows 10, где серийный номер и дата установки не учитываются). Под Linux версия и наименование ОС в проверку не входят.
2.2. Что можно менять без переактивации
- Правило "только удаление": добавление нового оборудования (второй сетевой адаптер, дополнительный диск) не ломает лицензию. Замена или отключение уже учтённого компонента - ломает, и требует повторной активации по резервному пинкоду.
- ОЗУ можно только увеличивать: если лицензия активирована на 8 ГБ, увеличение до 32 ГБ и последующее снижение до 16 ГБ (больше исходных 8 ГБ) привязку не ломает. Снижение ниже точки активации (например, до 4 ГБ) - ломает.
- Внешние накопители игнорируются при повседневной проверке, кроме момента самой активации - тогда конфигурация должна совпадать полностью, включая подключённые в этот момент USB-накопители.
Проверка выполняется платформой в фоне не чаще одного раза в сутки. При обнаружении критического расхождения файл лицензии блокируется, а новые сеансы (включая шаги сборочного пайплайна) не запускаются до ввода резервного пинкода.
3. Сборка образа и настройка сетевого HASP-клиента
Дистрибутивы платформы 1С для Linux (*.deb или *.tar.gz) кладутся в каталог сборки, после чего образ собирается обычным docker build:
docker build -t 1c-ci-runner:latest --build-arg ONEC_VERSION=8.3.25.1394 .
Локальный файл nethasp.ini для сетевого HASP-клиента:
[NH_COMMON]
NH_TCPIP = Enabled
[NH_TCPIP]
NH_SERVER_ADDR = 192.168.1.50 # IP-адрес вашего HASP License Manager в локальной сети
NH_PORT_NUMBER = 475
NH_TCPIP_METHOD = UDP
NH_USE_BROADCAST = Disabled
При запуске контейнера файл пробрасывается по пути установки платформы:
-v /path/to/local/nethasp.ini:/opt/1cv8/x86_64/conf/nethasp.ini:ro
4. Локальный стенд через Docker Compose
Для отладки пайплайна и автотестов Vanessa-Automation удобен docker-compose.yml, который поднимает контейнер, монтирует каталоги проекта и пробрасывает Xvfb для виртуального графического экрана:
# Каталоги для баз данных и логов
mkdir -p /var/1c/db /var/1c/logs
# Контейнер в фоновом режиме
docker-compose up -d
5. Регистрация GitLab Runner на Linux-хосте
- Установите GitLab Runner на целевой Linux-сервер по официальной инструкции.
- Зарегистрируйте раннер:
sudo gitlab-runner register \ --non-interactive \ --url "https://gitlab.yourcompany.com/" \ --registration-token "REGISTRATION_TOKEN_HERE" \ --executor "docker" \ --docker-image "1c-ci-runner:latest" \ --description "1C Linux Docker Runner with Licences" \ --tag-list "1c-linux-runner" - В файле
/etc/gitlab-runner/config.tomlразрешите проброс каталога лицензий и (если используется программная лицензия хоста) сеть хоста:[[runners]] name = "1C Linux Docker Runner" executor = "docker" [runners.docker] tls_verify = false image = "1c-ci-runner:latest" privileged = false disable_entrypoint_overwrite = false oom_kill_disable = false disable_cache = false volumes = ["/cache", "/var/1C/licenses:/var/1C/licenses:ro", "/var/1c/db:/var/1c/db"] network_mode = "host" shm_size = 2147483648 - Перезапустите службу:
sudo systemctl restart gitlab-runner.
6. Конвейер .gitlab-ci.yml: синтаксический контроль, деплой, acceptance-тесты
stages:
- test
- deploy
- acceptance-test
variables:
DB_CONNECTION: "/F\"/var/1c/db/test_ci\""
EXT_NAME: "MyCustomExtension"
DB_USER: "Admin"
DB_PASS: "SecurePassword123"
# Шаг 1: синтаксический контроль расширения
run-syntax-check:
stage: test
tags:
- 1c-linux-runner
script:
- chmod +x ./scripts/1c-ci-linux-build-v4.sh
- ./scripts/1c-ci-linux-build-v4.sh -c "$DB_CONNECTION" -e "$EXT_NAME" -u "$DB_USER" -w "$DB_PASS" -s "./src/extension"
artifacts:
when: always
paths:
- /tmp/1c_compile_log_*.txt
- /tmp/1c_compile_err_*.txt
expire_in: 1 week
# Шаг 2: применение изменений конфигурации на тест-контуре
deploy-to-stage:
stage: deploy
only:
- main
tags:
- 1c-linux-runner
script:
- /opt/1cv8/x86_64/current/rac session --cluster=$(/opt/1cv8/x86_64/current/rac cluster list | grep cluster | head -n1 | awk '{print $3}') terminate --base=test_ci || true
- /opt/1cv8/x86_64/current/1cv8 DESIGNER $DB_CONNECTION /N "$DB_USER" /P "$DB_PASS" /UpdateDBCfg /Force
dependencies:
- run-syntax-check
# Шаг 3: acceptance-тесты Vanessa-Automation с JUnit-отчётом
run-acceptance-tests:
stage: acceptance-test
only:
- main
tags:
- 1c-linux-runner
script:
- chmod +x ./scripts/1c-ci-linux-test.sh
- ./scripts/1c-ci-linux-test.sh -c "$DB_CONNECTION" -u "$DB_USER" -w "$DB_PASS" -v "/opt/vanessa/vanessa-automation.epf" -f "./tests/features"
artifacts:
when: always
reports:
junit: /tmp/junit_report.xml
paths:
- /tmp/vanessa_log_*.txt
expire_in: 2 weeks
dependencies:
- deploy-to-stage
7. Чек-лист: типичные симптомы и что проверить
| Симптом | Вероятная причина | Что проверить |
|---|---|---|
| "Не найден ключ защиты программы..." при запуске в Docker | Платформа внутри контейнера ищет локальный физический ключ и не видит его из-за изоляции | Настроен ли сетевой nethasp.ini с явным IP HASP License Manager; проброшен ли файл в контейнер |
| Файл *.lic смонтирован, но платформа пишет "Лицензия не обнаружена" | Нарушены права доступа к каталогу лицензий на хосте | Входит ли пользователь, под которым работает 1С в контейнере, в группу grp1cv8 на хосте; права каталога |
| Лицензия слетает при каждом новом раннере | Контейнер использует сеть Docker bridge со случайным MAC-адресом | Запущен ли контейнер с --net=host, чтобы использовать сетевую карту хоста, к которой привязана лицензия |
| Пайплайн зависает на шаге синтаксического контроля | Конфигуратор вывел модальное окно на Xvfb и ждёт реакции пользователя | Передан ли ключ /Force; настроен ли лимит времени выполнения (watchdog) в сборочном скрипте |
Проверить свой уровень бесплатно →