How to Install Self-Hosted n8n on a VPS with Docker
You install self hosted n8n on a VPS by installing Docker Engine and the Compose plugin, running n8n with PostgreSQL from one compose file, and putting Caddy in front of it for HTTPS on your own subdomain. On a fresh Ubuntu server the whole job takes about 30 minutes, plus whatever time your DNS needs to catch up. Most of that time goes to the domain and the security steps, not to n8n itself.
We run servers across 25 worldwide locations, and 20+ years of that work has taught us one thing about automation tools. They start small and then quietly become the machine that sends your invoices, your leads and your alerts. So build them like they matter from day one.
This guide follows the official n8n Docker Compose documentation and then adds what a real server needs: PostgreSQL, a locked encryption key, a firewall, backups and a safe update routine.
One honest warning first. Self hosting means you own the patching, the backups and the security. n8n says the same thing in its own docs, and if that sounds like a chore you do not want, n8n Cloud is a fair choice.
What Do You Need Before Installing n8n on a VPS?
You need a Linux VPS running Ubuntu with at least 2 GB of RAM, SSH access with a sudo user, a domain or subdomain you control, and about 30 minutes. Docker and Docker Compose get installed in the next section. Everything else runs from the command line on that server.
Choosing a suitable VPS operating system and provider
Pick Ubuntu Server LTS. Ubuntu 24.04 is a safe choice because Docker publishes packages for it and nearly every tutorial you will search for assumes it. Debian works almost the same way if you prefer it.
The provider matters more than the distro. Check that the plan uses full virtualization such as KVM. Docker needs a real Linux kernel to create containers, and some container based VPS plans block it. Ask support before you order, ours included. That one question can save you a wasted afternoon.
Location counts as well. n8n spends its life making API calls, so put the server close to the apps your workflows talk to most. Our multi location hosting page shows how we spread across 25 worldwide locations, and our USA VPS plans are one place to start if your tools live in North America.
Understanding CPU, RAM and storage requirements
n8n itself is light. One vCPU and 2 GB of RAM runs a small instance with PostgreSQL and Caddy without trouble. That is our practical starting point, not an official n8n minimum, and it assumes workflows that move small amounts of JSON between apps.
Memory is where people get caught. A workflow that loads a big file, a long spreadsheet or thousands of items at once can eat RAM fast, and Linux will kill a process when memory runs out. If you plan heavy data work or AI document handling, start at 4 GB.
Storage grows quietly. n8n keeps execution history in the database, and every run adds to it unless you prune old data. Twenty to forty GB is comfortable for most small teams.
Disk speed matters too, because PostgreSQL writes constantly. We explain the gap in our guide to NVMe drives versus SSDs. Once one VPS is not enough, a dedicated server gives you room to run n8n with separate workers.
Preparing an Ubuntu VPS and SSH access
Log in as root once, create a normal user, and do everything else as that user. Running a whole deployment as root is a habit that hurts later.
ssh root@203.0.113.10
adduser deploy
usermod -aG sudo deploy
rsync –archive –chown=deploy:deploy ~/.ssh /home/deploy
The last command copies your SSH key to the new user. Now open a second terminal and log in as deploy before you close the root session. If that login fails, you still have a way back in. People lock themselves out at exactly this step more often than anywhere else.
Replace the example address with your server’s real IP. The 203.0.113.0 range is reserved for documentation, so it will never point at a live machine.
Connecting a domain or subdomain to your VPS
Use a dedicated subdomain such as n8n.example.com rather than your root domain. Your root domain probably serves a website already, and n8n’s own docs recommend a dedicated subdomain for the same reason.
Create an A record for the subdomain that points at your server’s IPv4 address, and set the TTL low, around 300 seconds, so mistakes fix themselves quickly. Do this now, before you install anything. DNS is the one step you cannot speed up, so let it propagate while you work through the Docker steps.
Skip the AAAA record unless your server really answers on IPv6. A stale or wrong AAAA record is a sneaky cause of certificate failures later.
Understanding Docker, Docker Compose and n8n
n8n is an open source workflow automation platform. You connect apps, APIs and AI services as nodes on a canvas, and n8n runs the chain when a trigger fires. A billing system can send a webhook, n8n can enrich the data, and a Slack message goes out a second later.
Docker packages n8n and its dependencies into a container so it runs the same way on every server. Docker Compose describes several containers in one YAML file: here n8n, PostgreSQL and Caddy. You start or stop the whole stack with a single command.
Hosting companies use this stack too. A reseller can trigger welcome emails and ticket routing from WHMCS events, and our reseller hosting plans suit anyone building that kind of business. If your workflows send email, remember that mail from a bare VPS often lands in spam, which is why our MailChannels corporate email page is worth a read.
How Do You Install Docker and Docker Compose on an Ubuntu VPS?
Add Docker’s official apt repository, install the Docker CE packages and the Compose plugin, then confirm both with a version check. It takes about five minutes. Use Docker’s own repository instead of the docker.io package from Ubuntu, because the Docker repository ships current releases and the Compose plugin together.
Updating Ubuntu packages and system dependencies
Start with a clean, current system. Updates fix security holes, and installing Docker on a half updated server invites odd dependency errors. Fresh VPS images are often weeks old, so there is almost always something waiting.
sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl
[ -f /var/run/reboot-required ] && echo “Reboot needed”
If the last line prints a message, reboot with sudo reboot and log back in. A new kernel does nothing until the machine restarts. Skipping this is harmless today and confusing in three weeks.
The ca-certificates and curl packages are the only extras Docker’s repository setup needs. Keep the list short. Every package you add to a server that holds API keys is one more thing to patch.
Installing Docker Engine from the official repository
These are the commands from Docker’s Ubuntu instructions at the time of writing. Docker occasionally changes the format, so compare against the official Docker Engine install page before you paste.
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo “deb [arch=$(dpkg –print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo \”${UBUNTU_CODENAME:-$VERSION_CODENAME}\”) stable” | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
A one line convenience script exists too, and it works. We still prefer the repository method because you can see exactly what gets added and apt upgrade keeps Docker current afterwards.
The key file and the repository entry are the two things this block creates. If apt later complains about a missing signature, the key file is the first place to look. The architecture and release name are filled in automatically, so the same block works on a standard x86 server and on ARM.
Installing and verifying the Docker Compose plugin
The Compose plugin arrived with the packages above. You run it as docker compose with a space. The old standalone command, written with a hyphen, was the previous generation and old tutorials still use it.
docker –version
docker compose version
Both commands should print a version number. If the second one says it is not a docker command, the plugin package did not install, so rerun the apt install line. Do not mix the old and new commands in one project. Pick the plugin and stay with it.
You do not need to install anything else for Compose. There is no separate download and no manual upgrade step, because the plugin updates with the rest of Docker through apt.
Checking Docker permissions and service status
Confirm the service is running and set to start on boot. Then decide whether your user may run Docker without sudo.
sudo systemctl enable –now docker
sudo systemctl status docker –no-pager
sudo usermod -aG docker $USER
newgrp docker
Here is the catch. Membership in the docker group is effectively root access on that server, because anyone who can start containers can mount the whole filesystem. Add only people you would trust with the root password. On a single admin VPS this is fine. On a shared one, keep using sudo.
Log out and back in if the group change does not apply straight away. The newgrp command is a shortcut for the current session only, so a fresh login is the reliable way to confirm it stuck.
Testing Docker with a simple container
Run the tiny hello world image before you touch n8n. If this works, your Docker install, your network access to the registry and your permissions are all sound.
docker run –rm hello-world
You should see a short message that begins with Hello from Docker. A permission denied error means your group change has not taken effect, so log out and back in. A message about being unable to reach the Docker daemon means the service is not running, which sends you back to the status check above.
The –rm flag removes the test container after it exits, so nothing is left behind to clean up. It also pulls a small image from Docker Hub, which proves your server can reach the registry. Every later step depends on that, since n8n and PostgreSQL arrive the same way.
How Do You Install n8n Using Docker Compose?
Create a project folder, add an .env file and a compose.yaml that defines n8n and PostgreSQL, then run docker compose up -d. Named Docker volumes keep your data safe across restarts and updates. We use PostgreSQL instead of the default SQLite database because it copes better with concurrent runs, larger histories and proper backups.
Creating a dedicated directory for the n8n installation
Keep everything for this deployment in one folder. One folder means one thing to back up, one thing to move to a new server and one place to look when something breaks.
mkdir -p ~/n8n-compose/local-files
cd ~/n8n-compose
sudo chown -R 1000:1000 local-files
The local-files folder is shared with the container so workflows can read and write files on the host. The n8n container runs as a user with ID 1000, and a folder owned by root will throw permission errors inside n8n. The chown line prevents that. It is a ten second fix that otherwise costs a confusing hour.
Name the folder anything you like, but keep the name simple and avoid spaces. We use n8n-compose because it says what is inside. Compose also uses the folder name as a prefix for your volumes and network, so a clear name makes docker volume ls easier to read months from now.
Preparing the Docker Compose configuration file
Create the .env file first. It holds every value that changes between servers, so the compose file itself stays clean. Generate the two secrets with openssl rand -hex 32, run once for each.
# .env
DOMAIN_NAME=example.com
SUBDOMAIN=n8n
GENERIC_TIMEZONE=Europe/Berlin
SSL_EMAIL=you@example.com
POSTGRES_USER=n8n
POSTGRES_DB=n8n
POSTGRES_PASSWORD=paste_first_random_value_here
N8N_ENCRYPTION_KEY=paste_second_random_value_here
Next comes compose.yaml. This first version runs n8n and PostgreSQL only. The n8n port is bound to 127.0.0.1, which means only the server itself can reach it. We add HTTPS in the next section.
services:
postgres:
image: postgres:16
restart: always
environment:
– POSTGRES_USER=${POSTGRES_USER}
– POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
– POSTGRES_DB=${POSTGRES_DB}
volumes:
– postgres_data:/var/lib/postgresql/data
healthcheck:
test: [“CMD-SHELL”, “pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}”]
interval: 5s
timeout: 5s
retries: 10
n8n:
image: docker.n8n.io/n8nio/n8n:stable
restart: always
ports:
– “127.0.0.1:5678:5678”
environment:
– DB_TYPE=postgresdb
– DB_POSTGRESDB_HOST=postgres
– DB_POSTGRESDB_PORT=5432
– DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
– DB_POSTGRESDB_USER=${POSTGRES_USER}
– DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
– N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
– N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
– NODE_ENV=production
– GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
– TZ=${GENERIC_TIMEZONE}
volumes:
– n8n_data:/home/node/.n8n
– ./local-files:/files
depends_on:
postgres:
condition: service_healthy
volumes:
postgres_data:
n8n_data:
The stable tag follows n8n’s recommended release for production. The beta tag runs newer code that n8n itself warns may be unstable, so leave it for a test server.
Save the file, and check that it sits in the same folder as the .env file. Compose reads that .env automatically and fills in every dollar sign variable. If you see a warning that a variable is not set, a name in .env does not match the name in compose.yaml, and the typo is almost always one letter.
Configuring environment variables and timezone settings
Every line in the environment block does a job. The DB_ variables tell n8n to use PostgreSQL and where to find it, and the hostname postgres works because Compose puts both containers on a private network where each service name resolves to its container.
N8N_ENCRYPTION_KEY is the one to respect. n8n uses it to encrypt the credentials you save, such as API keys and passwords. If you leave it unset, n8n generates a key and writes it into the data volume, which works until the day you rebuild the server and the key is gone.
Timezone deserves a minute of thought. GENERIC_TIMEZONE controls when Schedule and Cron nodes fire, and n8n falls back to New York if you set nothing. A workflow you meant to run at 9 in the morning your time will run at 9 in New York, and nobody notices for a week. Set TZ to the same value so the container clock matches.
Setting up persistent storage for workflows and credentials
Two named volumes hold everything that matters. The postgres_data volume stores workflows, credentials and execution history. The n8n_data volume stores n8n’s own config files, including the encryption key if you did not set one yourself.
Here is the rule that protects you. docker compose down stops and removes containers but leaves volumes alone. docker compose down -v deletes the volumes too, and with them every workflow you built. Make a habit of reading the command twice before you press Enter.
SQLite is the default database, and it lives as a single file inside n8n_data. That is fine for a quick trial. For anything you depend on, start on PostgreSQL, because moving a live instance from SQLite to PostgreSQL later is a migration project, not a setting.
Starting the n8n container and checking its status
Bring the stack up in the background, then check it.
docker compose up -d
docker compose ps
docker compose logs -f n8n
curl http://127.0.0.1:5678/healthz
The first start takes longer, because n8n runs its database migrations. Wait until the logs say the editor is accessible, then press Ctrl+C to leave the log view. The containers keep running.
The curl command should return a small JSON reply with an ok status. That proves n8n is alive and talking to PostgreSQL. You cannot open it in a browser yet, because the port only listens on the server itself. That changes in the next section.
If a container shows as restarting instead of running, do not keep rerunning the same command. Read the log first. The error is usually in the first twenty lines after the start, and it tells you what n8n could not find.
How Do You Configure a Domain and HTTPS for Self-Hosted n8n?
Point an A record at your VPS, add Caddy as a reverse proxy in the same compose file, and Caddy will request and renew a free Let’s Encrypt certificate on its own. Then set the host, protocol and webhook URL so n8n builds correct public links. Caddy needs ports 80 and 443 open on the server.
Pointing a subdomain to the VPS IP address
You created the record earlier. Now confirm the world can see it. Run this from your own computer, not from the server.
dig +short n8n.example.com
The answer must be your VPS IP and nothing else. If it is empty or shows an old address, wait and ask again. Propagation can take minutes or a few hours depending on TTL and the resolver.
If you manage DNS through CloudFlare, set the record to DNS only, the grey cloud, while the certificate is issued. You can switch the proxy on afterwards, but then set the SSL mode to Full strict, or you may land in a redirect loop.
Do not skip this check. Asking Let’s Encrypt for a certificate before DNS is right counts as a failed attempt, and the rate limits punish repeated failures for about an hour.
Configuring a reverse proxy with Caddy or Nginx
n8n speaks plain HTTP on port 5678. A reverse proxy sits in front, handles HTTPS and forwards clean traffic to n8n. We use Caddy because it fetches and renews certificates by itself with three lines of config. Nginx works fine, but you add Certbot and a longer server block, including the headers that keep websocket connections alive. n8n’s own docs use Traefik for the same job, and any of the three is a sound choice.
Create a file called Caddyfile in the project folder. Write your real domain here, because Compose does not fill variables into this file.
n8n.example.com {
reverse_proxy n8n:5678 {
flush_interval -1
}
}
The flush_interval line stops Caddy from buffering streamed responses, which keeps the editor feeling live. Now add Caddy as a third service in compose.yaml, and add its volumes at the bottom.
caddy:
image: caddy:2
restart: always
ports:
– “80:80”
– “443:443”
volumes:
– ./Caddyfile:/etc/caddy/Caddyfile
– caddy_data:/data
– caddy_config:/config
depends_on:
– n8n
volumes:
postgres_data:
n8n_data:
caddy_data:
caddy_config:
Setting up an SSL/TLS certificate
With Caddy there is almost nothing to do. When it starts and sees a domain name in the Caddyfile, it contacts Let’s Encrypt, proves it controls the domain over port 80, and installs the certificate. Renewals happen in the background before expiry.
Open the ports first. If UFW is already active, run sudo ufw allow 80/tcp and sudo ufw allow 443/tcp. Some VPS control panels also have their own network firewall outside the server, so check there too.
Caddy keeps its certificates in the caddy_data volume. Do not delete that volume casually. A rebuilt Caddy has to request fresh certificates, and doing that repeatedly while you experiment is a quick route to a rate limit.
Configuring the public webhook URL and environment settings
Behind a proxy, n8n does not know its own public address. Left alone, it shows webhook URLs that start with localhost, and no outside service can call those. Add these lines to the environment block of the n8n service.
– N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
– N8N_PORT=5678
– N8N_PROTOCOL=https
– N8N_WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
N8N_WEBHOOK_URL exists from n8n 2.30.0. On older versions the variable is called WEBHOOK_URL, so check which version your image runs before you copy. The trailing slash matters, and so does the https.
Once this is right, every Webhook node shows a production URL under your own domain. Third party services such as payment tools, form builders and CRMs can then reach your workflows.
Testing secure access through the custom domain
Apply everything with one command, then open the site.
docker compose up -d
docker compose logs caddy –tail 30
curl -I https://n8n.example.com
Browse to https://n8n.example.com and look for the padlock. Plain HTTP should redirect to HTTPS on its own. If the page loads, n8n shows its owner setup screen.
Create the owner account immediately. The first person to reach that screen becomes the owner, and your server is public now. Use a long password from a password manager.
Then run a quick proof. Build a workflow with a Webhook node, activate it, and call its production URL with curl from your laptop. If you get a response and see the run in the Executions tab, the stack works from the outside.
How Do You Secure and Maintain Your n8n VPS Installation?
Open only ports 22, 80 and 443, protect the editor with a strong owner password, keep the encryption key somewhere safe and separate, back up the database on a schedule, and update by pulling a new image after a fresh backup. n8n stores API keys for your other systems, so a careless install is a master key sitting on the open internet.
Restricting public access to unnecessary ports
A firewall with three open ports is enough here. Add the SSH rule before you turn the firewall on, or you will cut off your own session.
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
There is a Docker quirk you should know about. Ports that Docker publishes can bypass UFW rules, because Docker writes its own firewall entries. That is why this setup never publishes PostgreSQL, and why n8n is bound to 127.0.0.1. Only Caddy faces the internet.
Go one step further if you can. Switch SSH to key login only, and consider fail2ban to slow down password guessing. Both take minutes.
Run sudo ufw status verbose once more after a reboot, and test your SSH login from a second terminal. A firewall rule you never verified is only a guess. This takes two minutes and gives you a clear answer.
Protecting n8n with authentication and strong credentials
n8n has built in user management, and the owner account you made earlier is the front door. Use a long unique password, turn on two factor authentication in your user settings if your version offers it, and give each teammate their own login instead of sharing the owner account.
Old tutorials mention basic auth variables for the editor. Those were removed in n8n 1.0, so adding them today does nothing and gives a false sense of safety.
For an extra layer, restrict the editor to your own IP address at the proxy while leaving the webhook paths open to the world. Webhooks must be reachable by outside services, but the editor does not. This is optional, and it breaks if your home IP changes often, so weigh that before you do it.
Keeping encryption keys and environment variables secure
Treat the .env file like a password vault. Set its permissions with chmod 600 .env, keep it out of Git, and never paste it into a forum post or support ticket when you ask for help. Blank out the values first.
Store a copy of N8N_ENCRYPTION_KEY in your password manager, away from the server. Without that key, every saved credential in a database backup is unreadable. You would restore your workflows and then type every API key in again by hand. That is the most avoidable disaster in the whole setup, and the fix costs one minute.
Changing the key later is possible but painful, because stored credentials were encrypted with the old one. Choose it once and keep it.
Backing up workflows, credentials and database files
Back up the database, the .env file, compose.yaml and the Caddyfile. Together they let you rebuild the whole system on a new server in under an hour. Here is a daily database dump to start with.
mkdir -p ~/backups
cd ~/n8n-compose
docker compose exec -T postgres pg_dump -U n8n -d n8n | gzip > ~/backups/n8n-$(date +%F).sql.gz
Put that in a cron job, then copy the files off the server to another location. A backup on the same disk dies with the disk. Provider snapshots help as a second layer, and our reseller features page lists what ships with our plans, but a snapshot is not a replacement for a database dump you have tested.
Test a restore at least once. Create an empty database, load the dump into it and check that your workflows appear. A backup you have never restored is a hope, not a backup. You can also export workflows as JSON with n8n’s CLI export command for a human readable copy.
Updating Docker images without losing existing data
Back up first, then update. Your data lives in volumes, so replacing the container does not touch it.
cd ~/n8n-compose
docker compose pull
docker compose down
docker compose up -d
docker image prune -f
n8n ships a new minor version most weeks. Read the release notes before a major version jump, because a major release can change behavior. If you want full control, pin an exact version tag in the compose file instead of stable, and move the pin forward when you are ready.
Rollback has a limit. Newer n8n versions may migrate the database schema on first start, and an older version cannot always read the result. That is the real reason to take the backup before every update, not just the big ones.
How Do You Troubleshoot Common n8n Docker Installation Problems?
Start with docker compose ps and docker compose logs, because the logs name the cause in most cases. Then work outward in order: container, DNS, certificate, webhook URL. Fix one layer at a time, and test after each fix.
Fixing Docker containers that fail to start
A container stuck in a restart loop shows up in docker compose ps. Read its logs with docker compose logs n8n –tail 50, and look at the first error, not the last one.
The common causes are small. A missing value in .env produces a warning that a variable is not set. A YAML indentation mistake, one space off, stops Compose from parsing the file. Another web server already using port 80 blocks Caddy, which sudo ss -tulpn | grep ‘:80’ will reveal.
One cause surprises people. PostgreSQL reads POSTGRES_PASSWORD only the first time it creates an empty data volume. If you change the password in .env afterwards, n8n fails to log in to the database. On a fresh install, remove the postgres_data volume and start again. On a live one, change the password inside PostgreSQL instead.
Resolving domain and DNS connection problems
If the domain does not load at all, check DNS before anything else. Run dig +short n8n.example.com @1.1.1.1 from your own machine and compare the answer to your VPS IP.
A wrong or missing answer means the record is wrong or still propagating. An old AAAA record pointing somewhere else can break access for some visitors while others see the site fine, which makes the fault look random. Remove it if the server does not use IPv6.
If DNS is correct and the page still hangs, the firewall is next. Check UFW, then check any network firewall in your VPS control panel. A closed port 443 looks exactly like a DNS failure from the browser.
Troubleshooting SSL certificate and HTTPS errors
Read the Caddy logs with docker compose logs caddy. They say plainly why issuance failed. Failed challenges usually mean DNS points to the wrong address or port 80 is blocked, because Let’s Encrypt must reach your server over HTTP to verify it.
A typo in the Caddyfile domain is another classic. Caddy then requests a certificate for the wrong name, and your real domain serves an error. Compare the Caddyfile to your A record character by character.
Browsers showing a redirect loop usually point to CloudFlare in Flexible SSL mode. Change it to Full strict. And resist the urge to restart Caddy ten times in a row, because every failed attempt counts toward the rate limit.
Fixing webhook URL and port configuration issues
If the Webhook node shows a URL that starts with localhost, N8N_WEBHOOK_URL is missing or wrong. Fix the .env or compose entry and run docker compose up -d again, which recreates the container with the new value.
A 404 on a production webhook URL usually means the workflow is not active. The test URL only works while the editor is listening for a test event, and the production URL works only after you activate the workflow. People mix these up constantly.
A 502 error from Caddy means it cannot reach n8n. Check that the n8n container is running and that the Caddyfile says n8n:5678, matching the service name and port. If you ever open n8n over plain HTTP on a raw IP, you may see a secure cookie warning. The right answer is to use the HTTPS domain, not to switch the cookie check off.
Checking container logs and verifying workflow execution
Logs are your best tool. Use docker compose logs -f n8n to watch live, or docker compose logs n8n –since 30m to look back. The Executions tab inside n8n shows each run with its input and output data.
Make a tiny test workflow that runs every minute and writes a line to the log. It tells you at once whether scheduling works and whether the timezone is what you expect. Delete it when you are done.
Watch memory too. Run docker stats to see usage per container, and sudo dmesg | grep -i kill to check whether Linux killed a process for lack of RAM. If a heavy workflow keeps dying, the fix is usually a bigger plan, not more config. And if the trouble looks like the server or its network rather than n8n, contact your host. Our team answers 24/7.
You now have n8n running on a server you control, with HTTPS, a database you can back up and an update routine that does not put your data at risk. If you want fast storage and a clean start, take a look at our NVMe VPS plans and run this stack on one tonight.