# n8n workflow automation

Source: https://docs.quake.ai/resources/iac-templates/n8n-workflow
Markdown: https://docs.quake.ai/resources/iac-templates/n8n-workflow.md

---

# n8n workflow automation

This pattern composes Compute, Network, and Block Storage into a self-hosted workflow-automation host you run on infrastructure you control.

## What this template does

Provisions a single instance running [n8n](https://n8n.io), an open-source workflow-automation tool (a self-hosted alternative to Zapier or Make). You build workflows in the editor that connect APIs, databases, and services with triggers, branching, and scheduled runs:

- Compute instance that runs n8n in Docker, sized for n8n's basic SQLite mode (2 vCPU and 2 GiB RAM)
- Private network, subnet, router, port, and security group; a floating IP for public access
- A block volume mounted at `/var/lib/docker`, so the n8n data (workflows, credentials, the SQLite database, and the encryption key) lives on a volume you can grow rather than on the boot disk
- cloud-init installs Docker Engine and starts n8n from a compose file on first boot

n8n is the glue layer that wires together the services a project depends on. It runs the automation loop on a VM you own, which keeps credentials and workflow data on your infrastructure.

No credential ships with this template. n8n generates its own encryption key on first start and persists it on the data volume, and you set the owner account the first time you open the editor.

## Parameters

| Parameter | Description | Default |
| --- | --- | --- |
| `key_name` | SSH keypair name (must already exist) | No default |
| `flavor_name` | Instance size (n8n SQLite mode runs on 2 vCPU / 2 GiB) | `s1a.small` |
| `image_name` | Operating system image | `Ubuntu-24.04` |
| `app_name` | Display name prefix for resources | `n8n` |
| `volume_size` | Block volume size in GiB, mounted at `/var/lib/docker` | `20` |
| `external_network` | External network for floating IP allocation | `PublicStatic` |
| `private_cidr` | CIDR for the private subnet | `10.40.0.0/24` |
| `editor_allowed_cidr` | CIDR allowed to reach the editor on port 5678 | `10.40.0.0/24` |
| `db_type` | Datastore backend: `sqlite` or `postgres` | `sqlite` |
| `postgres_host` | PostgreSQL host (when `db_type` is `postgres`) | `""` |
| `postgres_db` | PostgreSQL database name (when `db_type` is `postgres`) | `n8n` |
| `postgres_user` | PostgreSQL user (when `db_type` is `postgres`) | `n8n` |

## Editor access and security

The editor listens on port 5678 over plain HTTP. The security group restricts 5678 to `editor_allowed_cidr`, which defaults to the private network only, so the raw editor stays off the public internet. n8n's own user management gates the editor with an owner account you set on first visit. Reach the editor one of three ways:

- Put a reverse proxy (Caddy or Nginx) in front of n8n and serve the editor over HTTPS on 443. Point the domain's DNS A record at the floating IP, then set `N8N_HOST`, `N8N_PROTOCOL`, and `WEBHOOK_URL` in `/opt/n8n/.env`. This is the recommended path for routine access.
- Tunnel over SSH: `ssh -L 5678:localhost:5678 user@FLOATING_IP`, then open `http://localhost:5678`.
- Set `editor_allowed_cidr` to `YOUR_IP/32` to reach port 5678 directly from one address.

Ports 80 and 443 stay open for the reverse proxy you put in front; they carry no traffic until you add one.


n8n stores its encryption key on the data volume on first start. Workflow credentials are encrypted with that key, so a destroyed volume means unrecoverable credentials. Snapshot the volume before you resize or rebuild the host.


## Datastore

The `db_type` parameter selects the backend:

- `sqlite` (default): a file database on the data volume. No external service runs, which suits getting started and light use.
- `postgres`: points n8n at an external PostgreSQL database, such as a [self-managed PostgreSQL](/resources/iac-templates/self-managed-postgres) instance. This is the production backend and the prerequisite for n8n's queue mode. Set `postgres_host`, `postgres_db`, and `postgres_user`, then add `DB_POSTGRESDB_PASSWORD` to `/opt/n8n/.env` on the instance and run `docker compose up -d`. The password stays out of tfvars and the repo.

## When to use this pattern

Run a workflow-automation tool with a visual editor, scheduled triggers, and hundreds of service integrations on a VM you operate. n8n suits API-to-API glue, scheduled jobs, webhook handlers, and the orchestration steps around an AI agent.

For a single containerized app rather than the automation layer, use the [Next.js app template](/resources/iac-templates/nextjs-app) or the [Containerized app template](/resources/iac-templates/containerized-app). For the external datastore that backs production and queue mode, see [self-managed PostgreSQL](/resources/iac-templates/self-managed-postgres).

## Estimated cost

<PricingCompanion
  components={[
    { kind: "template", slug: "n8n-workflow", required: true },
  ]}
/>

## Template source

<TemplateSource slug="n8n-workflow" />

<TemplateResourceMap template="n8n-workflow" format="opentofu" />

## Customize this pattern

- [Customize a template's image and flavor](/docs/automation/how-to/customize-template-image-flavor)
- [Add a block volume to a template](/docs/automation/how-to/add-volume-to-template)
- [Parameterize a template with a tfvars file](/docs/automation/how-to/parameterize-template-tfvars)

## See also

- [Coolify host](/resources/iac-templates/coolify-host)
- [self-managed PostgreSQL](/resources/iac-templates/self-managed-postgres)
