How I setup my n8n instance
n8n is freaking awesome, and it's allowed me to prototype various MVPs without actually coding anything substantial. I don't have to think about infra, and I can use it as long as it's not directly user-facing.
Try n8n. I beg you. It's free, and you can run it on a spare VPS that you have (or on your spare gaming PC).
To setup n8n, you have 2 options:
- Self-host it for free (preferably using Docker); or
- Use the hosted plans on n8n.io and pay $20.
The former is what we'll focus on for this post. If you're using the hosted plans, then feel free to skip this post entirely (but thanks for reading anyways haha).
What | How much | Why |
---|---|---|
OpenAI API account | 5 cents per month (at most) | To extract information from your transaction emails |
Google Cloud Credentials | Free | To provide n8n access to your Google Sheets and GMail |
n8n | Free Server costs: $5 if you're self-hosting on a 1GB VPS $20 if you're using hosted n8n | To do the automation (duh). Based on testing, n8n is going to take up to 100MB-200MB of RAM for standard usages (without Selenium or having to store binary files) |
Side note: self-host or hosted plans?
If you're using it for yourself (e.g. to track your personal expenses), self-host it.
If you're going to be using it for your company, but n8n isn't part of your critical business flows (e.g. less than 3 users editing the same workflow), or if you have a dev that can maintain it for you in-house, then self-host it.
For everyone and everything else - CEOs, non-technical folks - use the hosted plans. They give you things like SSO (so that your employees have to use their corporate account to login), and some things that are already setup out of the box (like "Sign-in With Google").
TLDR this is my n8n setup
- I host my n8n instance on a AWS Lightsail VPS - I like to keep all of my pet projects under the same provider to simplify my own infra cost tracking.
- I use
docker-compose.yml
and aDockerfile
to spin up a n8n container. Note that I need theDockerfile
to add additional dependencies to the base n8n image (so that I can run shell scripts on n8n to unencrypt PDFs) - you can omit this if you want. - I have a Caddy container that acts as the main reverse proxy for all of my containers (I have a bunch of containers other than n8n sitting on the same VPS).
My n8n setup on Docker
My favourite setup is to use Docker Compose to spin up my stacks. For one, docker-compose.yml
files are readable once you're used to it, and it's easy to configure most images using environment variables. It's also really nice to have Docker manage n8n's lifecycle, such as restarting your n8n container when it crashes, and to manage the image versioning itself (e.g. you just need to do a docker-compose pull; docker-compose up -d
to update your n8n instance).
n8n.io provides an official tutorial to help you get started, but if you ceebs reading the whole post, you can copy my docker-compose.yml
file.
services:
initContainer:
image: busybox
command: ["sh", "-c", "chown -R 1000:1000 /home/node/.n8n"]
volumes:
- ~/.n8n:/home/node/.n8n
n8n:
image: docker.n8n.io/n8nio/n8n
# use your own Dockerfile if you want
# build:
# context: .
# dockerfile: n8n.Dockerfile
restart: unless-stopped
ports:
- "127.0.0.1:5678:5678"
environment:
- N8N_HOST="https://yourn8ndomain.com"
- N8N_PORT=5678
- N8N_PROTOCOL=https
- NODE_ENV=production
- N8N_PATH
- N8N_PROXY_HOPS=1 # needed since I'm using Caddy
- WEBHOOK_URL="https://yourn8ndomain.com/"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ~/.n8n:/home/node/.n8n
depends_on:
initContainer:
condition: service_completed_successfully
networks: # connect to my Caddy network - optional
- caddy_network
networks:
caddy_network: # connect to my pre-existing Caddy network
external: true
name: caddy_network
A custom Dockerfile for your own n8n image could look something like this
FROM docker.n8n.io/n8nio/n8n
USER root
# qpdf is just a thing I need to decrypt PDFs - feel free to ignore
RUN apk --update add qpdf
USER node
Optional: Caddy
You do not need Caddy. I just like Caddy because it's one of the easiest reverse proxies to setup - much easier compared to Nginx / Apache's httpd. It also comes with a painless HTTPS cert generation process (through LetsEncrypt).
If you don't want to use Caddy, then omit the Caddy-related configurations.
I use Caddy to act as the gateway to various services that I have on my VPS (having one Caddy serve everything is much more efficient than having multiple Caddy instances). This is how my Caddy's docker-compose looks like:
services:
caddy:
image: caddy:latest
container_name: caddy
restart: unless-stopped
ports:
- '80:80'
- '443:443'
- '8082:8082'
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
networks:
- caddy_network
extra_hosts: # ngl I can't remember what this does - feel free to omit
- 'host.docker.internal:host-gateway'
deploy:
resources:
limits:
memory: 100M
volumes:
caddy_data:
caddy_config:
networks:
caddy_network:
name: caddy_network # note that service containers will manually bind themselves to this network
Roughly speaking, the architecture somewhat looks like this - any services that wants to be exposed by Caddy will have to join caddy_network
(see my n8n docker-compose file):
My Caddyfile roughly looks like this
{
# Global options block
email myemail@gmail.com # Replace with your email for Let's Encrypt notifications
# HTTPS is enabled by default
}
myn8ndomain.com {
handle {
reverse_proxy http://n8n:5678
}
}
Do note that before you let Caddy register your SSL certs, you have to have already setup your DNS A record to point to your VPS's IP address. Otherwise, Caddy can't verify that you own myn8ndomain.com
!
Once n8n is running on your Docker container
...That's pretty much it. Just access the URL you've set for your n8n instance and n8n should guide you through its configuration process (which, if I recall correctly, is just setting up your initial username and password).
Caveats: Security
This is not the most secure setup in the world, because n8n's self-hosted version only supports the standard username-password authentication. n8n doesn't have that much of an anti-abuse mechanism built into it by default. But - not to worry - there are some things that you can do:
- Use Caddy to restrict accessing n8n to specific IP addresses (yay Caddy!). I restrict my instance so that it's only accessible from my personal VPN-slash-bastion server.
- Setup MFA on n8n. Pretty easy to do - you just need your standard TOTP app like Google Authenticator.
- Setup rate-limiting to prevent abuse (and potentially IP blacklists). I personally haven't had time to suss this part out yet, so the exercise is left up to the reader.