DEV Community

Self-Host n8n on AWS EC2 with Docker - Install to First Login

n8n holds your keys. Stripe, your database, Slack, Google, all of it, sitting in one place. So the question of where it runs is not a detail. On the hosted plan, that pile of credentials and every workflow you build lives on someone else's server, behind their pricing, under their limits.

This episode moves it onto a box you own.

We start with a bare Amazon Linux EC2 instance. Nothing installed. By the end you have n8n running, backed by Postgres, with your own account, entirely inside your AWS account. No SaaS seat fees. No execution caps. Your data stays home.

This is Episode 2 of the n8n on AWS series. Episode 1 takes this same self-hosted n8n and hardens it on AWS: closes the public port, patches the CVE, moves secrets into AWS Secrets Manager, and locks it to a least-privilege IAM role. This episode is the step before that: getting n8n running from zero, the right way, on the box that Episode 1 then locks down. (Watch for the hardening episode next in the series.)

Launch the box

Before anything else, you need the EC2 instance itself:

  • AMI: Amazon Linux 2023.
  • Size: t3.small or bigger. n8n plus Postgres want 2 GB of RAM to be comfortable, so skip t2.micro/t3.micro (1 GB) unless you enjoy watching containers get OOM-killed.
  • Security Group: allow SSH (22) from your IP only. For this first private test you can also open 5678 to your IP only. Never open 5678 to 0.0.0.0/0 (that is the exact mistake Episode 1 exists to fix).
  • SSH in: ssh -i your-key.pem ec2-user@<PUBLIC_IP>

That is the whole "bare box" we start from. Everything below runs on that instance as ec2-user.

Get the code

Clone the repo so you have the compose file and helper scripts on the box:

git clone https://github.com/simplynadaf/self-host-n8n-on-ec2.git
cd self-host-n8n-on-ec2
Enter fullscreen mode Exit fullscreen mode

Everything after this runs from that directory. (If you would rather not clone, you can paste the compose file below into compose/docker-compose.yml by hand.)

Why not just use n8n Cloud

Because n8n is a credential aggregator. One instance can reach a dozen services. On a managed plan that concentration lives off your infrastructure, priced per seat, capped on executions. Self-hosting flips every one of those: no seat fees, no caps, full control of the version, the backups, and the network in front of it.

The tradeoff is honest. You now own the patching, the backups, and the security. Episode 1 covers the security half. This episode covers getting it up in the first place.

The stack, in one file

Two containers. That is the whole thing.

  • n8n for the editor and the workflow engine.
  • Postgres for storage, so your workflows and executions survive a restart.

Not SQLite. n8n defaults to SQLite, which is fine for a five-minute look, but it does not handle concurrent executions well and migrating off it later is a chore. Start on Postgres and skip that future afternoon.

Here is the compose file we build on camera:

services:
  n8n:
    image: n8nio/n8n:1.123.64
    restart: unless-stopped
    ports:
      - "5678:5678"
    environment:
      - N8N_SECURE_COOKIE=false
      - N8N_DIAGNOSTICS_ENABLED=false
      - N8N_PERSONALIZATION_ENABLED=false
      - N8N_ENCRYPTION_KEY=change-me-to-a-long-random-string-please
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=change-me-strong-db-password
    depends_on:
      - postgres

  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      - POSTGRES_DB=n8n
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=change-me-strong-db-password
    volumes:
      - pg_data:/var/lib/postgresql/data

volumes:
  pg_data:
Enter fullscreen mode Exit fullscreen mode

Two lines earn a note.

image: n8nio/n8n:1.123.64 is pinned, not latest. Pinning makes the build reproducible, and 1.123.64 is a patched version (it fixes an info-disclosure issue, CVE-2026-65589, where credentials passed as custom headers in LLM sub-nodes could land in execution records). Use latest and you are one silent upgrade away from a surprise.

N8N_ENCRYPTION_KEY encrypts every credential n8n stores. Set a real 32-plus character random string and keep it somewhere safe. Lose it and every saved credential becomes unrecoverable. You re-enter all of them. Back it up the moment you generate it.

One easy thing to get wrong: the password appears twice (DB_POSTGRESDB_PASSWORD in the n8n service and POSTGRES_PASSWORD in postgres). They must be the same value, or n8n cannot connect to its own database and the container just restarts in a loop.

The prerequisite nobody mentions

Here is the part that trips people up, and it is the reason the "install n8n" tutorials break on AWS.

On Amazon Linux 2023, this works:

sudo dnf install -y docker
Enter fullscreen mode Exit fullscreen mode

And this does not:

docker compose version
# docker: 'compose' is not a docker command.
Enter fullscreen mode Exit fullscreen mode

dnf install docker gives you the Docker engine. It does not include the Compose v2 plugin. So the very next command in most guides, docker compose up, fails on a fresh box. I hit this live while recording, watched n8n never come up, and traced it straight back to the missing plugin.

The fix is to drop the official plugin binary into Docker's plugin directory:

sudo dnf install -y docker
sudo mkdir -p /usr/local/lib/docker/cli-plugins
sudo curl -fsSL \
  https://github.com/docker/compose/releases/download/v2.29.7/docker-compose-linux-x86_64 \
  -o /usr/local/lib/docker/cli-plugins/docker-compose
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
sudo systemctl enable --now docker
Enter fullscreen mode Exit fullscreen mode

Now check both:

sudo docker --version
# Docker version 25.0.14, build 0bab007
sudo docker compose version
# Docker Compose version v2.29.7
Enter fullscreen mode Exit fullscreen mode

Two version banners. That is the moment you know the box is actually ready.

Bring it up

With Docker and Compose in place, edit the two passwords and the encryption key in the compose file, then:

cd compose
sudo docker compose up -d
sudo docker compose ps
Enter fullscreen mode Exit fullscreen mode

First run pulls the n8n and Postgres images, then starts both. Give it twenty to forty seconds. Then check it is answering:

curl -s -o /dev/null -w 'n8n -> HTTP %{http_code}\n' http://localhost:5678
# n8n -> HTTP 200
Enter fullscreen mode Exit fullscreen mode

200 means n8n is up and serving. On the recording, that check came back green on the first try once Compose was actually installed.

First login

Open http://<PUBLIC_IP>:5678 in a browser. On a fresh instance n8n shows the setup wizard: create your owner account, email and a strong password. Submit, and you land on the canvas.

That is your n8n. Private, on your box, ready for the first workflow.

One small thing you will notice in the compose file: N8N_SECURE_COOKIE=false. That is only so first login works over plain HTTP on a raw IP while you are testing. It is a development shortcut, not a setting you keep. In production you sit n8n behind HTTPS and this goes away.

Do not skip this before you expose it

The compose here publishes port 5678 directly. That is fine for a private test where the Security Group only lets your IP reach the box. It is not fine for the open internet. An n8n editor reachable at http://your-ip:5678 is an editor anyone can find.

Before you point a domain at this or open the Security Group, harden it:

  1. Keep n8n patched (1.123.64 or newer).
  2. Stop publishing 5678. Use expose so it is reachable only inside Docker.
  3. Put Caddy in front for automatic TLS, and restrict the editor to your admin IP. Leave only /webhook/* public.
  4. Move the encryption key and DB password into AWS Secrets Manager, read through a least-privilege IAM role.
  5. Security Group: allow 22 (your IP), 80, 443. Never 5678 to 0.0.0.0/0.

That whole checklist is the hardening episode (Episode 1) of this series. If this box is going anywhere near the public internet, that is your next read.

Stop and start

Your data lives in the pg_data volume, so you can stop the stack without losing anything:

cd compose
sudo docker compose down     # stop
sudo docker compose up -d    # start again
Enter fullscreen mode Exit fullscreen mode

down stops the containers and keeps the volume. Your workflows and account are still there when you bring it back up. To also drop the data, that is down -v, and only when you mean it.

What you have now

  • n8n running on an EC2 box you control, backed by Postgres.
  • A pinned, patched image instead of a moving latest target.
  • An encryption key you actually set and saved.
  • A clear line for what to do before this ever faces the internet.

Where the series goes next

Three episodes, one arc:

  • Episode 1, harden it: Secure Self-Hosted n8n on AWS. TLS, closed editor port, Secrets Manager, least-privilege IAM.
  • Episode 2 (this one), get it running from zero and log in.
  • Episode 3, give it a brain. We wire this same n8n to Amazon Bedrock and build a real AI agent on the canvas, with the model running in your account and no OpenAI key anywhere. That is where self-hosting pays off: your automation and your model, both in your boundary.

The compose file, the install and verify scripts, and the full setup notes are in the repo:

GitHub logo simplynadaf / n8n-bedrock-agent-on-aws

Self-host n8n on AWS EC2 and give it a brain: a real tool-using AI Agent backed by Amazon Bedrock (Nova Pro) - no OpenAI key. Least-privilege IAM, importable workflow, and the live empty-to-populated model dropdown story.

πŸ€– n8n + Amazon Bedrock on AWS (2026)

Self-host n8n on an EC2 box from scratch, then give it a brain: a real tool-using AI Agent backed by Amazon Bedrock - no OpenAI key, no third-party API. Your model, your data, your AWS account.

n8n AWS Bedrock Docker License: MIT

Stars Forks Issues


⭐ If this helped you run n8n + Bedrock in your own account, give it a star! It helps others find it.

Why This β€’ What You Build β€’ Getting Started β€’ The IAM Story β€’ FAQ β€’ Contributing

πŸ“– Table of Contents

πŸ€” Why This

Most "AI in n8n" tutorials reach for…

The video walks the whole thing, from the empty box to the canvas.


Follow me for more on AWS architecture, DevOps, and AI Infrastructure:
Portfolio | LinkedIn | Dev.to | YouTube | Email | AWS Builder Center | X

Top comments (0)