Category: Без рубрики

  • n8n Self Hosted: Full Docker Installation Guide 2026

    n8n Self Hosted: The Complete Docker Setup and Hardening Guide

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    If you’re tired of paying monthly fees for Zapier or Make, running n8n self hosted on your own VPS is one of the highest-leverage moves you can make as a developer or sysadmin. You get unlimited workflow executions, full data ownership, and no per-task billing — for the cost of a $6/month server.

    This guide covers everything you need to run n8n self hosted in production: Docker Compose setup, reverse proxy configuration, database choice, backups, and scaling with queue mode.

    Why Self-Host n8n

    n8n is an open-source workflow automation tool — think Zapier, but with a visual node editor and the ability to write custom JavaScript inside any node. The hosted cloud version is convenient, but it caps executions and charges per active workflow. Self-hosting removes both limits.

    When you run n8n self hosted, you also get:

  • Full control over data retention and where your credentials are stored
  • No vendor lock-in — export/import workflows as JSON anytime
  • The ability to run community and custom nodes that aren’t approved for n8n Cloud
  • Direct network access to internal services (databases, internal APIs) without exposing them publicly
  • The tradeoff is that you own the ops burden: updates, backups, uptime, and security. This guide addresses all four.

    n8n vs Zapier and Make

    If you’re evaluating whether to self-host at all, the deciding factor is usually volume and complexity. Zapier and Make are fine for a handful of simple, low-frequency automations. Once you’re running dozens of workflows with branching logic, webhooks, and custom code, the per-task pricing on those platforms gets expensive fast, and n8n self hosted becomes the more economical option, especially at scale.

    Prerequisites

    Before you start, you’ll need:

  • A VPS with at least 1 vCPU and 2GB RAM (n8n is fairly lightweight, but PostgreSQL and Redis add overhead if you use queue mode)
  • Docker and Docker Compose installed
  • A domain name you control, with DNS pointed at your server’s IP
  • Basic familiarity with the command line
  • If you don’t already have a VPS, DigitalOcean and Hetzner both offer affordable droplets/instances that are more than capable of running n8n comfortably — a $12/month droplet handles most single-user workloads without issue.

    Installing n8n with Docker

    The fastest, most maintainable way to run n8n self hosted is with Docker Compose. This keeps n8n, its database, and any supporting services isolated and easy to upgrade.

    First, create a project directory and the required subfolders:

    mkdir -p ~/n8n-stack/local-files
    cd ~/n8n-stack

    Docker Compose Setup

    Create a docker-compose.yml file with the following contents:

    version: '3.8'
    
    services:
      postgres:
        image: postgres:16
        restart: unless-stopped
        environment:
          - POSTGRES_USER=n8n
          - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
          - POSTGRES_DB=n8n
        volumes:
          - postgres_data:/var/lib/postgresql/data
        healthcheck:
          test: ['CMD-SHELL', 'pg_isready -U n8n']
          interval: 5s
          timeout: 5s
          retries: 10
    
      n8n:
        image: docker.n8n.io/n8nio/n8n:latest
        restart: unless-stopped
        ports:
          - '127.0.0.1:5678:5678'
        environment:
          - N8N_HOST=${DOMAIN_NAME}
          - N8N_PROTOCOL=https
          - N8N_PORT=5678
          - WEBHOOK_URL=https://${DOMAIN_NAME}/
          - DB_TYPE=postgresdb
          - DB_POSTGRESDB_HOST=postgres
          - DB_POSTGRESDB_DATABASE=n8n
          - DB_POSTGRESDB_USER=n8n
          - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
          - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
          - GENERIC_TIMEZONE=UTC
        volumes:
          - n8n_data:/home/node/.n8n
          - ./local-files:/files
        depends_on:
          postgres:
            condition: service_healthy
    
    volumes:
      postgres_data:
      n8n_data:

    Next, create a .env file to hold your secrets — never commit this to version control:

    cat > .env << 'EOF'
    DOMAIN_NAME=n8n.yourdomain.com
    POSTGRES_PASSWORD=change_this_to_a_long_random_string
    N8N_ENCRYPTION_KEY=change_this_to_another_long_random_string
    EOF

    Generate strong random values instead of the placeholders:

    openssl rand -hex 32

    Run that command twice and paste the outputs into POSTGRES_PASSWORD and N8N_ENCRYPTION_KEY respectively. The encryption key is critical — it encrypts stored credentials, and if you lose it, you lose access to every saved credential in your workflows. Back it up somewhere safe outside the server.

    Now bring the stack up:

    docker compose up -d

    Check that both containers are healthy:

    docker compose ps
    docker compose logs -f n8n

    At this point n8n is running on 127.0.0.1:5678, bound only to localhost. It isn’t reachable from the internet yet — that’s intentional. We’ll expose it safely through a reverse proxy in the next section.

    Setting Up a Reverse Proxy with HTTPS

    Running n8n behind a reverse proxy with TLS is non-negotiable for anything beyond local testing, since n8n handles webhooks and stored credentials. Nginx with Let’s Encrypt is the simplest combination.

    Install Nginx and Certbot on the host:

    sudo apt update
    sudo apt install -y nginx certbot python3-certbot-nginx

    Create a server block at /etc/nginx/sites-available/n8n:

    server {
        listen 80;
        server_name n8n.yourdomain.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_cache_bypass $http_upgrade;
        }
    }

    Enable the site and issue a certificate:

    sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
    sudo nginx -t && sudo systemctl reload nginx
    sudo certbot --nginx -d n8n.yourdomain.com

    Certbot will automatically rewrite the config for HTTPS and set up renewal. If you’d rather use Traefik with automatic Let’s Encrypt via Docker labels, our Traefik reverse proxy guide walks through that setup in detail, and it pairs well with the Compose file above.

    Database Configuration: SQLite vs PostgreSQL

    By default, n8n ships with SQLite, which is fine for quick testing but not recommended for production. SQLite struggles under concurrent writes, and a corrupted database file can silently break your entire instance with no easy recovery path. PostgreSQL, as configured in the Compose file above, handles concurrent workflow executions far more reliably and makes backups straightforward with standard tooling like pg_dump.

    If you’re already running PostgreSQL for other services, you can point n8n at that instance instead of running a dedicated container — just make sure the DB_POSTGRESDB_HOST environment variable resolves correctly from inside the n8n container’s network.

    Securing Your n8n Instance

    A self-hosted automation tool that stores API keys and OAuth tokens for every service you connect is a high-value target if compromised. Treat it accordingly.

  • Enable n8n’s built-in user management (Settings → Users) so the instance isn’t wide open to anyone with the URL
  • Restrict SSH access to key-based auth only and disable root login
  • Keep the Docker image updated regularly — docker compose pull && docker compose up -d pulls the latest patched release
  • Set N8N_BLOCK_ENV_ACCESS_IN_NODE=true to prevent workflow code nodes from reading host environment variables
  • Put the server behind a firewall that only allows ports 22, 80, and 443
  • For a full server hardening checklist beyond n8n specifically, see our guide on securing a self-hosted VPS, which covers fail2ban, unattended upgrades, and SSH hardening in more depth.

    If uptime matters for your automations — for example, workflows that process incoming webhooks from payment providers — it’s worth pairing your instance with an external monitoring service. BetterStack offers uptime monitoring and status pages that will alert you immediately if your n8n instance or its webhook endpoint goes down, which is far better than discovering a failed workflow days later.

    Backups

    Backups need to cover two things: the PostgreSQL database (your workflow definitions and execution history) and the n8n_data volume (which holds the encryption key and local file storage).

    A simple daily backup script:

    #!/bin/bash
    set -euo pipefail
    
    BACKUP_DIR=/root/n8n-backups
    TIMESTAMP=$(date +%Y%m%d-%H%M%S)
    mkdir -p "$BACKUP_DIR"
    
    docker compose exec -T postgres pg_dump -U n8n n8n | gzip > "$BACKUP_DIR/n8n-db-$TIMESTAMP.sql.gz"
    docker run --rm -v n8n-stack_n8n_data:/data -v "$BACKUP_DIR":/backup alpine 
      tar czf "/backup/n8n-data-$TIMESTAMP.tar.gz" -C /data .
    
    find "$BACKUP_DIR" -type f -mtime +14 -delete

    Schedule it with cron:

    crontab -e
    # Add the following line:
    0 3 * * * /root/n8n-backup.sh >> /var/log/n8n-backup.log 2>&1

    Copy the backups off the server itself — to object storage or another machine — since a backup that lives only on the server it’s protecting isn’t a real backup.

    Scaling n8n with Queue Mode

    If you’re running high-volume or long-running workflows, the default setup can become a bottleneck because a single n8n process handles both the UI and execution. Queue mode splits this: a main process handles the editor and webhook triggers, while separate worker processes pull jobs from a Redis-backed queue and execute them.

    To enable it, add a Redis service to your Compose file and set these additional environment variables on the n8n service:

      redis:
        image: redis:7-alpine
        restart: unless-stopped

    EXECUTIONS_MODE=queue
    QUEUE_BULL_REDIS_HOST=redis

    Then run a separate worker container using the same image with the command n8n worker. This lets you scale workers horizontally as workflow volume grows, without touching the main instance.

    Monitoring and Observability

    Once n8n is handling anything business-critical, blind spots become expensive. At minimum, track:

  • Container health via docker compose ps and restart policies
  • Disk usage on the volumes, since execution history can grow unbounded if you don’t configure EXECUTIONS_DATA_PRUNE
  • HTTP response codes on the reverse proxy for failed webhook deliveries
  • Our Docker Compose monitoring guide shows how to wire up Prometheus and Grafana against a Compose stack like this one if you want dashboards rather than just log tailing.

    Recommended: Want to explore DigitalOcean yourself? DigitalOcean is a direct vendor link (not an affiliate/tracked link).

    FAQ

    Is n8n free to self-host?
    Yes. The core n8n software is fair-code licensed and free to self-host with no execution limits. You only pay for the server it runs on and optional enterprise features if you need SSO or advanced permissions.

    How much does it cost to run n8n self hosted?
    A small VPS with 1-2 vCPUs and 2GB of RAM, typically $6-12/month from providers like DigitalOcean or Hetzner, is enough for most individual or small-team workloads.

    Do I need PostgreSQL, or can I stick with SQLite?
    SQLite works for testing, but PostgreSQL is strongly recommended for production because it handles concurrent executions more reliably and supports standard backup tooling.

    Can I run n8n without Docker?
    Yes, n8n can be installed via npm directly on the host, but Docker is recommended because it isolates dependencies, simplifies upgrades, and matches the environment n8n is tested against.

    How do I update a self-hosted n8n instance safely?
    Back up your database and volumes first, then run docker compose pull followed by docker compose up -d. Check the n8n release notes for breaking changes before upgrading across major versions.

    Is it safe to expose n8n’s webhook URLs publicly?
    Yes, that’s expected usage, but only expose them behind HTTPS via a reverse proxy, and enable user authentication on the editor UI so the workflow builder itself isn’t publicly accessible.

    Final Thoughts

    Running n8n self hosted takes maybe 30 minutes of setup time and gives you a private, unlimited automation platform that competes with tools costing hundreds of dollars a month at scale. Start with the Docker Compose setup above, put it behind HTTPS, automate your backups, and you’ll have a production-grade instance before the end of the afternoon.

  • SEO Automation Platform Guide for DevOps Teams 2026

    SEO Automation Platform: Build a Self-Hosted Stack for Scalable Search Growth

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    If you manage SEO for more than a handful of sites, you already know the pain: five different SaaS dashboards, five different invoices, and none of them talk to each other. A self-hosted SEO automation platform solves that by pulling rank tracking, crawling, log analysis, and alerting into one stack you control. This guide walks through the actual components, the Docker configuration, and the cron jobs that keep it running without babysitting.

    Why Most Teams Outgrow SaaS-Only SEO Tools

    Commercial rank trackers and audit tools are fine when you’re managing one site with a small keyword list. The moment you’re running audits across a portfolio of domains, tracking thousands of keywords, or need custom alerting tied to deploys, the per-seat and per-keyword pricing model starts eating your margin. Worse, most SaaS tools don’t expose raw data easily — you get a dashboard, not a database you can query.

    The Hidden Cost of Per-Seat SEO Subscriptions

    The sticker price is rarely the real cost. Once you factor in the extras, a “simple” SEO stack adds up fast:

  • Rank tracking tiers that charge per keyword, not per site
  • Crawl tools that cap URLs per audit and charge overages
  • Separate uptime/alerting tools with their own billing
  • No API access without an enterprise plan
  • Vendor lock-in on historical ranking data
  • A self-hosted platform trades a few hours of setup for full ownership of that data and no recurring per-keyword fees.

    What “Automation” Actually Means Here

    Automation in this context isn’t a single tool — it’s a pipeline. Containers crawl your sites on a schedule, write results to a shared database, a script diffs the results against the previous run, and alerts fire only when something meaningful changes (a ranking drop, a spike in 404s, a broken canonical tag). The goal is to never manually open a spreadsheet to check if something broke.

    Core Components of a Self-Hosted SEO Automation Platform

    Before writing any config, it helps to know what you’re actually assembling. A functional platform needs:

  • A rank-tracking service (open-source or API-driven)
  • A crawler for technical audits (broken links, duplicate titles, canonical issues)
  • A log-file parser for crawl-budget analysis
  • A scheduler (cron or a job runner) to trigger everything
  • A database to store historical results
  • An alerting layer for regressions
  • Each of these can run as its own Docker container, which keeps the stack portable across any VPS provider.

    Rank Tracking Container

    Most teams start here because it’s the highest-visibility metric. Instead of paying per keyword, you can run an open-source tracker or a lightweight scraper against Google’s SERPs via a licensed API, storing results in Postgres. Here’s a minimal docker-compose.yml for the tracking layer:

    version: "3.9"
    services:
      rank-tracker-db:
        image: postgres:16
        environment:
          POSTGRES_USER: seo
          POSTGRES_PASSWORD: changeme
          POSTGRES_DB: rankings
        volumes:
          - rank_data:/var/lib/postgresql/data
    
      rank-tracker:
        image: ghcr.io/example/rank-tracker:latest
        depends_on:
          - rank-tracker-db
        environment:
          DB_HOST: rank-tracker-db
          SEARCH_API_KEY: ${SEARCH_API_KEY}
        volumes:
          - ./keywords.csv:/app/keywords.csv:ro
    
    volumes:
      rank_data:

    The keywords.csv file holds your tracked terms and target URLs; the container runs on a schedule (set via the platform’s own cron config or an external scheduler) and writes daily snapshots to Postgres.

    Automated Crawling and Technical Audits

    For technical audits, Screaming Frog SEO Spider has a headless CLI mode that runs well inside a container, exporting CSVs you can diff programmatically. A simple wrapper script triggered nightly looks like this:

    #!/usr/bin/env bash
    set -euo pipefail
    
    SITE_URL="https://example.com"
    OUTPUT_DIR="/data/audits/$(date +%F)"
    mkdir -p "$OUTPUT_DIR"
    
    docker run --rm 
      -v "$OUTPUT_DIR:/output" 
      screamingfrog/seo-spider:latest 
      --crawl "$SITE_URL" 
      --headless 
      --output-folder /output 
      --save-crawl 
      --export-tabs "Internal:All,Response Codes:All"
    
    echo "Audit complete: $OUTPUT_DIR"

    Pipe the CSV output into a small parser that compares today’s broken-link count against yesterday’s, and you have automated regression detection without opening a single dashboard.

    Log-File Analysis for Crawl Budget

    Rank position tells you what happened; server logs tell you why. Parsing raw access logs for Googlebot hits shows you exactly which pages get crawled, how often, and which ones are being ignored. A basic pipeline uses goaccess or a custom Python script to filter user-agent strings matching Googlebot, bucket requests by path, and flag pages that haven’t been crawled in 30+ days — often a sign of weak internal linking or a noindex mistake.

    Deploying the Stack on a VPS

    All of this needs somewhere to run. For a stack this size — a handful of containers, a database, and scheduled jobs — a mid-tier VPS is plenty. We’ve had good results running similar Docker stacks on Hetzner and DigitalOcean droplets; both give you predictable pricing and fast NVMe storage, which matters when Postgres is writing ranking snapshots daily. If you’re comparing options, our guide on choosing a VPS for Docker workloads breaks down CPU and IOPS tradeoffs in more detail.

    Provisioning is straightforward once Docker and Compose are installed:

    curl -fsSL https://get.docker.com | sh
    sudo usermod -aG docker $USER
    mkdir -p /opt/seo-stack && cd /opt/seo-stack
    git clone https://github.com/example/seo-automation-stack.git .
    docker compose up -d

    Scheduling Jobs with Cron and Webhooks

    With containers running, the scheduler ties everything together. A basic crontab on the host handles daily and weekly jobs:

    # Rank tracking - daily at 3am
    0 3 * * * docker exec rank-tracker /app/run.sh
    
    # Technical audit - weekly on Monday at 4am
    0 4 * * 1 /opt/seo-stack/scripts/run-audit.sh
    
    # Log parsing - daily at 5am
    0 5 * * * /opt/seo-stack/scripts/parse-logs.sh

    For anything that needs to run outside the schedule — say, right after a deploy — a webhook endpoint (a small Flask or Express route) can trigger the same scripts on demand, which is useful for re-auditing right after you ship a template change.

    Alerting When Rankings or Uptime Drop

    Automation is only useful if failures reach a human. Pair the stack with an uptime and alerting service so you’re notified the moment a monitored page starts returning errors or a crawl job fails silently. We use BetterStack for this layer — it handles both uptime monitoring and log-based alerting, and integrates cleanly via webhook with the scripts above so a failed audit or a sudden ranking drop pages you directly instead of sitting unnoticed in a CSV file.

    Reporting Without Manual Spreadsheet Work

    Once data is flowing into Postgres, a lightweight Python script can generate weekly summary reports automatically instead of someone manually exporting charts:

    import psycopg2
    import csv
    from datetime import date, timedelta
    
    conn = psycopg2.connect(host="rank-tracker-db", dbname="rankings", user="seo")
    cur = conn.cursor()
    
    last_week = date.today() - timedelta(days=7)
    cur.execute(
        "SELECT keyword, position, checked_at FROM rankings WHERE checked_at >= %s ORDER BY keyword",
        (last_week,)
    )
    
    with open("weekly_report.csv", "w", newline="") as f:
        writer = csv.writer(f)
        writer.writerow(["keyword", "position", "checked_at"])
        writer.writerows(cur.fetchall())
    
    print("Report generated: weekly_report.csv")

    Schedule this alongside the other cron jobs and pipe the CSV into whatever BI tool or Slack integration your team already uses. The point isn’t a fancier chart — it’s removing the manual export step entirely.

    Scaling and Hardening the Platform

    As the stack grows past a couple of sites, put a CDN and WAF in front of anything web-facing, including your reporting dashboard. Cloudflare is a solid default here — free tier DNS proxying and basic firewall rules stop most scraper and bot noise before it ever reaches your VPS, which matters since your crawler containers are themselves generating meaningful outbound traffic that can look suspicious to your own hosting provider if unmanaged.

    If you eventually need managed rank-tracking data alongside your self-hosted audits — for competitor tracking at scale, for instance — a tool like SE Ranking can complement the stack rather than replace it, feeding its API output into the same Postgres database so all your historical data lives in one place regardless of source. For teams already running a broader observability setup, our self-hosted monitoring stack guide covers how to fold these SEO containers into the same Grafana dashboards you’re using for uptime.

    Before scaling further, double check container resource limits in your Compose file — an unthrottled crawler can consume all available memory during a large site audit and take down the rank-tracker container alongside it. Setting mem_limit and cpus per service avoids that failure mode entirely.

    Recommended: Ready to put this into practice? SE Ranking is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    Do I need to be a developer to run a self-hosted SEO automation platform?
    Basic comfort with the command line and Docker is enough. You don’t need to write the tools from scratch — most of the stack is existing open-source containers wired together with cron and a shared database.

    How much does it cost to run compared to SaaS tools?
    A mid-tier VPS running the full stack typically costs $20–$40/month, regardless of how many keywords or sites you track. Compare that to per-keyword SaaS pricing, which scales linearly with your portfolio size.

    Can this replace tools like Ahrefs or SEMrush entirely?
    Not fully — those tools include massive backlink indexes that are expensive to replicate. This platform is best for rank tracking, technical audits, and log analysis; keep a SaaS subscription for backlink data if you rely on it heavily.

    What happens if a container crashes overnight?
    That’s what the alerting layer is for. With BetterStack or a similar webhook-based monitor watching job completion, a failed cron run pages you instead of silently skipping a day of data.

    Is it safe to run crawlers against my own production site?
    Yes, as long as you rate-limit requests and respect your own robots.txt. Set a reasonable crawl delay in the Screaming Frog config to avoid triggering your own WAF or rate limiter.

    How do I back up the ranking history?
    Since everything lives in Postgres, a nightly pg_dump to object storage (or a snapshot through your VPS provider) is sufficient. Add it as another line in the same crontab used for the rest of the pipeline.

  • Redis Docker Compose: The Complete Setup Guide

    Redis Docker Compose: The Complete Setup and Caching Guide

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    Adding a cache layer used to mean provisioning a separate service, wiring up network rules, and hoping the versions matched. A Redis Docker Compose setup collapses all of that into a few lines of YAML: one service block, one shared network, and Redis is reachable from every other container in your stack by name.

    This guide walks through a production-ready Redis Docker Compose configuration, how to persist data across restarts, how to secure the connection with a password, and the mistakes that cause the most confusion when people wire Redis into an existing Postgres Docker Compose stack.

    What a Redis Docker Compose Setup Actually Gives You

    At its simplest, a Redis Docker Compose service is just an image reference and a port:

    yaml
    services:
    cache:
    image: redis:7-alpine
    ports:
    - "6379:6379"
    `

    That's enough to get Redis running, but a real Redis Docker Compose stack needs three more things most tutorials skip: a named volume for persistence, a password, and a healthcheck so dependent services don't start before Redis is actually ready to accept connections.

    A Complete Redis Docker Compose Configuration

    Here's a realistic Redis Docker Compose file for an API that uses Redis for session storage and caching, alongside Postgres for durable data:

    `yaml
    services:
    api:
    build: .
    environment:
    - REDIS_URL=redis://:$REDIS_PASSWORD@cache:6379
    depends_on:
    cache:
    condition: service_healthy

    cache:
    image: redis:7-alpine
    command: redis-server --requirepass $REDIS_PASSWORD --appendonly yes
    volumes:
    - redis_data:/data
    healthcheck:
    test: [CMD, redis-cli, --raw, -a, $REDIS_PASSWORD, ping]

    volumes:
    redis_data:
    `

    Every other service resolves the cache by its Compose service name, cache:6379, because Compose gives the project its own internal bridge network automatically. That's the core advantage of a Redis Docker Compose deployment over running docker run redis by hand.

    Why the Healthcheck Matters

    Without a healthcheck, depends_on only waits for the Redis container to start, not for the Redis server inside it to finish loading. The condition: service_healthy clause blocks the api service until redis-cli ping actually succeeds.

    Persisting Redis Data with Docker Compose Volumes

    By default, Redis is an in-memory store, restart the container and everything is gone. A Redis Docker Compose setup that cares about surviving restarts needs a named volume plus one of Redis's two persistence modes.

  • RDB snapshotting: periodic point-in-time dumps, smaller files, faster restarts, but you can lose the last few minutes of writes
  • AOF append-only file: logs every write operation, safer, larger on disk, slightly slower recovery on huge datasets
  • Checking That Persistence Is Actually Working

    `bash
    docker compose exec cache redis-cli -a $REDIS_PASSWORD set healthcheck ok
    docker compose down
    docker compose up -d
    docker compose exec cache redis-cli -a $REDIS_PASSWORD get healthcheck
    `

    If the second get returns ok, your Redis Docker Compose volume is correctly mounted and persistence is active.

    Securing a Redis Docker Compose Service

    Redis binds with no authentication by default, which is fine on an isolated Compose network but dangerous the moment a port gets accidentally exposed to the host or the internet.

  • Set –requirepass so every client needs a password, injected via a .env file
  • Drop the ports: mapping entirely unless you need to reach Redis from outside the Compose network
  • Common Redis Docker Compose Patterns

  • Session store: Express, Django, and Rails all have first-party Redis session adapters
  • Rate limiting: token-bucket limiters backed by Redis's atomic INCR and EXPIRE commands
  • Job queues: libraries like BullMQ or Celery use Redis as the broker between web and worker processes
  • Full-page and query caching: cache expensive database results with a TTL
  • Troubleshooting a Redis Docker Compose Stack

  • Connection refused from the app container: add the healthcheck shown above instead of a fixed sleep
  • NOAUTH Authentication required: confirm the connection string includes the password segment
  • Data disappears after docker compose down: check the volumes: mapping, or you ran docker compose down -v
  • High memory usage: set maxmemory and maxmemory-policy allkeys-lru in the command: block
  • Hosting a Redis Docker Compose Stack in Production

    Redis is memory-hungry by design. If you're outgrowing a budget droplet, DigitalOcean makes it easy to resize RAM, and Hetzner is a solid budget option. BetterStack gives you uptime monitoring for a wedged Redis container, and Cloudflare keeps DNS and TLS predictable in front of your API.

    Once your Redis Docker Compose service is stable, docker compose down is the safe way to stop it without touching the redis_data volume. Our guide to Docker Compose environment variables covers .env file precedence in more depth.

    Monitoring a Redis Docker Compose Service

    Once a Redis Docker Compose stack is running in production, memory pressure is the metric that matters most, since Redis keeps its entire working set in RAM. Two commands make quick diagnostics easy:

    `bash
    docker compose exec cache redis-cli -a $REDIS_PASSWORD info memory
    docker compose exec cache redis-cli -a $REDIS_PASSWORD info stats
    `

    The info memory output shows used_memory_human and maxmemory_human; if the two are converging, it's time to either raise the container's memory limit or tighten your maxmemory-policy. The info stats output includes keyspace_hits and keyspace_misses — a rising miss ratio over time usually means your cache TTLs are too short or your working set has outgrown the box.

    Setting Resource Limits in the Compose File

    A Redis Docker Compose service without a memory ceiling can consume all available host RAM during a traffic spike, starving the database and app containers sharing the same VPS. Pin it explicitly:

    `yaml
    cache:
    image: redis:7-alpine
    deploy:
    resources:
    limits:
    memory: 512M
    `

    Combined with maxmemory 400mb inside the command: block, this keeps a single Redis Docker Compose service from taking down its neighbors when key eviction alone isn't fast enough.

    Redis Docker Compose with Multiple Logical Databases

    Redis ships with 16 numbered logical databases (0-15) inside a single instance, selectable with SELECT n from redis-cli. For a small Redis Docker Compose stack running a cache and a job queue side by side, putting each on its own numbered database avoids a FLUSHDB in one context accidentally wiping the other. For anything beyond a handful of services, most teams prefer key prefixing (session:, queue:, cache:) over numbered databases, since prefixes show up clearly in monitoring dashboards while a bare database number does not.

    Recommended: Want to explore DigitalOcean yourself? DigitalOcean is a direct vendor link (not an affiliate/tracked link).

    FAQ

    Do I need a separate Dockerfile for Redis in a Docker Compose stack?
    No. Use the official
    redis:7-alpine image directly in your Redis Docker Compose file — you only need a custom Dockerfile if you're baking in custom modules that can't be passed via command: flags.

    Does Redis Docker Compose data survive docker compose down?
    Yes, as long as you're using a named volume and skip the
    -v flag. Plain docker compose down removes containers and networks but leaves volumes, and therefore your Redis data, intact.

    What's the difference between RDB and AOF persistence in a Redis Docker Compose setup?
    RDB snapshots recover faster but can lose a few minutes of recent writes; AOF logs every write and is safer but slightly slower to replay on restart. Many production Redis Docker Compose stacks enable both for defense in depth.

    Can multiple services share one Redis Docker Compose instance?
    Yes — use separate numbered Redis databases or key prefixing per service, so a cache flush in one service doesn't wipe session data for another.

    Is it safe to run one Redis Docker Compose instance for both caching and a job queue?
    Yes, as long as you isolate them with separate logical databases or key prefixes and set eviction policies that only apply to cache keys — you don't want
    allkeys-lru evicting queue jobs still waiting to be processed.

    How much RAM does a small Redis Docker Compose service actually need?
    For a low-traffic app using Redis purely for sessions and light caching, 128-256MB is typically enough; job queues holding large payloads need considerably more, and
    info memory is the fastest way to check actual usage rather than guessing.

    Wrapping Up

    A Redis Docker Compose setup is a handful of YAML lines once you know the pieces that matter: a named volume for persistence, –requirepass plus a .env` file for security, a healthcheck so dependent services wait for Redis to be truly ready, and a memory limit so one noisy cache doesn’t starve the rest of the stack. Get those right and Redis becomes a boring, reliable part of your stack instead of a source of cold-start races and vanished cache data.

  • n8n vs Make: Workflow Automation Comparison Guide 2026

    n8n vs Make: Which Workflow Automation Tool Should You Choose?

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    If you’ve spent any time evaluating workflow automation platforms, you’ve hit the n8n vs Make debate. Both tools let you connect APIs, automate repetitive tasks, and build integration pipelines without writing a full application from scratch — but they take fundamentally different approaches to deployment, pricing, and extensibility.

    This guide breaks down n8n vs Make from a developer and sysadmin perspective: what each tool actually does, how they handle self-hosting, what the real costs look like at scale, and which one you should pick for your specific use case.

    What Is n8n?

    n8n is an open-source, node-based workflow automation tool. It’s built in TypeScript, ships as a Docker image, and can be self-hosted on your own infrastructure or used via n8n Cloud. The name stands for “nodemation,” and the core pitch is fair-code licensing — you can view and modify the source, self-host for free, and only pay if you use their managed cloud offering or exceed certain usage thresholds under the Sustainable Use License.

    For developers, the killer feature is the Code node, which lets you drop raw JavaScript (or Python via a community node) directly into a workflow step. That means you’re never fully boxed in by the visual builder — if a connector doesn’t exist, you write it.

    Core n8n Features

  • Visual, node-based workflow editor with branching logic and error workflows
  • Native Docker support and official Helm charts for Kubernetes deployment
  • 400+ built-in integrations plus HTTP Request nodes for anything else
  • Self-hosted instances have no artificial execution caps — you’re limited by your own server resources
  • Built-in credential encryption and support for external secret managers (Vault, AWS Secrets Manager)
  • What Is Make (formerly Integromat)?

    Make is a cloud-only visual automation platform, rebranded from Integromat in 2022. It uses a “scenario” model — modules connected on a canvas — and is generally considered more polished and beginner-friendly than n8n out of the box. Make does not offer a self-hosted version; everything runs on their infrastructure, and pricing is based on “operations” consumed per billing cycle.

    Make shines for non-technical teams who want drag-and-drop automation without touching a terminal. It has strong error-handling visualizations, a cleaner UI for mapping data between apps, and a large library of pre-built app connectors maintained by Make’s own team.

    Core Make Features

  • Visual scenario builder with real-time execution mapping
  • 2,000+ pre-built app integrations
  • Operation-based pricing (each module execution consumes one “operation”)
  • No self-hosting option — vendor lock-in is part of the deal
  • Built-in scheduling, webhooks, and API endpoint creation per scenario
  • n8n vs Make: Pricing Comparison

    This is where the two tools diverge hardest. Make bills you per operation, which sounds fine until a workflow runs thousands of times a day across multiple modules — costs scale directly with usage. n8n’s self-hosted tier is free (you only pay for your own server), while n8n Cloud uses execution-based pricing that’s generally more generous at the entry tier.

  • Make Free plan: 1,000 operations/month, limited to 2 active scenarios
  • Make Core plan: starts around $9/month for 10,000 operations
  • n8n self-hosted: $0 licensing cost, only infrastructure spend (a $6-$12/month VPS easily handles moderate workloads)
  • n8n Cloud Starter: starts around $20/month with generous execution limits
  • If you’re running high-volume workflows — say, syncing data every few minutes across multiple systems — self-hosted n8n is almost always cheaper long-term, because you’re paying for compute, not per-execution metering. We cover how to size that compute correctly in our guide to choosing a VPS for Docker workloads.

    Self-Hosting and Deployment

    This is the single biggest differentiator in the n8n vs Make comparison: n8n can run entirely on infrastructure you control, Make cannot.

    A minimal self-hosted n8n deployment with Docker Compose looks like this:

    yaml
    version: "3.8"
    services:
    n8n:
    image: n8nio/n8n:latest
    restart: unless-stopped
    ports:
    - "5678:5678"
    environment:
    - N8N_HOST=automation.yourdomain.com
    - N8N_PORT=5678
    - N8N_PROTOCOL=https
    - NODE_ENV=production
    - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
    - DB_TYPE=postgresdb
    - DB_POSTGRESDB_HOST=postgres
    - DB_POSTGRESDB_DATABASE=n8n
    - DB_POSTGRESDB_USER=n8n
    - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
    volumes:
    - n8n_data:/home/node/.n8n
    depends_on:
    - postgres

    postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
    - POSTGRES_USER=n8n
    - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    - POSTGRES_DB=n8n
    volumes:
    - postgres_data:/var/lib/postgresql/data

    volumes:
    n8n_data:
    postgres_data:
    `

    Run it with:

    `bash
    export N8N_ENCRYPTION_KEY=$(openssl rand -hex 24)
    export POSTGRES_PASSWORD=$(openssl rand -hex 16)
    docker compose up -d
    `

    Put this behind a reverse proxy with TLS (Caddy or Traefik both work well) and you have a production-grade automation server for the cost of a small VPS. We walk through the full reverse-proxy setup in our Docker Compose deployment guide.

    For reliable uptime on a self-hosted instance, a provider like DigitalOcean or Hetzner gives you predictable pricing and enough headroom to run n8n plus Postgres comfortably on a $6-$12/month droplet or CX22 instance. If uptime matters for business-critical automations, pair your instance with BetterStack for uptime monitoring and incident alerting — self-hosting means you own the reliability, so monitor accordingly.

    Make, by contrast, requires zero infrastructure knowledge. You sign up, connect your apps via OAuth, and build. That simplicity is the entire value proposition — but it also means you're fully dependent on Make's uptime, rate limits, and pricing changes.

    Ease of Use and Learning Curve

    Make generally wins on initial onboarding. Its module-mapping interface makes data transformation between apps visually intuitive — you click a field, drag it to the target, done. n8n's node editor is powerful but assumes more comfort with JSON, expressions, and occasionally raw code.

    That said, n8n's expression editor ({{ $json.fieldName }} syntax) is straightforward once you've used it a few times, and the built-in Code node means you're never stuck waiting for an official connector — you can just call the API directly:

    `javascript
    const response = await this.helpers.httpRequest({
    method: 'GET',
    url: 'https://api.example.com/v1/status',
    headers: {
    Authorization:
    Bearer ${$credentials.apiToken}
    }
    });

    return [{ json: response }];
    `

    Teams with at least one developer tend to outgrow Make's constraints faster than they outgrow n8n's, simply because n8n gives you an escape hatch into real code.

    Integrations and Extensibility

    Make has a larger catalog of pre-built connectors out of the box — roughly 2,000+ compared to n8n's 400+. But raw connector count is misleading: n8n's HTTP Request node combined with the Code node means you can integrate with virtually any REST or GraphQL API even without a dedicated node, whereas Make's no-code-only model makes truly custom integrations more cumbersome.

    n8n also supports community nodes — npm packages that extend functionality — and because it's open source, you can fork it and build entirely custom nodes for internal tools. Make has no equivalent; you're limited to what Make's team builds or what you can construct with their generic HTTP module.

    Performance and Scalability

    For high-throughput automation (thousands of executions per hour), self-hosted n8n scales with your infrastructure — you can run it in queue mode with Redis and multiple worker containers to horizontally scale execution:

    `bash
    docker run -d
    -e EXECUTIONS_MODE=queue
    -e QUEUE_BULL_REDIS_HOST=redis
    -e N8N_ENCRYPTION_KEY=$N8N_ENCRYPTION_KEY
    n8nio/n8n worker
    `

    Make's scalability is entirely dictated by your plan tier and their platform's rate limits. You can't add compute to speed up execution — you upgrade your plan or wait. For teams with unpredictable or bursty automation needs, that's a real constraint.

    Which Should You Choose?

    The honest answer depends on who's running the automation:

  • Choose Make if you have a non-technical team, want zero infrastructure responsibility, and your automation volume is moderate and predictable.
  • Choose n8n if you have any DevOps or engineering capacity, want to avoid per-operation billing at scale, need custom code paths, or care about data residency and self-hosting for compliance reasons.
  • Choose n8n Cloud if you want n8n's flexibility without managing servers yourself, and you're fine paying for that convenience.
  • For most readers of a technical blog like this one — people comfortable with Docker, VPS management, and reverse proxies — self-hosted n8n is the more cost-effective and future-proof choice. You're not locked into a vendor's pricing changes, and you retain full control over your data and execution environment.

    If you're just getting started, spin up a test instance on a cheap VPS this week, connect two or three of your actual tools, and see how far the Code node takes you before deciding whether Make's polish is worth the recurring operation costs.

    Recommended: Want to explore DigitalOcean yourself? DigitalOcean is a direct vendor link (not an affiliate/tracked link).

    FAQ

    Is n8n really free?
    Self-hosted n8n is free to run under its Sustainable Use License — you can use it for internal business automation without paying license fees. You only pay for the server it runs on. n8n Cloud (their managed hosting) is a separate paid product.

    Can I migrate workflows from Make to n8n?
    There's no automated migration tool between the two platforms since they use different scenario/workflow formats. You'll need to manually rebuild workflows, though the underlying logic (triggers, actions, conditionals) usually maps over conceptually without much friction.

    Is Make more reliable than self-hosted n8n?
    Make's infrastructure is professionally managed with high uptime SLAs on paid plans. A self-hosted n8n instance is only as reliable as the server and monitoring you set up around it — which is why pairing it with uptime monitoring is important for production use.

    Does n8n support webhooks like Make does?
    Yes. n8n has native Webhook trigger nodes that generate a unique URL per workflow, functionally equivalent to Make's webhook modules. You can test one instantly with a simple curl request:
    curl -X POST https://your-n8n-instance.com/webhook/test-id -d ‘{“key”:”value”}’`.

    Which tool is better for a solo developer?
    n8n tends to win for solo developers because it’s free to self-host, gives full code-level control, and doesn’t penalize experimentation with per-operation billing. Make’s free tier caps out quickly once you’re testing multiple workflows.

    Can I run n8n on Kubernetes instead of Docker Compose?
    Yes — n8n publishes official Helm charts, and the same queue-mode architecture used for Docker scaling applies to Kubernetes deployments, letting you run separate worker pods for execution load.