Как сохранить n8n, чтобы восстановить автоматизации после потери VPS 列印

  • 0

Если VPS с n8n перестанет существовать, одних JSON-файлов автоматизаций может не хватить. Для восстановления нужны база данных, исходный ключ шифрования, файлы n8n и настройки запуска. Этот комплект должен храниться вне исходного VPS, а его пригодность проверяют запуском на другом сервере.

Ниже — порядок для n8n в Docker Compose с SQLite или PostgreSQL. Он предполагает окно остановки n8n на время создания согласованной копии. Для режима очередей с отдельными процессами исполнения — workers — и работы без перерыва потребуется расширить процедуру под вашу архитектуру.

Что сохранить вместе с автоматизациями

Workflow описывает шаги процесса. Credentials — сохранённые подключения к почте, CRM, базам данных и API. Они хранятся зашифрованными, поэтому восстановленная схема процесса ещё не означает, что он сможет выполнить свою работу.

Что сохранить Зачем это нужно
Полную базу SQLite или дамп PostgreSQL Workflows, credentials, пользователей, настройки и другие записи экземпляра n8n. Копирование отдельных таблиц может потерять связи между ними.
Каталог .n8n и действующий ключ шифрования В стандартном Docker-образе каталог находится в /home/node/.n8n. В нём могут находиться config с ключом, SQLite и локальные данные.
Compose-файл, .env, файлы secrets и настройки прокси Чтобы восстановить подключение к БД, домен, HTTPS, адреса вебхуков, часовой пояс и параметры запуска.
Файлы за пределами .n8n Каталоги, подключённые как /files, внешнее хранилище вложений, пользовательские узлы и другие зависимости автоматизаций.
Версии n8n, PostgreSQL, дополнительных узлов и собственные образы Чтобы сначала запустить прежнюю рабочую конфигурацию. Обновление одновременно с восстановлением усложняет поиск ошибок.

Для SQLite база обычно находится в /home/node/.n8n/database.sqlite. При PostgreSQL основная база расположена отдельно, но каталог .n8n всё равно нужно сохранить. Если менялись N8N_USER_FOLDER, пути файлового хранения или N8N_CUSTOM_EXTENSIONS, включите фактические каталоги в копию.

Для файлов в S3 или другом внешнем хранилище нужен собственный план резервирования. Ссылка на объект в базе не восстанавливает удалённый объект. Проверьте также настройки хранения истории: уже удалённые n8n данные выполнения не появятся в новой копии.

Как сохранить ключ шифрования и доступ к подключениям

При первом запуске n8n создаёт ключ шифрования и сохраняет его в файле config каталога .n8n, если ключ не задан настройкой N8N_ENCRYPTION_KEY. При восстановлении нужен именно тот ключ, с которым были сохранены credentials.

Пароль пользователя n8n, пароль PostgreSQL и ключ шифрования — разные вещи. Сброс пароля панели не исправит ошибку расшифровки подключений. Генерировать новый N8N_ENCRYPTION_KEY для старой базы тоже нельзя.

Если ключ задаётся через переменную окружения, сохраните его источник: защищённый .env, файл секрета или запись в менеджере секретов. Не рассчитывайте, что значение обязательно окажется в архиве каталога .n8n. В конфигурации восстановления не должно быть конфликта между сохранённым config и переменной окружения.

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

Если старый ключ уже потерян: проверьте прежние .env, менеджер секретов, копии config, сохранившиеся тома и снимки сервера. Если ключ найти не удалось, зашифрованные credentials придётся создать заново и повторно авторизовать интеграции. Новый ключ не расшифрует старые значения.

Сначала убедитесь, что нашли реальные данные n8n

На форуме n8n описан случай, когда пользователь сохранял каталог, подключённый к /root/.n8n, а приложение записывало данные в /home/node/.n8n внутри контейнера. Копии существовали, но содержали старую пустую базу. Автор подтвердил успешный перенос после исправления пути и копирования действующих данных.

В примерах ниже проект находится в /opt/n8n, сервис называется n8n, файлы конфигурации — compose.yaml и .env. Для варианта с PostgreSQL сервис БД называется postgres, база и пользователь — n8n. Это условные имена: замените их своими. Команды рассчитаны на стандартный путь /home/node/.n8n; если вы изменили его, подставьте фактический путь. Команды выполняются от root на VPS, в одной сессии Bash.

cd /opt/n8n
docker compose ps
docker compose exec -T n8n n8n --version
n8n_id="$(docker compose ps -q n8n)"
docker inspect "$n8n_id" --format '{{range .Mounts}}{{println .Type .Source "->" .Destination}}{{end}}'

В выводе найдите подключение к /home/node/.n8n. Оно покажет реальный том или каталог хоста. Если подключения нет, данные могут находиться в записываемом слое контейнера: не удаляйте контейнер до копирования и проверки восстановления.

В конфигурации запуска проверьте DB_TYPE: значение postgresdb означает PostgreSQL, sqlite — SQLite. При стандартной конфигурации без переопределения используется SQLite. Учитывайте настройки через файлы secrets, включая варианты переменных с окончанием _FILE.

Перед копированием проверьте свободное место: локально потребуется место для каталога данных и, при PostgreSQL, дампа. Зафиксируйте текущую версию n8n и замените плавающий тег latest точной версией в сохранённой конфигурации восстановления.

Как сделать согласованную копию

Выберите окно обслуживания и предусмотрите повторную доставку входящих событий на время остановки. Дождитесь завершения обычных выполняющихся задач. Ожидающие процессы с узлом Wait могут оставаться в базе; при восстановлении их нужно проверить отдельно.

Создайте каталог копии и сохраните конфигурацию. Если используются другие имена файлов, дополнительные Compose-файлы или секреты вне .env, добавьте их в комплект. Переходите к следующему этапу только после успешного выполнения команд.

umask 077
n8n_backup="/var/backups/n8n/$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -p "$n8n_backup/n8n-data"
cp -a compose.yaml .env "$n8n_backup/"
docker compose exec -T n8n n8n --version > "$n8n_backup/n8n-version.txt"
docker inspect "$n8n_id" --format '{{.Config.Image}} {{.Image}}' > "$n8n_backup/n8n-image.txt"

Остановите n8n и скопируйте весь каталог данных. PostgreSQL на этом этапе оставьте работающим.

docker compose stop -t 300 n8n
docker inspect "$n8n_id" --format '{{.State.Status}}'
docker cp -a "$n8n_id:/home/node/.n8n/." "$n8n_backup/n8n-data/"

Копируйте только после состояния exited. Ключ -a сохраняет владельцев файлов. Дополнительные каталоги и хранилища из первого раздела должны попасть в ту же точку восстановления, пока n8n не записывает новые данные.

Если используется SQLite. Вместе с базой сохраняйте имеющиеся файлы database.sqlite-wal и database.sqlite-shm. Не удаляйте их вручную: WAL может содержать уже подтверждённые изменения. Обычное копирование одного database.sqlite во время работы n8n не даёт надёжной копии.

Если на хосте установлен sqlite3, проверьте скопированную базу:

sqlite3 -readonly "$n8n_backup/n8n-data/database.sqlite" 'PRAGMA quick_check;'

Ожидаемый результат — ok. Ошибка открытия или другой результат требуют проверки пути и целостности. Эта команда проверяет структуру базы, но ещё не доказывает работоспособность автоматизаций.

Если используется PostgreSQL. Вместо копирования файлов работающей БД сделайте дамп. В примере подключение утилит к БД внутри контейнера уже настроено.

docker compose exec -T postgres pg_dump -U n8n -d n8n -Fc > "$n8n_backup/postgres.dump.tmp" &&
mv "$n8n_backup/postgres.dump.tmp" "$n8n_backup/postgres.dump"

docker compose exec -T postgres pg_restore --list < "$n8n_backup/postgres.dump" > /dev/null

Файл получает окончательное имя только после успешного pg_dump. Проверка через pg_restore --list должна завершиться без ошибки; она подтверждает чтение оглавления, а не полноценное восстановление. Зафиксируйте также версию PostgreSQL, например командой docker compose exec -T postgres postgres --version.

После копирования запустите исходный n8n:

docker compose start n8n
docker compose ps
docker compose logs --tail=50 n8n

Убедитесь, что контейнер работает без повторных перезапусков, панель открывается и контрольная автоматизация выполняется. Если на предыдущем этапе возникла ошибка, сначала верните исходный сервис в работу этой же командой запуска. Не считайте незавершённый комплект пригодным для восстановления.

Как вынести копию за пределы VPS

Каталог /var/backups/n8n на том же VPS — только промежуточная копия. При удалении сервера он исчезнет вместе с данными. Снапшот провайдера полезен для быстрого отката, но дополнительно нужен комплект, который можно получить независимо от исходного VPS.

Один из вариантов — restic: он сохраняет зашифрованные копии во внешнем репозитории. Ниже пример для отдельного SFTP-сервера. До выполнения должны быть установлены restic, настроен доступ по SSH и подготовлен каталог, доступный пользователю backup.

export RESTIC_REPOSITORY='sftp:backup@backup.example:/srv/restic/n8n'
restic init

Замените адрес и путь своими. restic init выполняется один раз для нового репозитория. Пароль шифрования сохраните в менеджере паролей вне VPS. Доступ к удалённому хранилищу тоже должен восстанавливаться без исходного сервера.

Отправьте подготовленный комплект:

restic backup "$n8n_backup" --tag n8n &&
restic snapshots --tag n8n

Успешный backup завершается кодом 0. Проверьте дату, путь и идентификатор новой копии. Наличие записи в списке само по себе недостаточно: при ошибках чтения restic может создать неполный снимок и вернуть ненулевой код.

Периодически проверяйте содержимое репозитория:

restic check --read-data

Команда читает все сохранённые блоки, поэтому учитывайте время и трафик. Даже успешная проверка restic не заменяет запуск восстановленного n8n.

В комплекте находятся ключи, токены и данные клиентов. Не помещайте его в публичный Git или веб-каталог. Локальные промежуточные копии тоже занимают место и содержат секреты: после проверки внешней копии удаляйте их по установленному сроку хранения.

Что даёт JSON-экспорт и чего в нём нет

Экспорт workflows полезен как дополнительная копия логики: отдельный процесс проще посмотреть или перенести. CLI-экспорт workflows и credentials не сохраняет весь экземпляр n8n — например, пользователей, полную историю выполнений и ключ шифрования.

Если делаете такой экспорт, сохраняйте workflows и credentials в разные каталоги. В GitHub Issues описана ошибка импорта credentials из общей папки с файлами workflows; автор воспроизвёл её на версиях 2.36.8 и 2.37.9. Раздельные каталоги рекомендованы и в актуальной документации.

Зашифрованному экспорту credentials потребуется исходный ключ. Режим --decrypted записывает секреты открытым текстом и не нужен для обычной полной копии. Восстановление из JSON также требует проверить владельцев и проекты, ссылки на credentials и вызываемые подпроцессы.

Не полагайтесь только на workflow, который «сохраняет n8n из самого n8n»: при остановке приложения такая копия тоже перестанет выполняться.

Как восстановить n8n на чистом сервере

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

1. Получите комплект из внешнего хранилища. На новом сервере настройте доступ к тому же репозиторию restic и выберите конкретный снимок:

restic snapshots --tag n8n
restic restore SNAPSHOT_ID --target /srv/n8n-restore

Вместо SNAPSHOT_ID укажите идентификатор выбранной копии. Restic сохраняет структуру путей, поэтому комплект из примера окажется в /srv/n8n-restore/var/backups/n8n/ДАТА_КОПИИ/.

2. Верните конфигурацию. Установите Docker Compose, подготовьте каталог проекта, скопируйте сохранённые Compose-файлы, .env и остальные секреты. Используйте сохранённые версии n8n и PostgreSQL. Восстановите дополнительные файлы и зависимости, а подключения направьте на тестовые ресурсы.

В разделе volumes сервиса n8n проверьте постоянное хранение каталога данных. Для стандартного пути запись может выглядеть как n8n_data:/home/node/.n8n, где n8n_data — объявленный в Compose именованный том. Если в старой конфигурации был ошибочный путь /root/.n8n, исправьте его перед восстановлением.

3. Верните данные до запуска приложения. В следующем примере переменная n8n_restore должна содержать реальный путь к распакованному комплекту:

n8n_restore='/srv/n8n-restore/var/backups/n8n/ДАТА_КОПИИ'
cd /opt/n8n
docker compose create n8n
n8n_restore_id="$(docker compose ps -aq n8n)"
docker cp -a "$n8n_restore/n8n-data/." "$n8n_restore_id:/home/node/.n8n/"

Для SQLite база уже находится в восстановленном каталоге. Для PostgreSQL дополнительно запустите только БД, дождитесь её готовности и загрузите дамп в пустую базу:

docker compose up -d postgres
docker compose exec -T postgres pg_isready -U n8n -d n8n

docker compose exec -T postgres pg_restore \
  --exit-on-error --single-transaction --no-owner --no-privileges \
  -U n8n -d n8n < "$n8n_restore/postgres.dump"

Продолжайте только после готовности PostgreSQL и успешного завершения pg_restore. Команда рассчитана на отдельную БД n8n, где пользователь n8n владеет восстанавливаемыми объектами. Нестандартные роли и права доступа нужно восстановить отдельно.

4. Отключите автоматические запуски в тестовой копии. В n8n 2.x до запуска основного сервиса снимите публикацию workflows через CLI:

docker compose run --rm --no-deps n8n unpublish:workflow --all

Для старых версий 1.x используется update:workflow --all --active=false; выбирайте команду по сохранённой версии. Ожидающие выполнения и задания очереди проверяются отдельно: снятие публикации не следует считать защитой от всех возможных повторов. Сетевую изоляцию пока сохраняйте.

5. Запустите экземпляр и проверьте его.

docker compose up -d n8n
docker compose logs --tail=100 n8n

Если вместо прежнего входа появилась регистрация владельца, остановитесь и проверьте подключённую базу, путь к тому и настройки БД. Если credentials не расшифровываются — проверьте исходный ключ и его источник. При EACCES сравните владельца и права восстановленных файлов с пользователем контейнера; выдавать всему каталогу права 777 не нужно.

Как проверить, что восстановлены именно автоматизации

Сначала откройте Overview → Executions → Filters и просмотрите состояния Waiting, Running и Failed. Сверьте связанные заказы, письма и записи с внешними системами. Не запускайте массовый повтор ошибок: часть действий могла уже выполниться до аварии или перед остановкой восстановленной задачи.

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

  • Вебхук: отправьте тестовое событие из внешней системы, найдите выполнение в n8n и проверьте результат в целевой системе.
  • Подключения: выполните безопасное чтение через credentials. Для OAuth проверьте действительность токенов и при необходимости повторите авторизацию.
  • Расписание: проверьте часовой пояс и фактическое срабатывание тестовой копии по времени.
  • Файлы: прочитайте и обработайте сохранённое вложение; наличие записи в истории не доказывает доступность самого файла.
  • Подпроцессы и дополнительные узлы: проверьте вызываемые workflows, установленные пакеты и нужные файлы или библиотеки.

После этого перезагрузите тестовый VPS и повторите контрольный запуск. Так проверяются автозапуск Docker, доступность БД и сохранность данных после перезагрузки.

Для возврата в работу восстановите исходный комплект заново, чтобы не переносить изменения тестовой проверки. До запуска приложения снова отключите публикацию workflows командой из шага 4; сохраняйте ограничения на рабочие интеграции, пока не проверите ожидающие выполнения. Верните рабочий домен и HTTPS, проверьте WEBHOOK_URL, адрес редактора, OAuth redirect URL и списки разрешённых IP у внешних сервисов. Если меняется только IP, обновите нужные записи DNS.

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

Как часто сохранять n8n и что останется за пределами копии

Частота зависит от допустимой потери данных. При одной копии в сутки можно потерять почти сутки изменений. Для часто меняющихся процессов нужны более частые копии; отдельно сохраняйтесь перед обновлением n8n, изменением узлов и параметров шифрования.

Храните несколько поколений. Например, 7 ежедневных и 4 еженедельных копии — отправная точка для небольшого проекта, если хватает места. Это позволяет вернуться к состоянию до ошибки, которую обнаружили не сразу.

После ручной проверки автоматизируйте последовательность через cron или systemd: согласованная локальная копия, проверка, запуск n8n, отправка во внешнее хранилище. Скрипт должен возвращать ошибку при сбое любого этапа и возвращать исходный сервис в работу после неудачного копирования. Для restic можно использовать защищённый файл пароля через RESTIC_PASSWORD_FILE; его резервная копия должна храниться отдельно от VPS.

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

Копия не гарантирует повторную доставку событий, пропущенных во время аварии. Для важных процессов заранее предусмотрите повторную отправку и защиту от дублей по идентификатору события. В режиме очередей отдельно согласуйте восстановление PostgreSQL, Redis, workers и внешних файлов; простое повторное включение очереди может повторить уже выполненные операции.

Для восстановления подойдёт новый сервер с достаточным местом под базу, файлы и временную распаковку. На странице VPS HSTQ можно подобрать конфигурацию для n8n и тестового восстановления. Внешнее хранилище копий и его доступность при потере рабочего VPS планируйте отдельно — они должны оставаться доступными независимо от него.


這篇文章有幫助嗎?

« 返回

知識庫