Skip to main content
AI Automation

Activepieces on my homelab: the config that actually runs

· · 4 min read

I’ve been looking for an alternative to Zapier that I could actually own. Tried Node-RED a while back but the UI felt like fighting with it half the time. Activepieces landed in my feed last week and the visual automation builder looked clean enough that I decided to spend a Saturday morning on it. Two hours in, it’s running behind Traefik with auth, and the thing just works.

🎯 Not sure if this will run on your hardware?Use our free Local LLM Hardware Checker — pick your GPU and RAM, see which models will run with real tokens/sec estimates.
Check my hardware →
Activepieces screenshot
Activepieces u2014 from the official site

The docker-compose setup

I’m running this on a 4-core VM with 8GB RAM alongside other services. Activepieces isn’t heavy, but it does need Postgres to back it. Here’s what I have:

version: '3.8'

services:
  activepieces:
    image: activepieces/activepieces:0.27.1
    container_name: activepieces
    restart: unless-stopped
    environment:
      - AP_API_URL=https://automations.mylab.local
      - AP_FRONTEND_URL=https://automations.mylab.local
      - AP_ENCRYPTION_KEY=${AP_ENCRYPTION_KEY}
      - AP_JWT_SECRET=${AP_JWT_SECRET}
      - DATABASE_URL=postgresql://activepieces:${DB_PASSWORD}@postgres-ap:5432/activepieces
      - AP_REDIS_URL=redis://redis-ap:6379
      - AP_ENVIRONMENT=prod
      - AP_LOG_LEVEL=info
    depends_on:
      - postgres-ap
      - redis-ap
    networks:
      - traefik
      - activepieces-internal
    labels:
      - traefik.enable=true
      - traefik.http.routers.activepieces.rule=Host(`automations.mylab.local`)
      - traefik.http.routers.activepieces.entrypoints=websecure
      - traefik.http.routers.activepieces.tls=true
      - traefik.http.routers.activepieces.service=activepieces
      - traefik.http.services.activepieces.loadbalancer.server.port=80
      - traefik.http.routers.activepieces.middlewares=authentik@docker
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/api/health"]
      interval: 30s
      timeout: 5s
      retries: 3

  postgres-ap:
    image: postgres:16-alpine
    container_name: postgres-activepieces
    restart: unless-stopped
    environment:
      - POSTGRES_USER=activepieces
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=activepieces
    volumes:
      - ap-postgres-data:/var/lib/postgresql/data
    networks:
      - activepieces-internal
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U activepieces"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis-ap:
    image: redis:7-alpine
    container_name: redis-activepieces
    restart: unless-stopped
    volumes:
      - ap-redis-data:/data
    networks:
      - activepieces-internal
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  ap-postgres-data:
  ap-redis-data:

networks:
  traefik:
    external: true
  activepieces-internal:
    driver: bridge

A few choices here. I’m using Postgres 16 Alpine because it’s small and stable. Redis sits alongside it for caching and job queues—Activepieces needs this, not optional. The health checks matter. I learned that the hard way on another service; without them, Traefik tries to route to a container that’s still booting. I set the Postgres one to 10 second intervals because database startup is slow.

The Traefik labels point everything at the TLS entry point and use my Authentik middleware for authentication. You could skip the auth middleware if you’re not running Authentik, but then Activepieces sits naked on your network. I’m not comfortable with that.

Environment variables

I generated the encryption and JWT secrets with openssl rand -base64 32 and threw them in a .env file that docker-compose reads at startup:

AP_ENCRYPTION_KEY=your_generated_key_here
AP_JWT_SECRET=your_generated_secret_here
DB_PASSWORD=very_long_postgres_password_here

The encryption key encrypts sensitive data like OAuth tokens inside the database. The JWT secret signs the auth tokens Activepieces hands out to users. If you lose either one, you lose access to your automation data. Keep these somewhere safe. I use Bitwarden for mine.

The API and frontend URLs need to match your reverse proxy hostname exactly. Activepieces uses these to build links in emails and webhooks. I had it set to http://localhost at first and webhooks didn’t work. That was the moment I realized I wasn’t reading the logs carefully enough.

Traefik reverse proxy config

I’m using Traefik’s docker provider, so everything runs as labels on the container. If you use a static config file instead, it looks like this:

[http.routers.activepieces]
rule = "Host(`automations.mylab.local`)"
entrypoints = ["websecure"]
service = "activepieces-service"
tls = true
middlewares = ["authentik"]

[http.services.activepieces-service]
[http.services.activepieces-service.loadbalancer]
  [[http.services.activepieces-service.loadbalancer.servers]]
    url = "http://activepieces:80"

Nothing fancy. Traefik handles TLS termination and routes HTTP traffic to port 80 inside the container. The healthcheck on the container means Traefik won’t send traffic to Activepieces until it’s ready, which avoids the 502 errors during startup.

First run and that one surprise

When I brought it up for the first time, the database migrations took about 30 seconds. I almost killed it, thinking something hung. Migrations always feel slow when you’re watching them. Let it sit.

One thing surprised me: Activepieces doesn’t have a CLI or API for creating user accounts out of the box. You have to go through the web UI. If you’re running this behind Authentik, you’ll need to either open it up temporarily for signup or create accounts manually in Postgres. I ended up doing the latter because I only have one user. That’s not a complaint, just not obvious from the docs.

I’ve built two automations so far. One watches a folder in my NAS and sends me a Telegram message when new files appear. The other syncs new Jellyfin watch history into Home Assistant so I can trigger other automations based on what I’m watching. The UI is fast, the integrations available are solid, and I haven’t hit any walls yet.

The question I’m sitting with now is whether the AI pieces—the ones that integrate with OpenAI or local LLMs—are actually useful or just shiny. I have Ollama running in the homelab, so theoretically I could chain that into automations. Probably worth an evening of experimenting once things stabilize.

Explore Activepieces in our AI Homelab Toolkit.

Share this article