# How to install Activepieces with Docker Compose and HTTPS

> Self-host Activepieces with Docker Compose, PostgreSQL and Redis from the official repo and secret generator, behind Caddy HTTPS, with backups and updates.

Difficulty: Intermediate\
Tested on: Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, Debian 12, Debian 13

Activepieces is an open-source automation platform. You build flows from triggers and steps called **pieces**, which connect to business apps and AI services, add branches, loops and code steps, and expose flows as tools to AI agents. Its builder targets business users as well as developers, and self-hosting keeps connections and run data on your own server.

This guide follows the **Docker Compose** method from Activepieces' documentation: you clone the official repository, generate secrets with the bundled `tools/deploy.sh` script, and run the app, a worker, **PostgreSQL** and **Redis** with Docker Compose. The app listens only on `127.0.0.1`, and **Caddy** serves it over HTTPS on your domain. You then create the platform admin account and set up backups and updates. A short section explains the official one-command installer as an alternative.

## Prerequisites

- A server running **Ubuntu 24.04 LTS**, **Ubuntu 26.04 LTS**, **Debian 12** or **Debian 13** with Docker Engine and Docker Compose v2. Follow [Install Docker on Ubuntu](/guides/install-docker-ubuntu) or [Install Docker on Debian](/guides/install-docker-debian).
- A non-root user with `sudo` rights and SSH key login, prepared as in [Secure a new Linux server](/guides/secure-a-new-linux-server) and [Set up SSH keys](/guides/ssh-keys).
- A subdomain such as `automation.example.com` with an A record (and AAAA for IPv6) pointing at the server.
- Caddy on the host, installed with [Caddy reverse proxy](/guides/caddy-reverse-proxy).
- `git` and `openssl`, which the next steps install if they are missing.

Activepieces' Docker Compose documentation asks for at least 2 vCPUs and 4 GB of RAM. It does not publish a disk figure; the database grows with your run history.

| Resource | Minimum (official) | Suggested starting point |
|---|---|---|
| CPU | 2 vCPU | 2 vCPU |
| RAM | 4 GB | 4 GB |
| Disk | Not published | 30 GB SSD |

## Step 1 — Clone the official repository

The repository contains the `.env.example` template and the secret generator. Clone it into `/opt/activepieces`; a shallow clone is enough:

```bash
sudo apt update
sudo apt install git openssl
sudo mkdir -p /opt/activepieces
sudo chown $USER:$USER /opt/activepieces
git clone --depth 1 https://github.com/activepieces/activepieces.git /opt/activepieces
cd /opt/activepieces
```

## Step 2 — Generate secrets with the official script

`tools/deploy.sh` copies `.env.example` to `.env` and fills in random values with `openssl`: `AP_API_KEY`, `AP_POSTGRES_PASSWORD`, `AP_JWT_SECRET` (signs login tokens) and `AP_ENCRYPTION_KEY` (32 hex characters that encrypt your saved connections). Run it once and check that the important values are not empty:

```bash
sh tools/deploy.sh
grep -E '^(AP_ENCRYPTION_KEY|AP_JWT_SECRET|AP_POSTGRES_PASSWORD)=' .env
chmod 600 .env
```

All three lines must show a long value. Activepieces' documentation warns that the script can report success with blank values when `openssl` is missing.

> **Warning**
>
> Run `deploy.sh` only once. It overwrites `.env` from the template every time, which replaces your encryption key and database password. Back up `.env` now and keep a copy off the server: without `AP_ENCRYPTION_KEY`, stored connections cannot be decrypted, even from a database backup.

## Step 3 — Configure the core settings

Three settings in `.env` need your attention:

- `AP_FRONTEND_URL` is the public address used for redirects, OAuth callbacks and webhook URLs. External services must be able to reach it.
- `AP_EDITION=ee` is the value that Activepieces' Docker Compose documentation and its installer set. Add it as shown below.
- `AP_EXECUTION_MODE` controls how code steps are isolated. With `AP_EDITION=ee` the server refuses to start with the default `UNSANDBOXED`, so set `SANDBOX_CODE_ONLY`: each code step then runs in a fresh V8 isolate with 128 MB of memory and no file system access, which Activepieces recommends when users are not fully trusted. Code steps cannot use npm packages in this mode.

The Compose file in the next step also reads `AP_VERSION`, the image tag to run. `0.92.2` was the latest release on 2026-10-09; use the current tag from the Activepieces releases page on GitHub:

```bash
cd /opt/activepieces
sed -i 's|^AP_FRONTEND_URL=.*|AP_FRONTEND_URL=https://automation.example.com|' .env
sed -i 's|^AP_EXECUTION_MODE=.*|AP_EXECUTION_MODE=SANDBOX_CODE_ONLY|' .env
cat >> .env <<'EOF'
AP_EDITION=ee
AP_VERSION=0.92.2
EOF
grep -E '^AP_(FRONTEND_URL|EXECUTION_MODE|EDITION|VERSION)=' .env
```

The last command should print the four values you just set.

## Step 4 — Adapt the Compose file

The repository's `docker-compose.yml` publishes port 8080 on every address, gives the database and Redis fixed container names and starts five workers. Keep a copy of the original and replace it with the version below. It matches the template that Activepieces' own installer writes, with two changes: the port is published on `127.0.0.1` only, and the image tag comes from `AP_VERSION`:

```bash
cp docker-compose.yml docker-compose.yml.orig
nano docker-compose.yml
```

```yaml
services:
  app:
    image: ghcr.io/activepieces/activepieces:${AP_VERSION}
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"
    depends_on:
      - postgres
      - redis
    env_file: .env
    environment:
      - AP_CONTAINER_TYPE=APP
    volumes:
      - ./cache:/usr/src/app/cache
    networks:
      - activepieces
  worker:
    image: ghcr.io/activepieces/activepieces:${AP_VERSION}
    restart: unless-stopped
    depends_on:
      - app
    env_file: .env
    environment:
      - AP_CONTAINER_TYPE=WORKER
      - AP_FRONTEND_URL=http://app
    volumes:
      - ./cache:/usr/src/app/cache
    networks:
      - activepieces
  postgres:
    image: pgvector/pgvector:0.8.0-pg14
    restart: unless-stopped
    env_file: .env
    environment:
      - POSTGRES_DB=${AP_POSTGRES_DATABASE}
      - POSTGRES_PASSWORD=${AP_POSTGRES_PASSWORD}
      - POSTGRES_USER=${AP_POSTGRES_USERNAME}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - activepieces
  redis:
    image: redis:7.0.7
    restart: unless-stopped
    volumes:
      - redis_data:/data
    networks:
      - activepieces
volumes:
  postgres_data:
  redis_data:
networks:
  activepieces:
```

The worker's own `AP_FRONTEND_URL=http://app` overrides the public URL from `.env`: workers talk to the app over the internal network, and `localhost` inside the worker container would point at the worker itself. Check the file for syntax errors:

```bash
docker compose config --quiet && echo "compose file OK"
```

## Step 5 — Start Activepieces

Pull the images and start the stack. The first start takes a minute or two while the app creates its database tables:

```bash
docker compose pull
docker compose up -d
docker compose ps
curl -s http://127.0.0.1:8080/api/v1/health
```

All four services should be `running`, and the health endpoint answers with a short JSON status once the app is ready. If it does not, follow the app log with `docker compose logs -f app`.

## Step 6 — Publish Activepieces over HTTPS with Caddy

Add a site block for the subdomain to `/etc/caddy/Caddyfile`:

```caddyfile
automation.example.com {
    reverse_proxy 127.0.0.1:8080
}
```

Reload Caddy, allow only SSH and web traffic, and test the public address:

```bash
sudo systemctl reload caddy
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
curl -I https://automation.example.com
```

You should get an HTTP 200 response with a valid certificate. Port 8080 stays closed to the internet because Docker publishes it on the loopback address only. For Nginx or Traefik instead of Caddy, see [Nginx with Certbot](/guides/nginx-reverse-proxy-certbot) and [Traefik](/guides/traefik-reverse-proxy).

## Step 7 — Create the platform admin account

Open `https://automation.example.com` straight away and sign up. On a fresh instance **the first account becomes the platform administrator**. After that, new people join through invitations from the admin console; open sign-up only happens if you set `AP_ALLOW_OPEN_SIGN_UP=true`, which you should not do on a public server.

Then open **Platform Admin → Operations → Workers** and check that at least one worker is listed. Configure outgoing email in the admin console so that invitations and the emailed six-digit sign-in codes work. Alternatively, set `AP_SMTP_HOST` (for example `smtp.example.com`), `AP_SMTP_PORT` (`587`), `AP_SMTP_USERNAME`, `AP_SMTP_PASSWORD`, `AP_SMTP_SENDER_EMAIL` and `AP_SMTP_SENDER_NAME` in `.env`; Activepieces only uses these variables when the admin screen has no email configuration and host, port, username and password are all set. Users with a password can always sign in through the **Use password** link.

> **Note**
>
> Outbound port 25 is closed by default on HyperDC VPS. For services bought for a term of 3 months or longer, it is opened on request: [open a support ticket](/guides/support-tickets). Until then, send mail through an SMTP relay on port 587.

To run more flows in parallel, add workers with `docker compose up -d --scale worker=2`. Activepieces' production guidance favours several workers with `AP_WORKER_CONCURRENCY=1` over one worker with many parallel jobs, because an out-of-memory error then affects only one run.

## Alternative: the one-command installer

Activepieces also offers an official installer at `get.activepieces.com`. It checks for Docker Compose v2, creates an `activepieces` folder with a `docker-compose.yml` and a `.env` full of generated secrets (`AP_EDITION=ee`, `SANDBOX_CODE_ONLY`), pulls the latest release and starts the stack. It never overwrites an existing `.env`, and the same script handles `--upgrade` and `--uninstall`. Download it and read it before running it:

```bash
curl -fsSL https://get.activepieces.com -o install-activepieces.sh
less install-activepieces.sh
sh install-activepieces.sh --dir /opt/activepieces
```

The official one-line form pipes the same script into `sh`. Note that the installer publishes the app on port 8080 on **all** addresses and sets `AP_FRONTEND_URL` to `http://localhost:8080`; Docker bypasses ufw, so the port is reachable from the internet until you change it. Create the admin account immediately, then set `AP_HOST_PORT=127.0.0.1:8080` and your HTTPS `AP_FRONTEND_URL` in the generated `.env` and apply them with `docker compose up -d` in that folder.

## Back up and restore

Activepieces keeps flows, runs, connections and users in PostgreSQL, in the `postgres_data` volume, not in the project folder. The second essential item is `.env` with the encryption key. Redis only holds the job queue, and the `cache` folder is rebuilt automatically. Back up the database and the configuration:

```bash
sudo mkdir -p /opt/backups
sudo chown $USER:$USER /opt/backups
cd /opt/activepieces
docker compose exec -T postgres sh -c 'pg_dump -U "$POSTGRES_USER" -Fc "$POSTGRES_DB"' > /opt/backups/activepieces-db-$(date +%F).dump
tar czf /opt/backups/activepieces-config-$(date +%F).tar.gz -C /opt/activepieces .env docker-compose.yml
chmod 600 /opt/backups/activepieces-*
```

To restore, on the same server or on a new one, put `.env` and `docker-compose.yml` from the archive into `/opt/activepieces`, start PostgreSQL alone, load the dump and start the rest:

> **Warning**
>
> `pg_restore --clean` replaces the current contents of the database. On an existing installation, take a fresh dump first.

```bash
cd /opt/activepieces
docker compose stop app worker
docker compose up -d postgres
until docker compose exec postgres pg_isready -U postgres; do sleep 2; done
docker compose exec -T postgres sh -c 'pg_restore -U "$POSTGRES_USER" -d "$POSTGRES_DB" --clean --if-exists' < /opt/backups/activepieces-db-2026-10-09.dump
docker compose up -d
```

Replace the date with the one in your file name. Copy `/opt/backups` to another machine or object storage regularly; backups that stay on the same server are lost with it.

## Update Activepieces

Activepieces releases often. Before each update, read the breaking-changes page in its documentation, which lists changes that affect self-hosted instances and individual pieces, and back up the database and `.env`. Then set `AP_VERSION` in `.env` to the new release and recreate the containers:

```bash
cd /opt/activepieces
nano .env
docker compose pull
docker compose up -d
docker compose logs --tail=50 app
```

Database migrations run when the app starts. Keep the PostgreSQL and Redis image tags as they are during routine updates; a PostgreSQL major upgrade needs a dump and restore. If you used the one-command installer, run it again with `--upgrade` instead, which updates `AP_VERSION` and keeps your `.env` and data.

## Troubleshooting

### Webhook and redirect URLs point to localhost:8080

`AP_FRONTEND_URL` in `.env` still has its default value. Set it to `https://automation.example.com` and run `docker compose up -d --force-recreate app`. Webhook URLs copied into external services before the change must be updated there.

### Flows stay queued and no worker is listed

The worker cannot reach the app. Make sure the worker service sets `AP_FRONTEND_URL=http://app` and that both containers share the `activepieces` network, then read `docker compose logs worker`. Platform Admin → Operations → Workers must list at least one worker.

### The app stops right after start with AP_EDITION=ee

With `AP_EDITION=ee`, the server rejects `AP_EXECUTION_MODE=UNSANDBOXED` at startup. Set `AP_EXECUTION_MODE=SANDBOX_CODE_ONLY` in `.env` and run `docker compose up -d`. The modes `SANDBOX_PROCESS` and `SANDBOX_CODE_AND_PROCESS` would need privileged containers and are not used in this guide.

### Connections fail after a restore

The `AP_ENCRYPTION_KEY` in the current `.env` is not the one that encrypted the data. Put the original `.env` back and recreate the containers. Without the original key, saved connections cannot be recovered and must be reconnected.

### A code step cannot import an npm package

`SANDBOX_CODE_ONLY` runs code in a V8 isolate without `require` or npm. Move the logic into a piece or call an external API instead.

### Port 8080 is already in use

Another service uses port 8080 on the loopback address. Change the host side of the mapping, for example `"127.0.0.1:8081:80"`, update the Caddy site block to match and run `docker compose up -d`. Do not change `AP_PORT`, which is the app's internal listen port.

## Next steps

- Compare Activepieces with [n8n](/guides/install-n8n) and [Node-RED](/guides/install-node-red).
- Learn more about Compose files in [Docker Compose basics](/guides/docker-compose-basics).
- Find servers sized for automation workloads on the [Activepieces hosting](/activepieces-hosting) page.
- Read the [Activepieces self-hosting documentation](https://www.activepieces.com/docs/install/overview) for environment variables, sandboxing and scaling.

## Frequently asked questions

### Which execution mode should I use for code steps?

SANDBOX_CODE_ONLY, the value the official Docker Compose setup and installer use together with AP_EDITION=ee. Each code step then runs in a fresh V8 isolate with 128 MB of memory and no file system access, which Activepieces recommends when users are not fully trusted. Code steps cannot use npm packages in this mode.

### What is AP\_ENCRYPTION\_KEY used for?

Activepieces encrypts the connections you save, such as API keys and OAuth tokens, with AP_ENCRYPTION_KEY. Without the original key, a database backup restores your flows but the stored connections cannot be decrypted. Keep the .env file in every backup.

### Can other people sign up on my Activepieces instance?

Only the first account signs up freely and becomes the platform admin. After that, new users join through invitations unless you set AP_ALLOW_OPEN_SIGN_UP=true, which you should avoid on a public server.

### Why does the worker use http://app as its frontend URL?

Workers reach the app over the internal Docker network. Inside the worker container, localhost points to the worker itself, so Activepieces' Docker Compose documentation sets AP_FRONTEND_URL=http://app for the worker service only.

### Does Activepieces run on a HyperDC server?

Yes. The guide works on a HyperDC Linux VPS, VDS or dedicated server with root access running Ubuntu 24.04, Ubuntu 26.04, Debian 12 or Debian 13, sized to at least the 2 vCPUs and 4 GB of RAM that Activepieces lists for Docker Compose.

---

Source: <https://hyperdc.com/guides/tutorials/install-activepieces>\
Updated: 2026-10-09
