Back
DevOps

How I Deployed n8n in 10 Minutes with Railway (Production-Ready Setup)

I wanted n8n running. Not a weekend project.

I love automation. I don’t love babysitting servers.

When I decided to use n8n seriously (not just locally), I had two options: self-host it properly or use n8n Cloud. Cloud is fine, but I prefer owning the stack. More control. Lower cost at scale. No vendor lock-in.

The problem? I didn’t want to spend hours configuring Docker, reverse proxies, SSL, volumes, and PostgreSQL.

So I used Railway.

Ten minutes later, I had n8n running in production with persistence and HTTPS. This is exactly how I did it.


Why Railway instead of Docker on a VPS?

You can absolutely deploy n8n with Docker on a VPS. I’ve done it before.

But here’s what that usually means:

  • Provision server
  • Install Docker
  • Configure volumes
  • Configure Postgres
  • Setup reverse proxy
  • Setup SSL
  • Handle updates
  • Pray you don’t misconfigure something

Railway removes 90% of that friction.

What I like about Railway:

  • One-click deploy templates
  • Managed Postgres
  • Persistent volumes
  • Automatic HTTPS
  • Simple environment variables
  • No infra maintenance

For side projects, MVPs, or internal automation tools, it’s perfect.


Step 1 — Deploy n8n from the Railway template

Railway has an official n8n template:

👉 https://railway.com/deploy/n8n

Click Deploy on Railway.

You’ll be prompted to:

  1. Create a new project
  2. Connect your GitHub account (if not connected)
  3. Confirm the deployment

Railway automatically provisions:

  • A web service running n8n
  • A PostgreSQL database
  • Persistent storage

You don’t need to write Dockerfiles. It’s already handled.

After a couple of minutes, the service builds and deploys.

That’s it. n8n is technically running.

But not production-ready yet.


Step 2 — Configure environment variables properly

This is the part that matters.

By default, the template works. But I always configure these variables explicitly.

Go to:

Project → Service → Variables

And define the following.


Define the public URL

This is critical for webhooks to work correctly.

N8N_HOST=your-app-name.up.railway.app
WEBHOOK_URL=https://your-app-name.up.railway.app/

If you don’t set this properly, webhooks will fail silently or generate wrong callback URLs.

If you use a custom domain later, update these values.


Encryption key (don’t skip this)

n8n encrypts credentials. If this key changes, your credentials break.

Set it manually:

N8N_ENCRYPTION_KEY=generate-a-long-random-string-here

I usually generate one with:

openssl rand -hex 32

Save it somewhere safe.


Step 3 — Persistent storage (verify it)

Railway’s template already mounts a volume.

But I always verify that /home/node/.n8n is persisted.

In Railway:

Service → Settings → Volumes

You should see a mounted volume.

This ensures:

  • Workflows persist
  • Credentials persist
  • Execution data persists

Without this, a redeploy could wipe everything.


Railway makes this easy.

Go to:

Settings → Domains → Add Custom Domain

Add something like:

automations.yourdomain.com

Then update your environment variables:

N8N_HOST=automations.yourdomain.com
WEBHOOK_URL=https://automations.yourdomain.com/

Railway auto-generates SSL certificates.

No Certbot. No Nginx. No pain.


What the architecture looks like

This is what Railway creates:

Project
├── n8n Service (Docker container)
│   ├── Persistent Volume
│   └── Environment Variables
└── PostgreSQL Database

That’s it.

No reverse proxy layer to manage. No manual database wiring. No firewall headaches.


Common mistakes I’ve seen (and made)

1. Forgetting N8N_ENCRYPTION_KEY

You redeploy. Credentials break. You panic.

Always set it manually.


2. Wrong WEBHOOK_URL

If you switch to a custom domain and forget to update:

WEBHOOK_URL

Your webhooks keep pointing to the Railway default domain.

Everything fails silently.


3. Not enabling basic auth

n8n exposes:

  • All workflows
  • Credentials UI
  • Execution logs

If you don’t protect it, bots will find it.

At minimum, use basic auth. Ideally, also restrict access by IP if needed.


4. Free tier sleep behavior

If you’re on Railway’s cheaper plans, services may sleep after inactivity.

That means:

  • First webhook after idle = slow
  • Scheduled workflows might delay

If automation is business-critical, don’t rely on the lowest tier.


Performance and cost

My current setup:

  • 512MB–1GB RAM
  • PostgreSQL included
  • Custom domain
  • Moderate automation load

It costs less than a typical VPS + time spent managing it.

And my time is more expensive than hosting.

That’s the real equation.


When I wouldn’t use Railway

Let’s be honest.

I wouldn’t use it if:

  • I needed strict enterprise networking
  • I required on-premise deployment
  • I had extreme workload scale
  • I needed complex container orchestration

In that case, I’d go Kubernetes or a dedicated Docker setup.

But for:

  • Startups
  • Internal tools
  • Agencies
  • Indie hackers
  • Personal automation systems

Railway + n8n is ridiculously efficient.


Local development vs Railway

I still use local Docker for testing workflows:

docker run -it --rm \
  -p 5678:5678 \
  n8nio/n8n

Then once stable, I replicate environment variables in Railway.

This gives me:

  • Fast experimentation locally
  • Stable production deployment remotely

Best of both worlds.


The real reason I like this setup

It removes friction.

Automation tools should save time. Not consume it.

With Railway:

  • No server maintenance
  • No SSL configuration
  • No Docker babysitting
  • No complex infra decisions

Just deploy and build workflows.

That’s the point.


Final thoughts

If you want n8n running today, use the Railway template and configure it properly. Ten minutes and you’re live.

Own your automation stack. Skip the DevOps headache.

Then focus on what actually matters: building workflows that do real work.