Activepieces Workflow Automation: Self-Host a Zapier Alternative in Docker
Learn how to deploy Activepieces using Docker Compose on a VPS. Build automated workflows and integrate services with a self-hosted automation hub.
Activepieces is a modular, self-hostable workflow automation engine. While a single-container setup works for testing, a production-grade deployment separates the application server (frontend & API) from execution workers. This decoupling ensures task execution scales horizontally without degrading dashboard responsiveness.
This guide provides a comprehensive configuration for deploying Activepieces on a VPS using Docker Compose, detailing worker scaling, database security, task queue monitoring, and Nginx reverse proxy configuration.
Activepieces Production Architecture
A high-availability Activepieces deployment consists of four primary components: 1. App Server (AP_CONTAINER_TYPE=APP): Handles the web dashboard, API endpoints, webhook reception, and user authentication. 2. Worker Pool (AP_CONTAINER_TYPE=WORKER): Polls the queue, provisions sandbox environments, runs flow logic, and reports execution status. 3. Redis: Powering BullMQ, managing job queues, triggers, execution statuses, and caching. 4. PostgreSQL: Stores persistent application state, including users, flows, piece metadata, and run history.
graph TD
Client[Client / Webhook Trigger] -->|HTTPS| Proxy[Nginx / Reverse Proxy]
Proxy -->|Port 8080| App[Activepieces App Server]
App -->|Reads/Writes| DB[(PostgreSQL)]
App -->|Enqueues Jobs| Cache[(Redis Queue)]
Worker[Activepieces Worker Pool] -->|Polls Queue| Cache
Worker -->|Reports Job State| App
Docker Compose Configuration
The following docker-compose.yml configures PostgreSQL, Redis, the Activepieces App instance, and a separate Activepieces Worker instance.
version: '3.8'
services:
postgres:
image: postgres:16-alpine
container_name: activepieces-postgres
restart: unless-stopped
environment:
POSTGRES_DB: ${AP_POSTGRES_DATABASE:-activepieces}
POSTGRES_USER: ${AP_POSTGRES_USERNAME:-activepieces}
POSTGRES_PASSWORD: ${AP_POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${AP_POSTGRES_USERNAME:-activepieces} -d ${AP_POSTGRES_DATABASE:-activepieces}"]
interval: 10s
timeout: 5s
retries: 5
networks:
- ap-network
redis:
image: redis:7-alpine
container_name: activepieces-redis
restart: unless-stopped
command: redis-server --appendonly yes --maxmemory 512mb --maxmemory-policy noeviction
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- ap-network
activepieces-app:
image: activepieces/activepieces:latest
container_name: activepieces-app
restart: unless-stopped
ports:
- "127.0.0.1:8080:80"
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
env_file:
- .env
environment:
- AP_CONTAINER_TYPE=APP
volumes:
- ap_cache:/usr/src/app/cache
networks:
- ap-network
activepieces-worker:
image: activepieces/activepieces:latest
container_name: activepieces-worker-1
restart: unless-stopped
# Required if using AP_EXECUTION_MODE=SANDBOX_PROCESS for kernel-level sandboxing
privileged: true
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
env_file:
- .env
environment:
- AP_CONTAINER_TYPE=WORKER
volumes:
- ap_cache:/usr/src/app/cache
networks:
- ap-network
volumes:
postgres_data:
driver: local
redis_data:
driver: local
ap_cache:
driver: local
networks:
ap-network:
driver: bridge
Environment Variables Configuration
Create a .env file in the same directory as docker-compose.yml. This configuration defines database parameters, sandboxing, concurrency settings, and queue metrics monitoring.
# ==========================================
# 1. Application URL & General Config
# ==========================================
# The public domain where Activepieces is hosted. (Required for Webhook callbacks)
AP_FRONTEND_URL=https://automation.yourdomain.com
# Node environment
NODE_ENV=production
# ==========================================
# 2. Database Configuration (PostgreSQL)
# ==========================================
AP_DB_TYPE=POSTGRES
AP_POSTGRES_HOST=postgres
AP_POSTGRES_PORT=5432
AP_POSTGRES_DATABASE=activepieces
AP_POSTGRES_USERNAME=activepieces
# Generate a secure database password
AP_POSTGRES_PASSWORD=f5d96a75f82c23a7e48b111cdde90df1
# ==========================================
# 3. Queue Configuration (Redis)
# ==========================================
AP_REDIS_TYPE=REDIS
AP_REDIS_HOST=redis
AP_REDIS_PORT=6379
# If using a password-protected Redis:
# AP_REDIS_PASSWORD=
# ==========================================
# 4. Security Keys (Generate unique keys)
# ==========================================
# Encrypts third-party API credentials stored in DB (16-byte hex value)
AP_ENCRYPTION_KEY=a7d2d3e4f9b8c0a2f1b4d5e6c7a8f9b0
# Secret for signing dashboard session tokens (32-byte hex value)
AP_JWT_SECRET=b8d9c0a1f2b3e4d5c6a7f8b9e0d1c2a3b4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9
# ==========================================
# 5. Task Execution & Sandboxing
# ==========================================
# Sandbox Isolation Levels:
# - UNSANDBOXED: Lowest security. Runs code inside the worker Node process. Fast.
# - SANDBOX_CODE_ONLY: Mid security. Uses lightweight code context virtualization.
# - SANDBOX_PROCESS: Highest security. Creates isolated OS-level namespace sandboxes.
# Requires `privileged: true` in docker-compose.yml.
AP_EXECUTION_MODE=SANDBOX_PROCESS
# Number of concurrent runs processed by a single worker container instance.
AP_WORKER_CONCURRENCY=10
# ==========================================
# 6. Queue UI (BullBoard Monitoring)
# ==========================================
# Enables the queue dashboard at https://automation.yourdomain.com/api/ui
AP_QUEUE_UI_ENABLED=true
AP_QUEUE_UI_USERNAME=admin
AP_QUEUE_UI_PASSWORD=change-this-secure-password
Step-by-Step Deployment Walkthrough
1. Generating Security Secrets
Activepieces demands distinct cryptographic secrets for encrypting database records and signing user sessions. Run these commands on your VPS shell to generate high-entropy keys:
# Generate AP_ENCRYPTION_KEY (32-character hexadecimal / 16 bytes)
openssl rand -hex 16
# Generate AP_JWT_SECRET (64-character hexadecimal / 32 bytes)
openssl rand -hex 32
# Generate AP_POSTGRES_PASSWORD
openssl rand -hex 16
Paste these generated strings into your .env file.
2. File Placement
Organize the configuration files under a unified directory on the host machine:
mkdir -p /opt/activepieces
cd /opt/activepieces
# Create docker-compose.yml and .env here
3. Deploying the Stack
Start the Activepieces stack in detached mode:
docker compose up -d
Verify that the containers are healthy and database migration scripts have executed:
docker compose ps
docker compose logs -f activepieces-app
Scaling Workers and High Availability
Because Activepieces workers are stateless queue-consumers, scaling them horizontally is trivial. To scale out processing capacity on a single node:
docker compose up -d --scale activepieces-worker=3
This starts three worker containers (activepieces-worker-1, activepieces-worker-2, activepieces-worker-3), all polling jobs from the single Redis queue.
CPU/Memory Optimization Rules:
- I/O-Bound Flows: If your automated steps primarily query external HTTP APIs, increase
AP_WORKER_CONCURRENCY=15or20to keep threads busy. - CPU-Bound Flows: If you execute heavy custom code steps (e.g., node script data parsing), keep
AP_WORKER_CONCURRENCY=5and scale the worker replicas using--scaleto leverage multi-core VPS environments.
Reverse Proxy Configuration (Nginx)
Place Activepieces behind Nginx to handle SSL termination, redirect HTTP traffic to HTTPS, and enforce websocket capabilities for the live flow builder.
upstream activepieces_app {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name automation.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name automation.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/automation.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/automation.yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
client_max_body_size 50M;
location / {
proxy_pass http://activepieces_app;
proxy_http_version 1.1;
# Enable WebSockets
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Pass Request Headers
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;
# Webhook timeout configuration
proxy_connect_timeout 90s;
proxy_send_timeout 90s;
proxy_read_timeout 90s;
}
}
Task Queue Monitoring (BullBoard)
Once Activepieces starts, BullBoard visualizes BullMQ activity, showing active, completed, failed, delayed, and paused runs.
- Navigate to
https://automation.yourdomain.com/api/ui. - Authenticate using the credentials configured via
AP_QUEUE_UI_USERNAMEandAP_QUEUE_UI_PASSWORD. - Use the interface to troubleshoot delayed triggers or manually retry failed runs.