1С без конфигуратора: полный цикл разработки расширения из командной строки

24.08.26

Разработка - DevOps и автоматизация разработки

Полный цикл разработки расширения 1С в пакетном режиме DESIGNER: выгрузка, правка, гейт компиляции, применение к базе и контроль результата — без единого клика в конфигураторе. Разбираю семь мин, на которых подорвался лично: почему LoadConfigFromFiles возвращает нулевой код на битом модуле, зачем нужен Xvfb, как pgrep находит сам себя, кто держит базу и как отличить работающий сеанс от забытого, и почему после рестарта сервера база остаётся закрытой. Платформа 8.3.27, УТ 11.5, сервер на Linux.

О чём это

Год назад у меня была задача: править расширения боевой УТ 11.5 с ноутбука, находясь в другом часовом поясе от сервера, и делать это так, чтобы кассы не вставали. Конфигуратор — приложение с графическим интерфейсом, RDP до сервера был медленным, а любая ошибка стоила простоя магазинов.

Выяснилось, что весь цикл разработки расширения — выгрузка, правка, проверка компиляции, применение к базе и контроль результата — закрывается пакетным режимом DESIGNER без единого клика. Но по дороге лежит несколько мин, на которых я подорвался лично и о которых почти нигде не написано.

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

Статья описывает рабочий цикл целиком, с проверками, которые действительно ловят ошибки. Платформа 8.3.27, конфигурация УТ 11.5, сервер на Linux. Для Windows команды те же, отличается только обвязка.


Команды, из которых складывается цикл

Задача Команда
Выгрузить расширение в файлы DESIGNER /DumpConfigToFiles <dir> -Extension <имя>
Загрузить расширение из файлов DESIGNER /LoadConfigFromFiles <dir> -Extension <имя>
Применить изменения к базе DESIGNER /UpdateDBCfg -Extension <имя>
Проверить компиляцию DESIGNER /CheckModules -Extension <имя> -Server
Выгрузить внешнюю обработку в файлы DESIGNER /DumpExternalDataProcessorOrReportToFiles <dir> <file.epf>
Собрать обработку из файлов DESIGNER /LoadExternalDataProcessorOrReportFromFiles <root.xml> <out.epf>

Ключ -AllExtensions вместо конкретного имени выгружает все расширения разом, каждое в подкаталог <dir>/<имя расширения>. Удобно, когда нужно снять слепок состояния базы целиком.

При выгрузке внешней обработки корневой XML пишется рядом с каталогом, а не внутрь него: указали /tmp/proc — получите каталог /tmp/proc и файл /tmp/proc.xml. Это неочевидно и ломает наивные скрипты, которые ожидают всё в одной папке.


Мина первая: загрузка не значит компиляция

Наивный пайплайн выглядит так: выгрузили, поправили Module.bsl, загрузили обратно, применили к базе. Проверять вроде нечего — команды отработали, коды возврата нулевые.

Проблема в том, что /LoadConfigFromFiles не компилирует модули. Она разбирает XML-структуру и складывает тексты модулей в конфигурацию как есть. Если в модуле синтаксическая ошибка — незакрытая скобка, опечатка в имени процедуры, лишняя точка с запятой — команда завершится с кодом 0 и напишет в лог, что всё хорошо.

Ошибка всплывёт позже: при /UpdateDBCfg, либо вообще в момент первого обращения пользователя к этому коду. То есть на кассе.

Единственная настоящая проверка — /CheckModules:

DESIGNER /CheckModules -Extension <имя> -Server

Она реально компилирует модули на стороне сервера и выдаёт ошибки с номерами строк и именами модулей. Занимает около минуты на среднее расширение. Это дорого для цикла «поправил-проверил», но абсолютно обязательно перед применением к бою.

Ключ -Server важен: без него проверяются не все контексты выполнения, и часть ошибок в серверных процедурах пройдёт мимо.

Правило, к которому я пришёл: между /LoadConfigFromFiles и /UpdateDBCfg всегда стоит /CheckModules, и пайплайн останавливается, если она вернула ошибки. Без этого гейта автоматизация опаснее ручного конфигуратора — тот хотя бы подсвечивает синтаксис при сохранении.


Мина вторая: без Xvfb ничего не запустится

На Linux-сервере без графической подсистемы любая команда DESIGNER падает с сообщением:

Unable to initialize GTK+

Платформа тянет за собой GTK даже в пакетном режиме, где никакого интерфейса нет и не предполагается. Лечится виртуальным X-сервером:

xvfb-run -a 1cv8 DESIGNER /S <сервер>\<база> /N <пользователь> /P <пароль> \
  /DumpConfigToFiles /tmp/cfg -Extension <имя>

Ключ -a заставляет xvfb-run самому выбрать свободный номер дисплея — без него параллельные запуски дерутся за :99 и падают.

Отсюда же вытекает следующая проблема.


Мина третья: модальные диалоги вешают процесс молча

Раз есть виртуальный экран, значит на нём могут появляться окна. И они появляются.

Самый частый случай — «Предупреждение безопасности» при первом открытии внешней обработки. В обычном конфигураторе вы нажимаете «Да» и забываете. В Xvfb окно висит на невидимом экране, процесс ждёт ответа, а вы наблюдаете команду, которая «выполняется» третий час без единой строчки в логе.

Диагностика неприятная, потому что дисплеев в системе бывает несколько, и окно живёт только на одном из них:

for A in $(pgrep -a Xvfb | grep -oE "/tmp/xvfb-run[^ ]*/Xauthority"); do
  D=$(pgrep -a Xvfb | grep "$A" | grep -oE ":[0-9]+" | head -1)
  echo "$D -> $(XAUTHORITY=$A DISPLAY=$D xwininfo -root -tree 2>/dev/null | grep -c 1cv8)"
done

Цикл пробегает по всем живым Xvfb и печатает, на каком дисплее сколько окон платформы. Дальше можно посмотреть, что там:

XAUTHORITY=<auth> DISPLAY=:NNN import -window root /tmp/screen.png

И даже нажать кнопку, если очень нужно:

XAUTHORITY=<auth> DISPLAY=:NNN xdotool mousemove 967 484 click 1

Способ работающий, но это лечение симптома. Правильный вывод: в автоматизированном цикле не должно быть операций, способных открыть модальное окно. Если такая операция появилась — её надо убирать из пайплайна, а не учиться кликать вслепую.


Мина четвёртая: обрыв ssh убивает конфигуратор на середине

/UpdateDBCfg на большой конфигурации идёт минутами. Если запустить её обычной ssh-командой и потерять связь, процесс получит SIGHUP и умрёт посреди применения изменений к базе данных. Состояние после такого — отдельное приключение.

Запускать долгие команды нужно так, чтобы они пережили обрыв:

setsid nohup xvfb-run -a 1cv8 DESIGNER ... </dev/null >/tmp/upd.log 2>&1 &

setsid выносит процесс в отдельную сессию, nohup глушит SIGHUP, </dev/null отвязывает stdin — без него процесс может получить SIGTTIN при попытке чтения с закрытого терминала.

И отдельное правило: не плодить параллельные запуски. Два DESIGNER на одну базу начнут драться за блокировку конфигурации, и в лучшем случае один упадёт, в худшем — оба повиснут. Перед запуском стоит убедиться, что предыдущий завершился.

Причём убедиться внимательно.


Мина пятая: pgrep находит сам себя

Естественная проверка «конфигуратор ещё работает?» выглядит так:

pgrep -f "1cv8 DESIGNER"

Если запустить её внутри цикла ожидания, который сам был вызван как bash -c '... 1cv8 DESIGNER ...', то pgrep найдёт собственную ssh-команду: строка с этим текстом присутствует в командной строке обёртки.

Результат — вечный цикл ожидания процесса, который завершился полчаса назад. Я потерял на этом ровно столько.

Лечится матчингом по полному пути бинарника:

pgrep -af "x86_64/8.3.27.1688/1cv8 DESIGNER"

и обязательной проверкой вывода глазами, а не только кодом возврата.


Кто держит базу: диагностика через ras/rac

Рано или поздно DESIGNER упадёт с сообщением «Ошибка блокировки информационной базы для конфигурирования». Значит, кто-то держит конфигуратор открытым.

В логе /Out видно, чей это сеанс: имя компьютера, номер сеанса, время начала. Но дальше начинается интересное — надо понять, там работают или человек ушёл домой, забыв закрыть окно. В первом случае надо ждать, во втором — снимать.

Сначала поднимаем администрирование кластера. ras по умолчанию не запущен, поэтому rac отвечает «Connection refused»:

setsid nohup ras cluster --port=1545 localhost:1540 </dev/null >/dev/null 2>&1 &

Дальше смотрим сеанс:

rac session info --session=<uuid> --cluster=<uuid> localhost:1545

Как читать вывод — самое важное во всём разделе:

  • calls-last-5min, cpu-time-last-5min, duration-last-5min, bytes-last-5min равны нулю → сеанс висит, в нём никто не работает;
  • last-active-at тикает даже у забытого окна, потому что клиент периодически пингует сервер. По этому полю судить об активности нельзя, и это ловушка, в которую попадают почти все;
  • суммарные duration-all и cpu-time-total в сотни миллисекунд за несколько часов означают, что человек поработал минуту и ушёл.

Забытый сеанс снимается:

rac session terminate --session=<uuid> --cluster=<uuid> localhost:1545

Отдельно стоит проверить, не ваш ли это собственный зависший DESIGNER из прошлого запуска — по моему опыту, виновником чаще всего оказывается именно он.


Мина шестая: после рестарта сервера умирает ras

Скрипты применения обычно закрывают базу от пользователей на время работ и открывают обратно:

rac infobase update --sessions-deny=on  ...   # закрыли
# ... работы ...
rac infobase update --sessions-deny=off ...   # открыли

Если между этими шагами случился systemctl restart srv1cv8 — а он случается, например при смене параметров кластера — то ras умирает вместе с сервером. Команда снятия блокировки молча не выполняется, база остаётся закрытой, а HTTP-сервисы начинают отдавать 500.

Со стороны это выглядит как «мы всё сделали правильно, а приложение легло».

Вывод простой: финальное состояние проверять фактом, а не кодом возврата скрипта. Две проверки, обе обязательны:

rac infobase info --infobase=<uuid> ... | grep sessions-deny
curl -u <логин> http://127.0.0.1/<база>/hs/<корень>/status

Первая говорит, что база открыта по мнению кластера. Вторая — что она действительно отвечает. Ожидаем 200 или 401, но не 500.


Контроль: как убедиться, что в базе именно ваш код

/UpdateDBCfg отработала, ошибок нет. Но лежит ли в базе то, что вы правили?

Вопрос не праздный. Расширение могли параллельно менять с другой стороны — у нас, например, к базе имеет доступ подрядчик. Или ваш патч не доехал по какой-то из причин выше.

Надёжный способ — выгрузить расширение заново и сравнить с тем каталогом, который вы правили:

DESIGNER /DumpConfigToFiles /tmp/cfg_after -Extension <имя>
diff -r -x ConfigDumpInfo.xml /tmp/cfg_patched /tmp/cfg_after && echo ИДЕНТИЧНО

ConfigDumpInfo.xml исключать обязательно — там служебные версии выгрузки, они различаются всегда, и без -x вы будете вечно видеть расхождение.

Тот же приём работает и в обратную сторону: свежий дамп против дампа прошлой сессии показывает, менял ли расширение кто-то ещё, пока вас не было.


Мина седьмая: CRLF против LF

И вот здесь ждёт последняя засада. Вы делаете diff -rq двух дампов и получаете «файлы различаются» на весь файл целиком, хотя глазами разницы не видно.

Причина в переводах строк. 1С выгружает модули с CRLF. Если файл потом правился скриптом на Python, sed или любым другим инструментом с настройками по умолчанию, он превратится в LF. Содержательно файлы идентичны, побайтово — различаются в каждой строке.

Сравнивать надо с нормализацией:

diff <(tr -d '\r' < a.bsl) <(tr -d '\r' < b.bsl)

Для рекурсивного сравнения каталогов проще всего прогнать оба дерева через tr во временные копии, либо использовать diff --strip-trailing-cr.


Как выглядит цикл целиком

Собирая всё вместе, безопасный цикл правки боевого расширения получается такой:

  1. Снять дамп с боя/DumpConfigToFiles, это же ваш бэкап и точка отката.
  2. Сравнить с дампом прошлой сессии — убедиться, что расширение не меняли без вас.
  3. Внести правку в копию каталога, сохраняя CRLF.
  4. Залить в тестовую базу/LoadConfigFromFiles.
  5. Прогнать гейт/CheckModules -Server. Есть ошибки — цикл останавливается, в бой ничего не едет.
  6. Закрыть базу от пользователей, применить в бою: /LoadConfigFromFiles + /UpdateDBCfg.
  7. Открыть базу, проверить фактом: sessions-deny снят, HTTP-сервис отвечает.
  8. Снять дамп заново и сравнить с патченным каталогом — «идентично» означает, что в базе действительно ваш код.

Шаги 5, 7 и 8 — это те самые проверки, которых нет в наивном варианте и без которых автоматизация превращается в рулетку.

Реальный простой касс при таком цикле — около двух минут: столько занимает закрытие базы, применение и открытие обратно. Всё остальное делается на тестовой базе и кассиров не касается.


Что нельзя сделать из командной строки

Честности ради, пакетный режим закрывает не всё:

  • Внешнюю обработку с формой собрать из файлов не получится. /LoadExternalDataProcessorOrReportFromFiles падает с исключением XDTO при чтении Form.xml даже на нетронутом дампе, сделанном той же версией платформы. Обработки без формы собираются нормально.
  • Выполнить произвольный код через 1cv8 ENTERPRISE /Execute не выйдет — команда лишь открывает обработку, тело модуля объекта при этом не исполняется. Это тема отдельной статьи.
  • Интерактивная отладка остаётся за конфигуратором.

Выводы

Пакетный режим DESIGNER полностью закрывает цикл разработки расширений и позволяет держать 1С в нормальном CI рядом с остальным стеком. Но три вещи надо принять как данность:

  1. /CheckModules -Server — единственный настоящий гейт компиляции. Всё остальное молча пропустит битый код.
  2. Успешный код возврата ничего не гарантирует. Финальное состояние проверяется фактом: дамп плюс diff, sessions-deny плюс живой curl.
  3. Окружение важнее команд. Xvfb, setsid nohup, отсутствие модальных окон и честный pgrep — без этого цикл будет виснуть в местах, где вы не ожидаете.

Если выстроить это один раз, дальше правка боевого расширения занимает минуты и не требует ни RDP, ни присутствия в офисе, ни остановки торговли.


Платформа 8.3.27, УТ 11.5, сервер 1С на Linux. Все приёмы проверены на боевых базах розничной сети.

Вступайте в нашу телеграмм-группу Инфостарт

расширение DESIGNER пакетный режим CheckModules DevOps автоматизация Linux Xvfb УТ 11.5 командная строка CI

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Интеграция Нейросети DevOps и автоматизация разработки Распознавание документов и образов 1C:ERP 1С:КА 1С:УНФ Химическая промышленность Горнодобывающая промышленность Металлургическая промышленность Россия Платные (руб)

От чертежа до себестоимости — за минуты, а не дни. ИИ-Технолог автоматически распознаёт чертежи и техническую документацию (включая фото, сканы, PDF, Excel), рассчитывает нормы времени, формирует технологические маршруты, оценивает возможность изготовления и точную себестоимость. Интеграция с 1С (ERP, MES, КА, УНФ) и отраслевыми нормативами (ГОСТы).

366000 руб.

18.06.2026    1268    0    2    

0

DevOps и автоматизация разработки Программист 1С:Предприятие 8 Бесплатно (free)

Технический разбор нашего конвейера разработки на 1С: песочницы, Gitea, сборка, проверки и CLI backend'ы. Основной CLI - cursor; также поддерживаются codex, claude и экспериментальный mimo.

16.06.2026    5152    Aleksandr    5    

8

DevOps и автоматизация разработки Программист Бесплатно (free)

Использование современных DevOps-практик в разработке и сопровождении активно внедряется в стек 1С. Мы в MagnitTech активно используем Docker, в том числе и для контейнеризации 1С-приложений, что позволяет ускорить развертывание, улучшить отказоустойчивость и упростить масштабирование. Рассмотрим лучшие практики создания Dockerfile и нюансы работы в контейнере для сервера приложений и сервера взаимодействия 1С – с какими сложностями мы столкнулись и как их преодолели.

26.05.2026    2961    daniloffartur    1    

5

DevOps и автоматизация разработки Программист Бесплатно (free)

Хватит ограничивать себя родным и уютным стеком 1С. Пора расширять кругозор и осваивать смежные стеки! Разберемся, как Docker может упростить жизнь одинэснику: от сборки и тестирования 1С до запуска инфраструктуры и автоматизации CI/CD, причем быстро, воспроизводимо и без лишнего мусора в системе.

08.05.2026    6015    sleemp    81    

37

DevOps и автоматизация разработки Программист Бесплатно (free)

Статья о том, как команда 1С смогла перейти от ручного управления к полноценной автоматизации, внедрив практики DevOps в среде 1С. Разбираем проблемы, которые мешали развиваться: медленный процесс командной разработки, отсутствие тестирования, длительные релизы, хаос с хотфиксами и ручные действия на каждом этапе. Объясняем, как внедренные решения – GitLab, Jenkins, автоматизированные пайплайны, тестовое окружение, стандарты разработки и тестирования – позволили масштабировать команду и повысить стабильность поставок.

14.04.2026    2551    Sicuro    4    

3

DevOps и автоматизация разработки Мониторинг Системный администратор Программист Бесплатно (free)

Практический гайд по применению DevOps-практик в 1С-инфраструктуре: контейнеризация СУБД, инфраструктура как код, мониторинг с алертами, автоматические бэкапы. Разбираю подводные камни и делюсь готовыми конфигами. Для 1С-разработчиков, которые хотят автоматизировать рутину и приблизиться к продакшен-среде.

06.04.2026    14399    vladimir-89    12    

33

DevOps и автоматизация разработки Программист Бесплатно (free)

Если вы думаете, что внедрение CDC конвейера — это геморрой, то вы правы. Но мы уже прошли через все боли: от настройки MSSQL CDC до танцев с Kafka и ClickHouse. Теперь конвейер работает и данные ключевых операций в 1С, от которых зависит бизнес, попадают в ClickHouse, где их можно анализировать и использовать для мониторинга в реальном времени. В этой статье я расскажу, как выглядит архитектура и с какими проблемами можно столкнуться

05.03.2026    2696    NesterTop1    4    

6
Для отправки сообщения требуется регистрация/авторизация