Self-hosted n8n: полное руководство по установке на VPS
Личная история: почему я ушёл от облака
Первые 8 месяцев я работал на n8n Cloud. Всё было прекрасно: зашёл, зарегистрировался, через 5 минут уже собирал workflow. Никаких серверов, никаких SSL, никаких обновлений — просто работа.
А потом мои workflow’ы выросли. Я подключил 15 интеграций, настроил 40 автоматизаций, и мой план за $20 перестал хватать. Счёт вырос до $60, потом до $120. Я посчитал: за год это $1 440. При этом сервер мне нужен был ненамного мощнее базового.
Взял VPS за $12 в месяц, потратил вечер на настройку — и получил такой же функционал. Через год разница: $1 440 vs $144. Экономия $1 300+. Но главное не только деньги. Self-hosted даёт полный контроль: свои бэкапы, свои интеграции, никаких лимитов на execution time.
В этой статье пошагово покажу, как поднять собственный n8n на VPS. Без воды, только рабочие команды и проверенные конфиги.
Self-hosted vs Cloud: когда что выбирать
Cloud подходит, если:
- Ты только начинаешь и хочешь попробовать
- Нет времени/желания разбираться с серверами
- Нужна максимальная стабильность без усилий
- Workflow критичные, downtime недопустим
- Команда без DevOps-навыков
Self-hosted выигрывает, когда:
- Есть опыт работы с Linux/Docker
- Нужно сэкономить на больших объёмах
- Требуется кастомизация (свои ноды, свои лимиты)
- Есть требования к локации данных (GDPR и пр.)
- Хочется полного контроля над инфраструктурой
Мой путь: начал с Cloud, через 8 месяцев перешёл на self-hosted. Если бы начинал сейчас — сразу бы пошёл self-hosted на минимальном VPS, а по росту масштабировал.
Требования к серверу
Минимальные (для 1-2 человек, до 10 000 операций в день):
- CPU: 1 vCPU
- RAM: 2 GB
- Диск: 20 GB SSD
- ОС: Ubuntu 20.04/22.04 LTS
- Цена: $5-8/мес
Рекомендуемые (для команды, до 100 000 операций):
- CPU: 2 vCPU
- RAM: 4 GB
- Диск: 40 GB SSD
- Цена: $12-20/мес
Для production с высокой нагрузкой:
- CPU: 4+ vCPU
- RAM: 8+ GB
- Диск: 100 GB SSD
- Redis для очередей
- Цена: $40-80/мес
Я использую DigitalOcean Droplet за $12/мес (2 vCPU, 2 GB RAM) — хватает для 50+ workflow и ~50 000 операций в день.
Шаг 1: Подготовка сервера
Создание VPS
Регистрируемся на DigitalOcean, Hetzner, AWS или любом другом провайдере. Создаём дроплет с Ubuntu 22.04.
Базовая настройка безопасности
Подключаемся по SSH:
ssh root@YOUR_SERVER_IP
Обновляем систему:
apt update && apt upgrade -y
Создаём пользователя (не работаем под root!):
adduser n8n usermod -aG sudo n8n su - n8n
Настраиваем SSH-ключи:
mkdir ~/.ssh chmod 700 ~/.ssh # Копируем публичный ключ с локальной машины nano ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys
Отключаем root-логин и парольную аутентификацию:
sudo nano /etc/ssh/sshd_config
Меняем:
PermitRootLogin no PasswordAuthentication no
Перезапускаем SSH:
sudo systemctl restart sshd
Устанавливаем fail2ban:
sudo apt install fail2ban -y sudo systemctl enable fail2ban
Шаг 2: Установка Docker и Docker Compose
Устанавливаем Docker:
# Удаляем старые версии sudo apt remove docker docker-engine docker.io containerd runc # Устанавливаем зависимости sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release -y # Добавляем GPG ключ Docker curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # Добавляем репозиторий echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # Устанавливаем sudo apt update sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y # Добавляем пользователя в группу docker sudo usermod -aG docker $USER newgrp docker
Проверяем:
docker --version docker compose version
Шаг 3: Настройка домена и DNS
Покупаем домен (например, на Namecheap или Cloudflare). Добавляем A-запись:
Type: A Name: n8n Value: YOUR_SERVER_IP TTL: Auto
Проверяем, что домен резолвится:
nslookup n8n.yourdomain.com
Настоятельно рекомендую Cloudflare — бесплатный SSL, защита от DDoS, кэширование.
Шаг 4: Установка n8n через Docker Compose
Создаём директорию:
mkdir -p ~/n8n && cd ~/n8n
Создаём файл docker-compose.yml:
version: '3.8' services: n8n: image: n8nio/n8n:latest restart: always ports: - "127.0.0.1:5678:5678" environment: - N8N_BASIC_AUTH_ACTIVE=true - N8N_BASIC_AUTH_USER=your_username - N8N_BASIC_AUTH_PASSWORD=your_strong_password - N8N_HOST=n8n.yourdomain.com - N8N_PORT=5678 - N8N_PROTOCOL=https - WEBHOOK_URL=https://n8n.yourdomain.com/ - GENERIC_TIMEZONE=Europe/Moscow volumes: - ~/.n8n:/home/node/.n8n - /etc/localtime:/etc/localtime:ro
Важные моменты: — 127.0.0.1:5678 — n8n доступен только локально, nginx будет проксировать снаружи — Меняем your_username и your_strong_password на свои — Указываем правильный часовой пояс
Запускаем:
docker compose up -d
Проверяем статус:
docker compose ps docker compose logs -f
Шаг 5: Настройка nginx и SSL через Let’s Encrypt
Устанавливаем nginx:
sudo apt install nginx -y
Создаём конфиг:
sudo nano /etc/nginx/sites-available/n8n
server { listen 80; server_name n8n.yourdomain.com; location / { proxy_pass http://127.0.0.1:5678; proxy_set_header Connection ''; proxy_http_version 1.1; chunked_transfer_encoding off; proxy_buffering off; proxy_cache off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
Активируем:
sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx
Устанавливаем Certbot:
sudo apt install certbot python3-certbot-nginx -y sudo certbot --nginx -d n8n.yourdomain.com
Выбираем redirect HTTP to HTTPS. Проверяем автообновление:
sudo certbot renew --dry-run
Теперь n8n доступен по https://n8n.yourdomain.com с валидным SSL.
Шаг 6: Настройка бэкапов
Автоматический бэкап данных n8n
Создаём скрипт:
mkdir -p ~/backups nano ~/backup-n8n.sh
#!/bin/bash DATE=$(date +%Y%m%d_%H%M%S) BACKUP_DIR="$HOME/backups" N8N_DIR="$HOME/.n8n" # Останавливаем n8n cd ~/n8n && docker compose stop # Архивируем tar -czf "$BACKUP_DIR/n8n_backup_$DATE.tar.gz" -C "$N8N_DIR" . # Запускаем n8n cd ~/n8n && docker compose start # Удаляем старые бэкапы (оставляем последние 7) ls -t "$BACKUP_DIR"/n8n_backup_*.tar.gz | tail -n +8 | xargs rm -f echo "Backup completed: n8n_backup_$DATE.tar.gz"
Делаем исполняемым:
chmod +x ~/backup-n8n.sh
Добавляем в cron (каждый день в 3 ночи):
crontab -e
0 3 * * * /home/n8n/backup-n8n.sh >> /home/n8n/backups/backup.log 2>&1
Бэкап в облако (опционально)
Отправляем бэкапы в S3:
# Устанавливаем AWS CLI sudo apt install awscli -y aws configure # Добавляем в скрипт бэкапа aws s3 cp "$BACKUP_DIR/n8n_backup_$DATE.tar.gz" s3://your-backup-bucket/n8n/
Шаг 7: Настройка обновлений
Обновление n8n:
cd ~/n8n # Бэкап перед обновлением ~/backup-n8n.sh # Обновляем образ docker compose pull # Перезапускаем docker compose up -d # Очищаем старые образы docker image prune -f
Автоматические обновления (осторожно!)
Для production лучше обновлять вручную после тестирования. Но если хочется автоматики:
# Каждое воскресенье в 4 утра 0 4 * * 0 cd /home/n8n/n8n && docker compose pull && docker compose up -d && docker image prune -f
Типичные ошибки и их решение
Ошибка: «Connection refused» при обращении к webhook
Проверяйте, что WEBHOOK_URL установлен правильно в docker-compose.yml. Должен включать домен и заканчиваться слешем.
Ошибка: 502 Bad Gateway от nginx
n8n ещё не запустился или упал. Проверьте:
docker compose logs
Ошибка: SSL не работает
Убедитесь, что домен резолвится на IP сервера. Let’s Encrypt не выдаст сертификат, если не может достучаться до сервера.
Ошибка: Permission denied на volumes
n8n в Docker работает от пользователя node (UID 1000). Убедитесь, что владелец директории ~/.n8n — правильный:
sudo chown -R 1000:1000 ~/.n8n
Ошибка: Out of memory
Добавьте swap:
sudo fallocate -l 2G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Ошибка: Webhook URL генерируется с localhost
Проверьте, что N8N_HOST и WEBHOOK_URL установлены в environment docker-compose.
Производственная настройка
Для production добавьте:
1. Мониторинг
Uptime Kuma или аналог для отслеживания доступности:
docker run -d --restart unless-stopped -p 3001:3001 -v uptime-kuma:/app/data --name uptime-kuma louislam/uptime-kuma:1
2. Логирование
Настройте ротацию логов Docker:
sudo nano /etc/docker/daemon.json
{ "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }
3. Файрвол
sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow ssh sudo ufw allow http sudo ufw allow https sudo ufw enable
4. Двухфакторная аутентификация
В настройках n8n включите 2FA после первого входа.
FAQ
Сколько стоит полноценная self-hosted установка?
Минимум: $5/мес за VPS + $10/год за домен = $70/год. Сравните с $240/год за базовый Cloud план. Экономия очевидна при любой нагрузке.
Можно ли использовать один сервер для n8n и других проектов?
Можно, но осторожно. n8n может потреблять много ресурсов при тяжёлых workflow. Я рекомендую отдельный VPS для production n8n.
Как мигрировать с Cloud на self-hosted?
В Cloud: Settings → Export → Download. На self-hosted: Settings → Import. Все workflow перенесутся, но credentials придётся создать заново (это безопасность).
Что если сервер упадёт?
Настройте мониторинг с уведомлениями. Держите актуальные бэкапы. Для критичных систем — настройте резервный сервер.
Нужен ли CDN?
Для n8n CDN не критичен — трафик небольшой, пользователи обычно в одном регионе. Но если используете Cloudflare для DNS, бесплатное кэширование не помешает.
Можно ли ограничить доступ по IP?
Да, в nginx добавьте:
allow YOUR_OFFICE_IP; deny all;
Как обновить базовую авторизацию?
Измените в docker-compose.yml, затем:
docker compose up -d
Что делать, если забыл пароль?
Остановите n8n, удалите базу SQLite (или отредактируйте), запустите заново. Или создайте нового пользователя через CLI внутри контейнера.
Можно ли использовать PostgreSQL вместо SQLite?
Да, для production с большой нагрузкой рекомендуется:
services: postgres: image: postgres:15 environment: - POSTGRES_USER=n8n - POSTGRES_PASSWORD=password - POSTGRES_DB=n8n volumes: - postgres_data:/var/lib/postgresql/data n8n: # ... environment: - DB_TYPE=postgresdb - DB_POSTGRESDB_HOST=postgres - DB_POSTGRESDB_DATABASE=n8n - DB_POSTGRESDB_USER=n8n - DB_POSTGRESDB_PASSWORD=password
Как масштабировать при росте нагрузки?
- Вертикально: увеличьте ресурсы VPS
- Горизонтально: настройте режим queue с Redis и несколькими воркерами (см. официальную документацию n8n)
