Setting up n8n in docker with PostgreSQL and Traefik

Posted by Ryan Goggin on Thu 11 May 2023

n8n is a useful workflow automation tool that can be used to automate various tasks. This post will cover how to set up n8n in docker with PostgreSQL and Traefik and will be used as a base for future posts in this series.

Install Docker and Docker Compose

Follow the instructions on the docker website to install docker and docker-compose on your system. You can find the instructions here.

Setting up n8n

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

version: '3.3'
services:
  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-postgres}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password}
      PGDATA: /data/postgres
    volumes:
      - postgres-data:/data/postgres
    network:
      - db
    restart: unless-stopped
  app:
    image: n8nio/n8n:latest
    restart: unless-stopped
    volumes:
      - n8n-data:/home/node/.n8n
      - n8n-local:/files
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRES_USER=${POSTGRES_USER:-postgres}
      - DB_POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password}
      - N8N_LOG_LEVEL=${N8N_LOG_LEVEL:-info}
      - N8N_PROTOCOL=https
      - N8N_LOG_OUTPUT=console
      - N8N_HOST=${N8N_DOMAIN}
      - VUE_APP_URL_BASE_API=https://${N8N_DOMAIN}/
      - N8N_EDITOR_BASE_URL=https://${N8N_DOMAIN}/
      - WEBHOOK_TUNNEL_URL=https://${N8N_DOMAIN}/
      - NODE_ENV=production
      - WEBHOOK_URL=https://${N8N_DOMAIN}/
      - GENERIC_TIMEZONE=America/Toronto
    networks:
      - db
      - traefik-public
    depends_on:
      - postgres
    deploy:
      labels:
        - traefik.enable=true
        - traefik.docker.network=traefik-public
        - traefik.constraint-label=traefik-public
        - traefik.http.routers.n8n-http.rule=Host(`${N8N_DOMAIN}`)
        - traefik.http.routers.n8n-http.entrypoints=http
        - traefik.http.routers.n8n-http.middlewares=https-redirect
        - traefik.http.routers.n8n-https.rule=Host(`${N8N_DOMAIN}`)
        - traefik.http.routers.n8n-https.entrypoints=https
        - traefik.http.routers.n8n-https.tls=true
        - traefik.http.routers.n8n-https.tls.certresolver=le
        - traefik.http.services.n8n.loadbalancer.server.port=5678

networks:
  traefik-public:
    external: true
  db:
    internal: true

volumes:
  n8n-data:
  n8n-local:
  redis-data:
  postgres-data: