n8n на VPS в Docker: установка, домен, HTTPS, бэкап

Как поднять свой n8n на арендованном сервере по схеме из документации n8n: Docker из официального репозитория, Docker Compose с Traefik, который сам получает сертификат Let's Encrypt, данные в томе Docker, домен третьего уровня, копия базы и экспорт сценариев, обновление и разбор типичных ошибок. Ubuntu 24.04, сентябрь 2026.

Что получится и что понадобится

n8n будет открываться по своему адресу вида n8n.example.com по HTTPS, переживать перезагрузку сервера и хранить сценарии, учётные данные и историю запусков в томе Docker, который легко скопировать. Схема из документации n8n для своего сервера: два контейнера, n8n и Traefik. Traefik принимает соединения на 80 и 443 портах, сам запрашивает сертификат у Let's Encrypt и передаёт запросы в n8n. База данных — SQLite внутри n8n, для личных и небольших рабочих сценариев её хватает.

Понадобятся: сервер с Ubuntu 24.04, где сделаны первые шаги из инструкции про настройку VPS (пользователь с sudo, ключи, файрвол ufw); домен, у которого вы можете править DNS-записи; почта для уведомлений Let's Encrypt; час времени. Команды я сверял в сентябре 2026 с документацией Docker (установка на Ubuntu, тома) и n8n (Docker Compose на своём сервере, переменные окружения, резервное копирование). Домен и адреса в примерах условные.

Шаг 1. Docker из репозитория Docker

В Ubuntu есть пакет docker.io, но версия там отстаёт, а плагин compose в нём отдельный. Ставим движок из репозитория Docker, как советует его документация: сначала ключ и описание источника, потом сами пакеты. Блок ниже вставляется целиком.

sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Проверка: тестовый контейнер должен напечатать приветствие, а compose — показать версию.

sudo docker run --rm hello-world
docker compose version

Docker после установки из репозитория уже стартует вместе с системой. Своего пользователя можно добавить в группу docker, чтобы не писать sudo, но кто в этой группе, тот может на сервере всё то же, что root. На сервере, куда ходят по ключу только вы, это приемлемо; в инструкции ниже везде стоит sudo, так безопаснее.

Шаг 2. Домен и порты

У регистратора или в панели DNS создайте запись A: имя n8n, значение — IP-адрес сервера. Так адрес n8n.example.com будет указывать на ваш VPS. Записи расходятся от нескольких минут до часа, проверить можно с самого сервера.

getent hosts n8n.example.com

Пока команда молчит или показывает чужой адрес, дальше идти рано: Traefik не сможет получить сертификат. Заодно откройте в файрволе порты 80 и 443, оба нужны Let's Encrypt и браузеру. Порт 5678, на котором работает сам n8n, наружу не открывайте: в схеме ниже он привязан к 127.0.0.1.

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status

Если на сервере уже стоит nginx или apache, они занимают порт 80, и Traefik не запустится. Либо остановите их, либо ставьте n8n на отдельный сервер.

Шаг 3. Папка проекта, .env и compose.yaml

Всё живёт в одной папке: файл с переменными и описание контейнеров. Папка local-files пробрасывается внутрь n8n как /files, только в ней сценарии смогут читать и писать файлы на диске сервера.

mkdir -p ~/n8n-compose/local-files && cd ~/n8n-compose
tee .env > /dev/null <<'EOF'
DOMAIN_NAME=example.com
SUBDOMAIN=n8n
GENERIC_TIMEZONE=Europe/Moscow
SSL_EMAIL=you@example.com
EOF

Подставьте свой домен, поддомен из записи A и почту. Часовой пояс важен для узлов расписания: без него n8n считает, что живёт в Нью-Йорке, и запускает задачи со сдвигом. Файл compose.yaml — из документации n8n, без правок.

services:
  traefik:
    image: "traefik"
    restart: always
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
      - "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - traefik_data:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro

  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    labels:
      - traefik.enable=true
      - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
      - traefik.http.routers.n8n.tls=true
      - traefik.http.routers.n8n.entrypoints=web,websecure
      - traefik.http.routers.n8n.tls.certresolver=mytlschallenge
      - traefik.http.middlewares.n8n.headers.SSLRedirect=true
      - traefik.http.middlewares.n8n.headers.STSSeconds=315360000
      - traefik.http.middlewares.n8n.headers.browserXSSFilter=true
      - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
      - traefik.http.middlewares.n8n.headers.forceSTSHeader=true
      - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
      - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
      - traefik.http.middlewares.n8n.headers.STSPreload=true
      - traefik.http.routers.n8n.middlewares=n8n@docker
    environment:
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
      - TZ=${GENERIC_TIMEZONE}
      - N8N_RESTRICT_FILE_ACCESS_TO=/files
    volumes:
      - n8n_data:/home/node/.n8n
      - ./local-files:/files

volumes:
  n8n_data:
  traefik_data:

Строка --api.insecure=true включает панель Traefik на порту 8080, но порт наружу не проброшен, так что снаружи её нет; я бы её просто убрал, панель на сервере с одним сервисом ни разу не понадобилась. Обе строки с 5678 держат n8n на локальном адресе: в интернет смотрит только Traefik. WEBHOOK_URL задаёт адрес, под которым n8n видят снаружи, иначе вебхуки в редакторе будут показывать localhost и внешние сервисы не смогут их вызвать; с версии 2.35.0 переменная называется N8N_WEBHOOK_URL, старое имя пока принимается, но n8n пишет предупреждение в лог. Ключ шифрования учётных данных n8n создаст сам при первом запуске и положит в /home/node/.n8n внутри тома n8n_data, поэтому том нельзя удалять при обновлениях. Если хотите закрепить версию, замените image: n8nio/n8n на n8nio/n8n:<номер>, список тегов есть на Docker Hub.

Шаг 4. Запуск и первый вход

sudo docker compose up -d
sudo docker compose ps
sudo docker compose logs -f traefik

В ps оба контейнера должны быть в состоянии running. Traefik первые полминуты получает сертификат, в логе это строки со словом acme (так называется протокол запроса сертификата у Let's Encrypt); когда они закончатся без ошибок, откройте https://n8n.example.com в браузере. Пустой n8n предложит создать первого пользователя, он станет владельцем экземпляра. Логи n8n смотрят так же: sudo docker compose logs -f n8n, выход по Ctrl+C.

Если браузер показывает ошибку сертификата, почти всегда виноват один из трёх шагов выше: запись A ещё не разошлась, порт 80 или 443 закрыт файрволом (у некоторых хостеров есть ещё свой файрвол в панели), либо порт 80 занят другим веб-сервером. После исправления перезапустите Traefik: sudo docker compose restart traefik.

Шаг 5. Бэкап: том с базой и экспорт сценариев

Копировать нужно папку .n8n: в ней база SQLite и файл config с ключом шифрования. Без ключа восстановленная база бесполезна, учётные данные из неё не расшифровать. Папка лежит в томе n8n_data, значит копия тома — полный бэкап. Делать её лучше при остановленном n8n, чтобы не поймать базу посреди записи; для домашнего экземпляра пауза на полминуты ночью незаметна. Имя контейнера подставьте из docker compose ps, у папки n8n-compose оно будет n8n-compose-n8n-1.

cd ~/n8n-compose && mkdir -p backup
sudo docker compose stop n8n
sudo docker run --rm --volumes-from n8n-compose-n8n-1 -v "$PWD/backup":/backup ubuntu \
  tar czf /backup/n8n_data-$(date +%F).tgz -C /home/node/.n8n .
sudo docker compose start n8n

Архив в папке backup и есть бэкап. Копию храните не на этом же сервере: скачайте по scp или отправьте в объектное хранилище, иначе при потере VPS пропадут обе. Строку с tar можно положить в cron раз в сутки и заодно удалять архивы старше месяца.

Вторая, независимая копия — экспорт сценариев и учётных данных в JSON встроенной командой n8n. Он не заменяет копию тома, зато файлы читаемы и переносятся в другой экземпляр по одному. Пишем в /files, то есть в папку local-files на сервере.

sudo docker compose exec n8n n8n export:workflow --backup --output=/files/backup/workflows/
sudo docker compose exec n8n n8n export:credentials --backup --output=/files/backup/credentials/

Флаг --backup означает «все, по одному файлу на объект, читаемо». Учётные данные выгружаются зашифрованными тем же ключом; расшифрованный экспорт (--decrypted) делайте только если понимаете, что кладёте пароли в открытый файл. Обратно они грузятся командами n8n import:workflow --separate --input=/files/backup/workflows/ и n8n import:credentials с тем же ключом.

Восстановление на новом сервере: поставить Docker, положить ту же папку проекта с .env и compose.yaml, выполнить docker compose up -d, чтобы появились тома, сразу остановить n8n командой docker compose stop n8n, развернуть архив в том и снова запустить. Команда для тома та же, что при бэкапе, только tar xzf вместо czf. Полный цикл с переездом на другой сервер я не прогонял, порядок взят из документации n8n: остановить, вернуть папку .n8n, запустить.

Обновление и типичные ошибки

Обновление в три команды, перед ним — бэкап из шага 5. Тома при down не удаляются, данные остаются.

sudo docker compose pull
sudo docker compose down
sudo docker compose up -d

Your n8n server is configured to use a secure cookie. Так n8n отвечает, если открыть его не по HTTPS, например по http://IP:5678 с самого сервера. Заходите по домену; переменную N8N_SECURE_COOKIE=false ставить не надо, она снимает защиту.

Вебхук в редакторе начинается с http://localhost:5678. Не задан WEBHOOK_URL, или в .env ошибка в домене. Поправьте и перезапустите n8n: sudo docker compose up -d n8n.

Bind for 0.0.0.0:80 failed: port is already allocated. Порт 80 держит другой процесс, обычно nginx или apache. Найти его: sudo ss -ltnp | grep ':80 '.

unable to obtain ACME certificate в логе Traefik. Let's Encrypt не смог достучаться до сервера по домену, причины те же три, что в шаге 4. У Let's Encrypt есть лимит на неудачные попытки, после серии ошибок подождите час, прежде чем перезапускать Traefik снова.

EACCES: permission denied при записи в /files. Папка local-files принадлежит не тому пользователю, под которым работает контейнер (uid 1000). Лечится sudo chown -R 1000:1000 ~/n8n-compose/local-files.

Сценарий по расписанию сработал не в то время. Проверьте GENERIC_TIMEZONE в .env: часовой пояс по умолчанию America/New_York.

Какой сервер под это нужен

Для схемы из этой инструкции документация n8n требований к железу не называет. Полный официальный набор, который n8n ставит своим скриптом установки, добавляет песочницу для узла Code и встроенный поисковик для ИИ-помощника и просит 4 ГБ и 2 vCPU. Для двух контейнеров с SQLite я бы брал от 2 ГБ: на 1 ГБ Docker с n8n стартует, но первое же обновление образа или тяжёлый сценарий упрутся в память. В нашем каталоге на 21 сентября 2026 в России продаётся 190 помесячных Linux-тарифов без видеокарты у 11 провайдеров; с 2 ГБ памяти и больше — 168, самый дешёвый из них Selectel «VDS 1-2-25» за 250 ₽ (1 vCPU, 2 ГБ, 25 ГБ SSD); с 4 ГБ и больше — 127, самый дешёвый Selectel «VDS 2-4-50» за 650 ₽ (2 vCPU, 4 ГБ, 50 ГБ SSD), следом AdminVPS «Micro (3,6 ГГц)» за 799 ₽ с диском 60 ГБ NVMe. Сравнить всех провайдеров с такой конфигурацией можно на страницах «VPS 1 vCPU / 2 ГБ / 30 ГБ» и «VPS 2 vCPU / 4 ГБ / 50 ГБ» в каталоге.

инструкцииdockerавтоматизация

Сравнить тарифы VPS

Весь каталог с фильтрами и честной сортировкой — цены обновляются автоматически.

Открыть каталог →