{"id":4481,"date":"2026-09-12T17:35:15","date_gmt":"2026-09-12T12:05:15","guid":{"rendered":"https:\/\/cpanelfree.com\/blog\/how-to-self-host-n8n-workflow-automation-docker-vps\/"},"modified":"2026-09-17T11:20:25","modified_gmt":"2026-09-17T05:50:25","slug":"how-to-self-host-n8n-workflow-automation-docker-vps","status":"publish","type":"post","link":"https:\/\/cpanelfree.com\/blog\/how-to-self-host-n8n-workflow-automation-docker-vps\/","title":{"rendered":"How to Self-Host n8n Workflow Automation Platform with PostgreSQL &amp; Docker"},"content":{"rendered":"<p>Workflow automation is the operational backbone of modern digital organizations. While proprietary iPaaS vendors like Zapier and Make impose strict task execution limits and escalating monthly bills, <strong>n8n<\/strong> provides an open-source, node-based workflow automation powerhouse that can be self-hosted on your own <a href=\"https:\/\/cpanelfree.com\/\">Linux cloud VPS<\/a>. With self-hosted n8n, you enjoy unlimited workflow runs, zero data privacy risks, internal database integrations, and granular webhook triggers. This step-by-step tutorial details configuring a production-grade n8n cluster with <strong>Docker Compose<\/strong>, <strong>PostgreSQL persistence<\/strong>, and automated <strong>Let&#8217;s Encrypt SSL<\/strong>.<\/p>\n<p><!-- more --><\/p>\n<h2>1. Why Self-Host n8n Over Proprietary SaaS?<\/h2>\n<p>Self-hosting n8n delivers substantial operational advantages for developers, IT engineers, and agencies:<\/p>\n<ul>\n<li><strong>Unlimited Task Executions:<\/strong> Execute hundreds of thousands of webhook events and data sync loops without incurring variable per-operation charges.<\/li>\n<li><strong>Data Residency &amp; GDPR Compliance:<\/strong> Sensitive customer credentials, proprietary API payloads, and internal database records remain securely isolated inside your private infrastructure.<\/li>\n<li><strong>Internal Network Access:<\/strong> Trigger internal microservices, execute private bash scripts, and query intranet databases located within your secure VPC.<\/li>\n<li><strong>Custom Node &amp; Community Expansion:<\/strong> Seamlessly integrate custom JavaScript functions, Python scripts, and community-contributed npm packages.<\/li>\n<\/ul>\n<h2>2. Server Sizing &amp; Initial Setup<\/h2>\n<p>For standard workflow loads handling several hundred webhooks hourly, the following specifications provide ideal performance:<\/p>\n<ul>\n<li><strong>Compute:<\/strong> 2 vCPUs, 4 GB RAM (2 GB minimum with swap).<\/li>\n<li><strong>Storage:<\/strong> 40 GB NVMe SSD storage.<\/li>\n<li><strong>OS:<\/strong> Ubuntu 22.04 or 24.04 LTS.<\/li>\n<li><strong>Domain:<\/strong> Dedicated domain record (e.g. <code>n8n.yourdomain.com<\/code>) pointed to your VPS IP.<\/li>\n<\/ul>\n<h2>3. Installing Docker and Docker Compose Plugin<\/h2>\n<p>Ensure your server has the latest Docker container runtime installed:<\/p>\n<pre><code>sudo apt update &amp;&amp; sudo apt upgrade -y\nsudo apt install -y curl git ufw\ncurl -fsSL https:\/\/get.docker.com | sh\nsudo usermod -aG docker $USER\nnewgrp docker<\/code><\/pre>\n<h2>4. Configuring Docker Compose Stack with PostgreSQL<\/h2>\n<p>While n8n defaults to SQLite for quick experiments, production environments handling high-concurrency webhook bursts require an external <strong>PostgreSQL 16<\/strong> engine. Create a dedicated directory at <code>\/opt\/n8n<\/code>:<\/p>\n<pre><code>sudo mkdir -p \/opt\/n8n &amp;&amp; cd \/opt\/n8n\nsudo mkdir -p data local-files<\/code><\/pre>\n<h3>Creating the Production docker-compose.yml<\/h3>\n<p>Create <code>\/opt\/n8n\/docker-compose.yml<\/code>:<\/p>\n<pre><code>version: '3.8'\n\nservices:\n  postgres:\n    image: postgres:16-alpine\n    restart: always\n    environment:\n      POSTGRES_USER: n8n_user\n      POSTGRES_PASSWORD: StrongN8nSecurePassword2026!\n      POSTGRES_DB: n8n_production\n    volumes:\n      - .\/postgres_data:\/var\/lib\/postgresql\/data\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -h localhost -U n8n_user -d n8n_production\"]\n      interval: 5s\n      timeout: 5s\n      retries: 10\n\n  n8n:\n    image: docker.n8n.io\/n8nio\/n8n:latest\n    restart: always\n    environment:\n      - DB_TYPE=postgresdb\n      - DB_POSTGRESDB_HOST=postgres\n      - DB_POSTGRESDB_PORT=5432\n      - DB_POSTGRESDB_DATABASE=n8n_production\n      - DB_POSTGRESDB_USER=n8n_user\n      - DB_POSTGRESDB_PASSWORD=StrongN8nSecurePassword2026!\n      - N8N_HOST=n8n.yourdomain.com\n      - N8N_PORT=5678\n      - N8N_PROTOCOL=https\n      - NODE_ENV=production\n      - WEBHOOK_URL=https:\/\/n8n.yourdomain.com\/\n      - GENERIC_TIMEZONE=UTC\n      - EXECUTIONS_DATA_PRUNE=true\n      - EXECUTIONS_DATA_MAX_AGE=168\n    ports:\n      - \"127.0.0.1:5678:5678\"\n    links:\n      - postgres\n    depends_on:\n      postgres:\n        condition: service_healthy\n    volumes:\n      - .\/data:\/home\/node\/.n8n\n      - .\/local-files:\/files<\/code><\/pre>\n<h2>5. Launching n8n and Initializing Database<\/h2>\n<p>Start the services in the background and monitor container status:<\/p>\n<pre><code>docker compose up -d\ndocker compose logs -f n8n<\/code><\/pre>\n<p>You should see n8n connect to PostgreSQL, apply database migrations, and output: <code>Editor is now accessible via https:\/\/n8n.yourdomain.com\/<\/code>.<\/p>\n<h2>6. Configuring Nginx Reverse Proxy with Let&#8217;s Encrypt SSL<\/h2>\n<p>Install Nginx to handle public SSL encryption and reverse proxy to the local n8n container port:<\/p>\n<pre><code>sudo apt install -y nginx certbot python3-certbot-nginx<\/code><\/pre>\n<p>Create <code>\/etc\/nginx\/sites-available\/n8n.conf<\/code>:<\/p>\n<pre><code>server {\n    listen 80;\n    server_name n8n.yourdomain.com;\n    return 301 https:\/\/$host$request_uri;\n}\n\nserver {\n    listen 443 ssl http2;\n    server_name n8n.yourdomain.com;\n\n    ssl_certificate \/etc\/letsencrypt\/live\/n8n.yourdomain.com\/fullchain.pem;\n    ssl_certificate_key \/etc\/letsencrypt\/live\/n8n.yourdomain.com\/privkey.pem;\n\n    client_max_body_size 64M;\n\n    location \/ {\n        proxy_pass http:\/\/127.0.0.1:5678;\n        proxy_http_version 1.1;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection \"upgrade\";\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n        proxy_buffering off;\n        proxy_cache off;\n    }\n}<\/code><\/pre>\n<p>Obtain certificates and activate the site:<\/p>\n<pre><code>sudo certbot --nginx -d n8n.yourdomain.com\nsudo ln -s \/etc\/nginx\/sites-available\/n8n.conf \/etc\/nginx\/sites-enabled\/\nsudo nginx -t &amp;&amp; sudo systemctl reload nginx<\/code><\/pre>\n<h2>7. Operational Best Practices &amp; Execution Pruning<\/h2>\n<p>Workflow automation engines log execution history for every trigger. Left unmanaged, execution tables can grow by tens of gigabytes. Our Compose configuration automatically enables pruning:<\/p>\n<ul>\n<li><code>EXECUTIONS_DATA_PRUNE=true<\/code>: Deletes historical execution records automatically.<\/li>\n<li><code>EXECUTIONS_DATA_MAX_AGE=168<\/code>: Retains 7 days of logs for debugging while keeping database size lean.<\/li>\n<li><strong>Automated Backups:<\/strong> Take regular snapshots of <code>\/opt\/n8n\/data<\/code> and dump PostgreSQL daily using <code>pg_dump<\/code>.<\/li>\n<\/ul>\n<h2>8. Scaling n8n with Redis Queue Mode &amp; Multi-Worker Nodes<\/h2>\n<p>For high-throughput enterprise deployments handling thousands of concurrent webhook calls, running n8n in single-instance mode can saturate the Node.js event loop. Scaling horizontally is straightforward using <strong>n8n Queue Mode<\/strong>:<\/p>\n<ul>\n<li><strong>Architecture:<\/strong> Deploy a primary n8n main instance (UI and webhook receiver), a Redis instance (BullMQ queue broker), and multiple n8n worker instances that pick up and execute workflow jobs asynchronously.<\/li>\n<li><strong>Configuration Flags:<\/strong> In your worker Compose configuration, specify:\n<pre><code>EXECUTIONS_MODE=queue\nQUEUE_BULL_REDIS_HOST=redis\nQUEUE_BULL_REDIS_PORT=6379<\/code><\/pre>\n<p>    This decouples webhook ingestion from computationally intensive data transformations, guaranteeing sub-50ms webhook acknowledgment times.<\/li>\n<li><strong>Securing Webhooks with HMAC Signatures:<\/strong> Protect public n8n webhook nodes by validating incoming HTTP request headers with HMAC SHA-256 signatures inside a Crypto node, preventing unauthorized API triggers.<\/li>\n<\/ul>\n<h2>9. Enterprise Role-Based Access Control (RBAC) &amp; Git-Based Versioning<\/h2>\n<p>As multiple developers and operations team members collaborate on business-critical n8n automations, safeguarding workflows with version control and granular permissions becomes mandatory:<\/p>\n<ul>\n<li><strong>Workspaces and Role-Based Permissions:<\/strong> Leverage n8n team workspaces to isolate production workflows (such as customer billing automations and CRM synchronization) from experimental staging workflows. Assign team members specific roles (Admin, Member, Viewer) to prevent accidental deletions.<\/li>\n<li><strong>Git Integration via n8n CLI:<\/strong> Automate continuous integration for workflows by exporting JSON definitions to an external Git repository:\n<pre><code>n8n export:workflow --all --output=\/opt\/n8n\/git-backup\/workflows\/\nn8n export:credentials --all --output=\/opt\/n8n\/git-backup\/credentials\/<\/code><\/pre>\n<p>    Integrate this export into a daily cron job or GitHub Actions workflow to enable full audit trails, pull-request code reviews, and instant disaster recovery rollback.<\/li>\n<\/ul>\n<div style=\"background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);border: 1px solid #334155;border-radius: 12px;padding: 28px;margin: 36px 0;text-align: center\">\n<h3 style=\"color: #38bdf8;margin-top: 0;font-size: 22px\">Power Unlimited Automations with CpanelFree Cloud VPS<\/h3>\n<p style=\"color: #cbd5e1;font-size: 16px;line-height: 1.6;max-width: 680px;margin: 12px auto 24px auto\">Self-host n8n with zero workflow execution limits, blazing fast NVMe storage, and isolated dedicated compute resources on CpanelFree.<\/p>\n<p>    <a href=\"https:\/\/cpanelfree.com\/\" style=\"background: #38bdf8;color: #0f172a;font-weight: 700;padding: 12px 28px;border-radius: 6px;text-decoration: none;display: inline-block;font-size: 15px\">Deploy Your Automation Cloud VPS &rarr;<\/a>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Workflow automation is the operational backbone of modern digital organizations. While proprietary iPaaS vendors like Zapier and Make impose strict task execution limits and escalating monthly bills, n8n provides an open-source, node-based workflow automation powerhouse that can be self-hosted on your own Linux cloud VPS. With self-hosted n8n, you enjoy unlimited workflow runs, zero data &#8230; <a title=\"How to Self-Host n8n Workflow Automation Platform with PostgreSQL &amp; Docker\" class=\"read-more\" href=\"https:\/\/cpanelfree.com\/blog\/how-to-self-host-n8n-workflow-automation-docker-vps\/\" aria-label=\"Read more about How to Self-Host n8n Workflow Automation Platform with PostgreSQL &amp; Docker\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":4531,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4481","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web-hosting-news"],"_links":{"self":[{"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/posts\/4481","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/comments?post=4481"}],"version-history":[{"count":2,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/posts\/4481\/revisions"}],"predecessor-version":[{"id":4497,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/posts\/4481\/revisions\/4497"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/media\/4531"}],"wp:attachment":[{"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/media?parent=4481"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/categories?post=4481"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cpanelfree.com\/blog\/wp-json\/wp\/v2\/tags?post=4481"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}