Deploy n8n workflow automation tool on a single AWS EC2 instance with enterprise-grade security, monitoring, and flexibility for both development and production environments.
- π― Overview
- β¨ Features
- ποΈ Architecture
- π Prerequisites
- β‘ Quick Start
- π§ Configuration
- π Deployment Options
- π Monitoring & Management
- π Security
- πΎ Backup & Recovery
- π οΈ Maintenance
- π Documentation
- β Troubleshooting
- π€ Contributing
This project provides a complete, production-ready n8n deployment on a single AWS EC2 instance using Ansible automation. It supports both development (IP-based HTTP) and production (domain-based HTTPS) environments with comprehensive monitoring, security, and backup solutions.
- IP-based:
http://demo-ip:5678
(Development) - Domain-based:
https://n8n.demo.com
(Production)
- π IP-based HTTP: Quick setup for development/testing
- π Domain-based HTTPS: Production-ready with SSL certificates
- Let's Encrypt SSL certificates with auto-renewal
- UFW firewall + Fail2ban intrusion prevention
- PostgreSQL with SCRAM-SHA-256 authentication
- Redis with password protection
- Security headers and rate limiting
- Prometheus metrics collection
- Grafana dashboards and alerting
- System health monitoring
- Automated health checks
- Automated daily backups
- S3 integration support
- Point-in-time recovery
- Configuration backup
- One-command deployment
- Automated service management
- Health monitoring scripts
- Maintenance utilities
graph TB
subgraph "EC2 Instance"
subgraph "Web Layer"
nginx[Nginx Proxy<br/>Ports 80/443]
end
subgraph "Application Layer"
n8n[n8n Workflows<br/>Port 5678]
pm2[PM2 Process Manager]
end
subgraph "Data Layer"
postgres[(PostgreSQL<br/>Port 5432)]
redis[(Redis<br/>Port 6379)]
end
subgraph "Monitoring Layer"
prometheus[Prometheus<br/>Port 9090]
grafana[Grafana<br/>Port 3000]
nodeexp[Node Exporter<br/>Port 9100]
end
subgraph "Management Layer"
pgadmin[pgAdmin<br/>Port 8080]
end
end
internet[Internet] --> nginx
nginx --> n8n
nginx --> grafana
nginx --> prometheus
nginx --> pgadmin
n8n --> postgres
n8n --> redis
pm2 --> n8n
prometheus --> nodeexp
prometheus --> n8n
π Detailed Architecture: See docs/ARCHITECTURE.md
Component | Minimum | Recommended |
---|---|---|
EC2 Instance | t3.medium | t3.large |
RAM | 4 GB | 8 GB |
Storage | 20 GB | 50 GB |
OS | Ubuntu 22.04 LTS | Ubuntu 22.04 LTS |
- β SSH access to EC2 instance
- β Sudo privileges on the instance
- β Domain name (optional, for HTTPS setup)
- β AWS CLI configured (optional, for S3 backups)
π§ Ubuntu/Debian
# Update package index
sudo apt update
# Install Ansible
sudo apt install ansible -y
# Verify installation
ansible --version
π macOS
# Using Homebrew
brew install ansible
# Using pip
pip3 install ansible
# Verify installation
ansible --version
πͺ Windows
# Using WSL2 (Recommended)
wsl --install
# Then follow Ubuntu instructions
# Using pip
pip install ansible
# Verify installation
ansible --version
# Install community collections
ansible-galaxy collection install community.general
ansible-galaxy collection install community.postgresql
ansible-galaxy collection install community.grafana
# Using AWS CLI (optional)
aws ec2 run-instances \
--image-id ami-0c02fb55956c7d316 \
--instance-type t3.medium \
--key-name your-key-pair \
--security-group-ids sg-xxxxxxxxx \
--subnet-id subnet-xxxxxxxxx \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=n8n-server}]'
Type | Protocol | Port Range | Source | Description |
---|---|---|---|---|
SSH | TCP | 22 | Your IP | SSH access |
HTTP | TCP | 80 | 0.0.0.0/0 | HTTP traffic |
HTTPS | TCP | 443 | 0.0.0.0/0 | HTTPS traffic |
Custom | TCP | 3000 | Your IP | Grafana (IP mode) |
Custom | TCP | 5678 | Your IP | n8n (IP mode) |
Custom | TCP | 8080 | Your IP | pgAdmin (IP mode) |
Custom | TCP | 9090 | Your IP | Prometheus (IP mode) |
Set up A records pointing to your EC2 instance:
n8n.yourdomain.com β your-ec2-ip
grafana.yourdomain.com β your-ec2-ip
prometheus.yourdomain.com β your-ec2-ip
pgadmin.yourdomain.com β your-ec2-ip
# 1. Clone the repository
git clone https://github.com/indranandjha1993/ec2-n8n-automation.git
cd ec2-n8n-automation
# 2. Make deployment script executable
chmod +x scripts/deploy.sh
# 3. Run interactive deployment
./scripts/deploy.sh
The script will guide you through:
- β Deployment type selection (IP vs Domain)
- β Target host configuration
- β Domain setup (if applicable)
- β Email configuration
- β SSH key selection
π IP-based Deployment (Development)
# Quick IP-based deployment
./scripts/deploy.sh \
--type ip \
--host your-ec2-ip \
--user ubuntu \
--key ~/.ssh/your-key.pem \
--email admin@example.com \
--yes
Access URLs:
- n8n:
http://your-ec2-ip:5678
- Grafana:
http://your-ec2-ip:3000
- Prometheus:
http://your-ec2-ip:9090
- pgAdmin:
http://your-ec2-ip:8080
π Domain-based Deployment (Production)
# Production domain-based deployment
./scripts/deploy.sh \
--type domain \
--domain yourdomain.com \
--host your-ec2-ip \
--user ubuntu \
--key ~/.ssh/your-key.pem \
--email admin@yourdomain.com \
--yes
Access URLs:
- n8n:
https://n8n.yourdomain.com
- Grafana:
https://grafana.yourdomain.com
- Prometheus:
https://prometheus.yourdomain.com
- pgAdmin:
https://pgadmin.yourdomain.com
- π Prerequisites Check: Validates Ansible, SSH connectivity
- π οΈ System Setup: Updates packages, installs dependencies
- ποΈ Database Setup: Installs and configures PostgreSQL
- π Cache Setup: Installs and configures Redis
- βοΈ n8n Installation: Installs n8n with PM2 process manager
- π Proxy Setup: Configures Nginx with SSL (if domain-based)
- π Monitoring Setup: Installs Prometheus, Grafana, exporters
- π Security Hardening: Configures firewall, fail2ban
- πΎ Backup Setup: Configures automated backups
- β Health Checks: Verifies all services are running
-
Copy Example Configuration:
cp inventory/group_vars/all.yml.example inventory/group_vars/all.yml
-
Edit Configuration:
nano inventory/group_vars/all.yml
π Deployment Settings
# Deployment type: 'ip' or 'domain'
deployment_type: "ip"
# Domain name (required for domain-based deployment)
domain_name: "yourdomain.com"
# Admin email for SSL certificates and notifications
admin_email: "admin@yourdomain.com"
π Application Settings
n8n:
version: latest # n8n version
port: 5678 # Application port
log_level: info # Logging level
timezone: UTC # Application timezone
basic_auth:
enabled: true # Enable basic authentication
user: "admin" # Username
password: "" # Auto-generated if empty
ποΈ Database Settings
postgresql:
version: 14 # PostgreSQL version
port: 5432 # Database port
database: n8n # Database name
user: n8n # Database user
password: "" # Auto-generated if empty
max_connections: 100 # Max connections
π Security Settings
security:
ufw_enabled: true # Enable UFW firewall
fail2ban_enabled: true # Enable fail2ban
ssh_port: 22 # SSH port
max_login_attempts: 5 # Max failed login attempts
ban_time: 3600 # Ban duration in seconds
π Monitoring Settings
monitoring:
prometheus:
port: 9090 # Prometheus port
retention: 15d # Data retention period
grafana:
port: 3000 # Grafana port
admin_user: admin # Admin username
admin_password: "" # Auto-generated if empty
π Complete Configuration Reference: See docs/CONFIGURATION.md
π Step-by-Step Manual Deployment
-
Configure Inventory:
# Edit inventory file nano inventory/hosts.yml
--- all: children: n8n_servers: hosts: n8n-server: ansible_host: "your-ec2-ip" ansible_user: "ubuntu" ansible_ssh_private_key_file: "~/.ssh/your-key.pem"
-
Test Connectivity:
ansible all -i inventory/hosts.yml -m ping
-
Run Deployment:
# IP-based deployment ansible-playbook -i inventory/hosts.yml playbooks/deploy-n8n.yml \ -e deployment_type=ip \ -e admin_email=admin@example.com # Domain-based deployment ansible-playbook -i inventory/hosts.yml playbooks/deploy-n8n.yml \ -e deployment_type=domain \ -e domain_name=yourdomain.com \ -e admin_email=admin@yourdomain.com
π§ Custom Variables
# Deploy with custom settings
ansible-playbook -i inventory/hosts.yml playbooks/deploy-n8n.yml \
-e deployment_type=domain \
-e domain_name=example.com \
-e n8n_version=1.0.0 \
-e postgresql_version=15 \
-e backup_enabled=true \
-e backup_s3_bucket=my-backup-bucket
π·οΈ Tag-based Deployment
# Deploy only specific components
ansible-playbook -i inventory/hosts.yml playbooks/deploy-n8n.yml \
--tags "common,postgresql,n8n"
# Skip specific components
ansible-playbook -i inventory/hosts.yml playbooks/deploy-n8n.yml \
--skip-tags "monitoring,ssl"
Available tags:
common
- System setup and dependenciespostgresql
- Database installationredis
- Cache installationn8n
- Application installationnginx
- Proxy configurationssl
- SSL certificate setupmonitoring
- Monitoring stacksecurity
- Security hardening
Service | IP-based Access | Domain-based Access | Default Credentials |
---|---|---|---|
n8n | http://ip:5678 |
https://n8n.domain.com |
admin / [generated] |
Grafana | http://ip:3000 |
https://grafana.domain.com |
admin / [generated] |
Prometheus | http://ip:9090 |
https://prometheus.domain.com |
admin / [generated] |
pgAdmin | http://ip:8080 |
https://pgadmin.domain.com |
[email] / [generated] |
# Manual health check
sudo /usr/local/bin/n8n-health-check.sh
# View health check logs
sudo tail -f /var/log/n8n/health-check.log
# Check service status
sudo systemctl status postgresql redis-server nginx prometheus grafana-server
Pre-configured dashboards include:
- System Overview: CPU, memory, disk, network metrics
- n8n Performance: Workflow executions, response times
- Database Metrics: PostgreSQL performance and connections
- Redis Metrics: Cache hit rates, memory usage
Configure alerts in Grafana for:
- High CPU/memory usage
- Disk space warnings
- Service downtime
- Failed workflow executions
π Monitoring Guide: See docs/MONITORING.md
- π₯ Network Security: UFW firewall with minimal open ports
- π« Intrusion Prevention: Fail2ban with custom rules
- π SSL/TLS: Let's Encrypt certificates with auto-renewal
- ποΈ Database Security: SCRAM-SHA-256 authentication
- π Access Control: Basic authentication and strong passwords
- π Security Headers: HSTS, CSP, and other security headers
π₯ Firewall Rules
# View current firewall status
sudo ufw status verbose
# Add custom rules
sudo ufw allow from your-ip to any port 22
sudo ufw allow 80
sudo ufw allow 443
π« Fail2ban Configuration
# Check fail2ban status
sudo fail2ban-client status
# View banned IPs
sudo fail2ban-client status sshd
# Unban an IP
sudo fail2ban-client set sshd unbanip x.x.x.x
π SSL Certificate Management
# Check certificate status
sudo certbot certificates
# Manual renewal
sudo certbot renew
# Test renewal process
sudo certbot renew --dry-run
π Security Guide: See docs/SECURITY.md
Backups run daily at 2 AM and include:
- β PostgreSQL database dump
- β n8n workflows and configurations
- β System configurations
- β Application logs
πΎ Manual Backup
# Run manual backup
sudo /usr/local/bin/n8n-backup.sh
# List available backups
ls -la /opt/backups/
# Check backup logs
sudo tail -f /var/log/backup.log
βοΈ S3 Integration
# Configure S3 backup (edit backup script)
sudo nano /usr/local/bin/n8n-backup.sh
# Set S3_BUCKET variable
S3_BUCKET="your-backup-bucket"
# Test S3 upload
aws s3 ls s3://your-backup-bucket/
π Restore Process
# 1. Stop services
sudo systemctl stop postgresql redis-server nginx
# 2. Extract backup
sudo tar -xzf /opt/backups/n8n_backup_YYYYMMDD_HHMMSS.tar.gz -C /tmp/
# 3. Restore database
sudo -u postgres psql -d n8n < /tmp/postgresql_backup.sql
# 4. Restore n8n data
sudo tar -xzf /tmp/n8n_userdata.tar.gz -C /opt/n8n/
# 5. Restart services
sudo systemctl start postgresql redis-server nginx
π Backup Guide: See docs/BACKUP.md
π n8n Management
# Check n8n status
sudo -u n8n pm2 status
# Restart n8n
sudo -u n8n pm2 restart n8n
# View n8n logs
sudo -u n8n pm2 logs n8n
# Monitor n8n processes
sudo -u n8n pm2 monit
ποΈ Database Management
# Connect to database
sudo -u postgres psql -d n8n
# Check database size
sudo -u postgres psql -d n8n -c "SELECT pg_size_pretty(pg_database_size('n8n'));"
# Vacuum database
sudo -u postgres psql -d n8n -c "VACUUM ANALYZE;"
π System Updates
# Update system packages
sudo apt update && sudo apt upgrade -y
# Update n8n
sudo npm update -g n8n
# Restart services after updates
sudo systemctl restart postgresql redis-server nginx
sudo -u n8n pm2 restart n8n
# System resources
htop
df -h
free -h
# Service logs
sudo journalctl -u postgresql -f
sudo journalctl -u redis-server -f
sudo journalctl -u nginx -f
π Maintenance Guide: See docs/MAINTENANCE.md
Document | Description |
---|---|
π Architecture | Detailed system architecture and components |
π Deployment Guide | Step-by-step deployment instructions |
βοΈ Configuration | Complete configuration reference |
π Security Guide | Security best practices and hardening |
π Monitoring | Monitoring setup and dashboard configuration |
πΎ Backup & Recovery | Backup strategies and recovery procedures |
π οΈ Maintenance | Ongoing maintenance and troubleshooting |
π§ Troubleshooting | Common issues and solutions |
π΄ n8n Won't Start
# Check PM2 status
sudo -u n8n pm2 status
# Check logs
sudo -u n8n pm2 logs n8n
# Check database connection
sudo -u postgres psql -d n8n -c "SELECT 1;"
# Restart n8n
sudo -u n8n pm2 restart n8n
π΄ SSL Certificate Issues
# Check certificate status
sudo certbot certificates
# Test nginx configuration
sudo nginx -t
# Renew certificates
sudo certbot renew --force-renewal
# Restart nginx
sudo systemctl restart nginx
π΄ Database Connection Errors
# Check PostgreSQL status
sudo systemctl status postgresql
# Check connections
sudo -u postgres psql -c "SELECT * FROM pg_stat_activity;"
# Restart PostgreSQL
sudo systemctl restart postgresql
π΄ High Resource Usage
# Check system resources
htop
df -h
free -h
# Check n8n processes
sudo -u n8n pm2 monit
# Scale n8n instances
sudo -u n8n pm2 scale n8n 2
- π Check Logs: Always start by checking relevant logs
- π Run Health Check: Use the automated health check script
- π Review Documentation: Check the relevant documentation section
- π Create Issue: If problem persists, create a GitHub issue with:
- Deployment type (IP/domain)
- Error messages and logs
- System information
- Steps to reproduce
π Complete Troubleshooting Guide: See docs/TROUBLESHOOTING.md
We welcome contributions! Please see our Contributing Guide for details.
# Fork and clone the repository
git clone https://github.com/indranandjha1993/ec2-n8n-automation.git
cd ec2-n8n-automation
# Create a feature branch
git checkout -b feature/your-feature-name
# Make your changes and test
./scripts/deploy.sh --type ip --host test-instance
# Submit a pull request
Please use our Issue Template when reporting bugs or requesting features.
This project is licensed under the MIT License - see the LICENSE file for details.
- n8n.io - The amazing workflow automation tool
- Ansible - Infrastructure automation
- Let's Encrypt - Free SSL certificates
- Prometheus & Grafana - Monitoring stack
β If this project helped you, please give it a star! β