How to Self-Host Activepieces on Cloud Servers
What You’ll Need
- n8n Cloud or self-hosted n8n (alternative automation platform)
- Hetzner VPS or Contabo VPS for hosting
- DigitalOcean as alternative cloud provider
- Namecheap for domain registration
- Docker and Docker Compose installed locally
- PostgreSQL database (managed or self-hosted)
- SSL certificate (Let’s Encrypt, free)
- Basic command-line experience
Table of Contents
- Understanding Activepieces Architecture
- Selecting Your Cloud Infrastructure
- Initial Server Setup and Security
- Installing Docker and Prerequisites
- Deploying Activepieces with Docker Compose
- Configuring SSL and Reverse Proxy
- Database Setup and Backup Strategy
- Getting Started
Understanding Activepieces Architecture
Activepieces is a powerful, open-source workflow automation platform that rivals paid solutions like Make.com and Zapier. Unlike hosted services, self-hosting gives you complete control over your workflows, data retention, and integration capabilities. The platform consists of several components: a frontend web application, a backend API server, a database layer, and job scheduling services.
When you self-host Activepieces, you’re responsible for maintaining these components across your cloud infrastructure. This approach offers significant advantages for developers building production-grade automation systems. You get to customize authentication, integrate with private APIs, and maintain strict data governance without cloud vendor limitations.
The typical architecture involves a frontend served over HTTPS, an API backend handling workflow execution, PostgreSQL storing your workflow definitions and execution logs, and Redis managing job queues. I’ve found this architecture performs exceptionally well on modest VPS instances, particularly on platforms like Hetzner where you get excellent price-to-performance ratios.
Selecting Your Cloud Infrastructure
I recommend starting with Hetzner VPS for self-hosting Activepieces. Their CPX11 instance (2 vCPU, 4GB RAM) handles moderate workflow loads beautifully, costing around 4 euros monthly. This beats comparable offerings from other providers for reliability and performance.
If you prefer US-based infrastructure, Contabo VPS provides similar specs at competitive pricing. For established teams with larger budgets, DigitalOcean offers managed database services and streamlined dashboard controls, though at higher cost.
Your domain should come from Namecheap, where you’ll point DNS records to your VPS IP address. Budget around 10 dollars yearly for a .com domain.
Storage requirements depend on your workflow volume, but expect 20GB minimum for the operating system, Docker images, and application data. I typically allocate 40GB to accommodate growth and logs. Database size varies wildly by use case: a single-user setup might use 500MB, while enterprise deployments with thousands of workflow executions could reach 10GB monthly.
Initial Server Setup and Security
Once you’ve provisioned your VPS, connect via SSH and update system packages immediately:
ssh root@your_vps_ip
apt update && apt upgrade -y
Security is non-negotiable. Follow the practices outlined in our guide on hardening SSH server security on Ubuntu VPS to lock down remote access properly. At minimum, disable root login and password authentication:
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd
Create a dedicated non-root user for running Activepieces services:
useradd -m -s /bin/bash activepieces
usermod -aG sudo activepieces
su - activepieces
If your VPS has less than 2GB RAM, implement swap space using our detailed guide on configuring swap space on low memory VPS. Create 2GB of swap for safety:
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
Enable the UFW firewall and allow only necessary ports:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Installing Docker and Prerequisites
Docker containerizes Activepieces and its dependencies, simplifying deployment and updates significantly. Install Docker as the activepieces user:
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo usermod -aG docker activepieces
newgrp docker
Verify installation:
docker --version
docker compose version
Create the application directory structure:
mkdir -p ~/activepieces/{config,data,postgres}
cd ~/activepieces
Deploying Activepieces with Docker Compose
Create your docker-compose.yml file with all necessary services. This configuration includes PostgreSQL for persistent storage, Redis for job queuing, and the Activepieces server itself:
version: '3.8'
services:
postgres:
image: postgres:15-alpine
container_name: activepieces-postgres
environment:
POSTGRES_DB: activepieces
POSTGRES_USER: activepieces
POSTGRES_PASSWORD: your_secure_password_here_change_this
volumes:
- ./postgres:/var/lib/postgresql/data
ports:
- "5432:5432"
networks:
- activepieces-network
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U activepieces"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: activepieces-redis
ports:
- "6379:6379"
networks:
- activepieces-network
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
command: redis-server --appendonly yes
activepieces:
image: activepieces/activepieces:latest
container_name: activepieces-server
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
environment:
AP_API_URL: https://your-domain.com
AP_FRONTEND_URL: https://your-domain.com
AP_POSTGRES_DATABASE: activepieces
AP_POSTGRES_HOST: postgres
AP_POSTGRES_PORT: 5432
AP_POSTGRES_USERNAME: activepieces
AP_POSTGRES_PASSWORD: your_secure_password_here_change_this
AP_REDIS_HOST: redis
AP_REDIS_PORT: 6379
AP_ENCRYPTION_KEY: your_random_encryption_key_min_32_chars
AP_JWT_SECRET: your_jwt_secret_key_make_it_random
AP_ENVIRONMENT: production
AP_TRIGGER_DEFAULT_POLL_INTERVAL_SECONDS: 300
NODE_ENV: production
ports:
- "3000:3000"
networks:
- activepieces-network
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
volumes:
- ./config:/app/config
activepieces-worker:
image: activepieces/activepieces:latest
container_name: activepieces-worker
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
environment:
AP_POSTGRES_DATABASE: activepieces
AP_POSTGRES_HOST: postgres
AP_POSTGRES_PORT: 5432
AP_POSTGRES_USERNAME: activepieces
AP_POSTGRES_PASSWORD: your_secure_password_here_change_this
AP_REDIS_HOST: redis
AP_REDIS_PORT: 6379
AP_ENCRYPTION_KEY: your_random_encryption_key_min_32_chars
AP_JWT_SECRET: your_jwt_secret_key_make_it_random
AP_ENVIRONMENT: production
NODE_ENV: production
networks:
- activepieces-network
restart: unless-stopped
command: node dist/packages/server/index.js worker
networks:
activepieces-network:
driver: bridge
volumes:
postgres_data:
redis_data:
Generate secure values for encryption and JWT secrets:
openssl rand -base64 32
Replace placeholder values in the compose file with your actual domain, database password, and generated secrets. Then start the stack:
docker compose up -d
docker compose logs -f activepieces
💡 Fast-Track Your Project: Don’t want to configure this yourself? I build custom n8n pipelines and bots. Message me with code SYS3-HUGO.
Wait for the logs to show the server is running. You should see messages indicating successful database migrations and the server listening on port 3000.
Configuring SSL and Reverse Proxy
Activepieces runs on port 3000 internally, but you need a reverse proxy (Nginx) to serve it securely over HTTPS using port 443. Install Nginx:
sudo apt install -y nginx
Create the Nginx configuration file:
sudo nano /etc/nginx/sites-available/activepieces
Paste this configuration:
server {
listen 80;
server_name your-domain.com www.your-domain.com;
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
server_name your-domain.com www.your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
client_max_body_size 50M;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_cache_bypass $http_upgrade;
proxy_connect_timeout 600s;
proxy_send_timeout 600s;
proxy_read_timeout 600s;
}
location /api/webhooks/ {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
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;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
Enable the site:
sudo ln -s /etc/nginx/sites-available/activepieces /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Install Certbot for free SSL certificates from Let’s Encrypt:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot certonly --nginx -d your-domain.com -d www.your-domain.com
Verify the certificate was installed correctly by checking the Nginx config paths match:
sudo certbot renew --dry-run
Your Activepieces instance is now accessible at https://your-domain.com. The reverse proxy handles SSL termination, allowing you to upgrade certificates automatically without restarting Docker containers.
Database Setup and Backup Strategy
PostgreSQL runs inside Docker, but you need regular backups to prevent data loss. Create a backup script:
cat > ~/activepieces/backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="$HOME/activepieces/backups"
mkdir -p "$BACKUP_DIR"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/activepieces_backup_$TIMESTAMP.sql.gz"
docker exec activepieces-postgres pg_dump -U activepieces activepieces | gzip > "$BACKUP_FILE"
echo "Backup created: $BACKUP_FILE"
find "$BACKUP_DIR" -name "activepieces_backup_*.sql.gz" -mtime +30 -delete
echo "Old backups removed"
EOF
chmod +x ~/activepieces/backup.sh
Schedule daily backups using cron:
crontab -e
Add this line to run backups at 2 AM daily:
0 2 * * * /home/activepieces/activepieces/backup.sh >> /home/activepieces/activepieces/backup.log 2>&1
Test the backup immediately:
~/activepieces/backup.sh
ls -lah ~/activepieces/backups/
When protecting your Activepieces instance with webhooks, apply the same security principles outlined in our guide for securing Telegram bot webhook endpoints. Generate webhook signing secrets and validate request signatures to prevent unauthorized access.
Create a monitoring script to check service health:
cat > ~/activepieces/health_check.sh << 'EOF'
#!/bin/bash
SERVICES=("postgres" "redis" "activepieces-server")
for service in "${SERVICES[@]}"; do
if docker ps | grep -q "$service"; then
echo "[$service] is running"
else
echo "[$service] is DOWN - attempting restart"
docker compose restart "$service"
fi
done
curl -f http://localhost:3000/api/health > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "[activepieces-api] is healthy"
else
echo "[activepieces-api] health check failed"
fi
EOF
chmod +x ~/activepieces/health_check.sh
Add this to crontab to run every 5 minutes:
*/5 * * * * /home/activepieces/activepieces/health_check.sh >> /home/activepieces/activepieces/health_check.log 2>&1
Getting Started
Now that Activepieces is running, access it at https://your-domain.com and create your initial account. The first user becomes the admin automatically.
Start with simple workflows to understand the platform. Create a test flow that triggers on a webhook and sends you an email notification. Once comfortable, integrate with external APIs using Activepieces’ extensive connector library.
For scaling beyond single-instance deployments, consider adding a managed PostgreSQL database separate from your VPS, or upgrading to a larger Contabo VPS instance. Monitor CPU and memory usage with:
docker stats
Regularly update Activepieces by pulling the latest image:
cd ~/activepieces
docker compose pull
docker compose up -d
docker compose logs -f
Keep your n8n Cloud account handy as a fallback if you need a managed alternative, though self-hosting provides superior control and customization.
Outsource Your Automation
Don’t have time? I build production n8n workflows, WhatsApp bots, and fully automated YouTube Shorts pipelines. Hire me on Fiverr, mention SYS3-HUGO for priority. Or DM at chasebot.online.
Self-hosting Activepieces gives you complete automation control without vendor lock-in. You handle infrastructure, but gain flexibility and cost savings that pay dividends as your workflows scale. The setup takes roughly 30 minutes once you understand each component’s role. From there, you can build sophisticated multi-step automations connecting dozens of applications, all running on infrastructure you control completely.
Want to automate this yourself?
Start with n8n Cloud (free tier available) or self-host on a Hetzner VPS for full control.
Want this engine running on your own VPS?
This blog publishes itself — daily, unattended, on free API tiers. The full engine, Hugo theme, and setup guide are available as System 3.
Get System 3