SQLite на Linux: когда переменные окружения не спасают

Деплой SQLite: когда переменные окружения предают в самый ответственный момент
Проект ai-agents-bot-social-publisher стоял на пороге боевого выпуска. Восемь n8n-воркфлоу, которые собирают посты из социальных сетей и сортируют их по категориям, прошли все локальные тесты с честью. Команда была уверена — завтра деплоим на Linux-сервер, и всё заживёт.
Реальность оказалась жестче. Первая же волна логов после развёртывания завалила ошибку: no such table: users. Все SQLite-ноды в воркфлоу панически искали базу по пути C:\projects\ai-agents\admin-agent\database\admin_agent.db. Классический Windows-путь. На Linux-сервере, разумеется, такого ничего не было.
Элегантное решение, которое не выжило встречи с реальностью
Первый инстинкт был логичен: использовать переменные окружения и выражения n8n. Добавили DATABASE_PATH=/data/admin_agent.db в docker-compose.yml, развернули воркфлоу с выражением $env.DATABASE_PATH в конфиге SQLite-ноды и нажали кнопку деплоя. Ничего не изменилось — всё падало с той же ошибкой.
Потом выяснилось неприятное: в n8n v2.4.5 таск-раннер не передавал переменные окружения в SQLite-ноду так, как обещала документация. Выражение красиво сохранялось в конфигурации, но при реальном выполнении система всё равно искала исходный Windows-путь. Красивое решение встретилось с суровой реальностью и проиграло.
Скучный способ, который работает
Пришлось отказаться от элегантности в пользу надёжности. Решение оказалось неожиданно простым: string replacement при деплое. Написал скрипт deploy/deploy-n8n.js, который перехватывает JSON каждого воркфлоу перед загрузкой на сервер и заменяет все $env.DATABASE_PATH на реальный путь /var/lib/n8n/data/admin_agent.db. Скучно? Абсолютно. Но работает.
Здесь же обнаружилась вторая подводная скала: n8n хранит две версии каждого воркфлоу. Stored-версия живёт в базе данных, active-версия загружена в памяти и реально выполняется. Когда обновляешь воркфлоу через API, обновляется только хранилище. Active может остаться со старыми параметрами. Спасение простое: после обновления конфига явно деактивировать и активировать воркфлоу.
К этому добавили инициализацию SQLite. Скрипт копирует на сервер SQL-миграции (schema.sql, seed_questions.sql) и выполняет их через n8n API перед активацией воркфлоу. Выглядит как излишество, но спасает в будущем — когда потребуется добавить колонку в таблицу users, просто добавляешь новую миграцию без полного пересоздания БД.
Итог
Теперь весь деплой — одна команда: node deploy/deploy-n8n.js --env .env.deploy. Воркфлоу создаются с правильными путями, база инициализируется, всё работает. Главный урок: не полагайся на runtime-выражения в критических параметрах конфигурации. Лучше заранее знать точное место и подставить путь при развёртывании. Скучно, но надёжно.
— Ну что, SQLite, теперь ты найдёшь свою базу? — спросил я у логов. SQLite ответил тишиной успеха. 😄
Метаданные
- Session ID:
- grouped_C--projects-bot-social-publisher_20260207_1903
- Branch:
- main
- Dev Joke
- Если Playwright работает — не трогай. Если не работает — тоже не трогай, станет хуже.
Часть потока:
Разработка: C--projects-bot-social-publisher