n8n, Open WebUI and AI apps#
The hosted versions of these tools are convenient, right up until one of three things happens: you hit the quota, the price scales with usage, or you would rather not send the data you are processing to someone else's server.
All three are solved by running them yourself. This page shows how.
The shortcut: ask your assistant
If you have connected VeriTeknik MCP to your AI assistant (Claude, ChatGPT, Cursor...), just say it:
"Open a small server with n8n installed, and tell me the monthly price first."
Your assistant shows you the price and, once you agree, opens the server with n8n already installed. The same works for Open WebUI, LibreChat, AnythingLLM, Flowise and Activepieces, and you can ask for the domain and HTTPS in the same conversation. ChatGPT has no tool for opening servers; there, use the panel route below. The permissions to turn on are in the deployment guide.
If you do not use an assistant, the same applications are one-click installs in the panel: once you have a server, just pick the application.
This page is for installing something not on that list, or for understanding how it works.
How much server do you need?#
| Application | Minimum | Comfortable |
|---|---|---|
| n8n (automation) | 1 vCPU / 2 GB | 2 vCPU / 4 GB |
| Open WebUI (external API) | 1 vCPU / 2 GB | 2 vCPU / 4 GB |
| Open WebUI + Ollama (local model) | 4 vCPU / 16 GB | needs a GPU |
Installing n8n#
Compose is the cleanest way. /opt/n8n/docker-compose.yml:
services:
n8n:
image: docker.n8n.io/n8nio/n8n:latest
restart: unless-stopped
ports:
- "127.0.0.1:5678:5678"
environment:
- N8N_HOST=n8n.example.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://n8n.example.com/
- GENERIC_TIMEZONE=Europe/Istanbul
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:
Generate the encryption key into .env:
cd /opt/n8n
echo "N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)" > .env
chmod 600 .env
docker compose up -d
Do not lose N8N_ENCRYPTION_KEY
n8n encrypts the credentials of every service you connect with this key. Lose it and every stored credential becomes unreadable and has to be re-entered. Back it up.
The 127.0.0.1:5678 binding is deliberate - see why it matters.
Installing Open WebUI#
/opt/openwebui/docker-compose.yml:
services:
open-webui:
image: ghcr.io/open-webui/open-webui:main
restart: unless-stopped
ports:
- "127.0.0.1:8080:8080"
environment:
- OPENAI_API_BASE_URL=https://api.veriteknik.com/v1
- OPENAI_API_KEY=${OPENAI_API_KEY}
- WEBUI_SECRET_KEY=${WEBUI_SECRET_KEY}
volumes:
- openwebui_data:/app/backend/data
volumes:
openwebui_data:
cd /opt/openwebui
{
echo "OPENAI_API_KEY=sk-..."
echo "WEBUI_SECRET_KEY=$(openssl rand -hex 32)"
} > .env
chmod 600 .env
docker compose up -d
Put a domain in front#
A subdomain per application is cleanest: n8n.example.com, chat.example.com.
Create an A record for each, then Nginx:
server {
listen 80;
server_name n8n.example.com;
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300s;
}
}
WebSockets and long requests
The Upgrade / Connection headers are required for n8n's live execution view and Open WebUI's streaming responses. proxy_read_timeout must be raised too; the 60 second default cuts off a long AI response mid-stream.
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d n8n.example.com
Do these, without exception#
Turn on authentication. Both applications ask you to create an admin account on first load. Do it immediately - an n8n left open to the internet is a machine anyone can run workflows on, as you.
Take backups. The data lives in Docker volumes:
docker run --rm \
-v n8n_n8n_data:/data \
-v /opt/backup:/backup \
alpine tar czf /backup/n8n-$(date +%F).tar.gz -C /data .
A panel snapshot is also an option, and easier.
Keep them updated. These projects move fast:
cd /opt/n8n && docker compose pull && docker compose up -d && docker image prune -f
With Morpheus
"update n8n and clean up the old images"
"back up n8n on the first of every month and let me know"
Checklist#
- [ ]
docker compose ps→Up - [ ]
sudo ss -tlnp→ app ports on127.0.0.1only - [ ] Admin account created, the app is not left open
- [ ]
https://n8n.example.comopens with the padlock - [ ] Live execution / streaming responses work (WebSocket headers correct)
- [ ]
N8N_ENCRYPTION_KEYand.envfiles backed up - [ ] A backup method is chosen and has been tested once