Docker Compose - Data Loss

I’m running into something unexpected whenever I stop n8n via docker to update it or make a change to .env. When I restart it, all the data is lost. I’m using postgres and traefik. It’s almost like it’s reverting to a non-postgres setup. I have to stop it again and copy the data over from the previous volume and restart it, at which point all my data is back. Any ideas? I’ve included sanitized files below.

.env

# Folder where data should be saved
DATA_FOLDER=/root/n8n/

# The top level domain to serve from
DOMAIN_NAME=dr02

# The subdomain to serve from
SUBDOMAIN=n8n

# DOMAIN_NAME and SUBDOMAIN combined decide where n8n will be reachable from
# above example would result in: https://n8n.example.com

# The user name to use for autentication - IMPORTANT ALWAYS CHANGE!
N8N_BASIC_AUTH_USER=admin

# The password to use for autentication - IMPORTANT ALWAYS CHANGE!
N8N_BASIC_AUTH_PASSWORD="easypassword"

# Optional timezone to set which gets used by Cron-Node by default
# If not set New York time will be used
GENERIC_TIMEZONE=America/Edmonton

# The email address to use for the SSL certificate creation
[email protected]

EXECUTIONS_PROCESS=main
EXECUTIONS_TIMEOUT=3599
EXECUTIONS_TIMEOUT_MAX=14399

# DATABASE
POSTGRES_USER=dbroot
POSTGRES_PASSWORD="rootpasswordsarefun"
POSTGRES_DB=n8n
POSTGRES_NON_ROOT_USER=n8nuser
POSTGRES_NON_ROOT_PASSWORD="supereasypassword"

docker-compose.yml:

version: "3.1"

services:
  traefik:
    image: "traefik"
    restart: always
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
      - "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
    ports:
      - "443:443"
    volumes:
      - ${DATA_FOLDER}/letsencrypt:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro


  postgres:
    image: postgres:11
    restart: always
    environment:
      - POSTGRES_USER
      - POSTGRES_PASSWORD
      - POSTGRES_DB
      - POSTGRES_NON_ROOT_USER
      - POSTGRES_NON_ROOT_PASSWORD
    volumes:
      - ./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh

  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    labels:
      - traefik.enable=true
      - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
      - traefik.http.routers.n8n.tls=true
      - traefik.http.routers.n8n.entrypoints=websecure
      - traefik.http.routers.n8n.tls.certresolver=mytlschallenge
      - traefik.http.middlewares.n8n.headers.SSLRedirect=true
      - traefik.http.middlewares.n8n.headers.STSSeconds=315360000
      - traefik.http.middlewares.n8n.headers.browserXSSFilter=true
      - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
      - traefik.http.middlewares.n8n.headers.forceSTSHeader=true
      - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
      - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
      - traefik.http.middlewares.n8n.headers.STSPreload=true
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
      - DB_POSTGRESDB_USER=${POSTGRES_NON_ROOT_USER}
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_NON_ROOT_PASSWORD}
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER
      - N8N_BASIC_AUTH_PASSWORD
      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_TUNNEL_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ${DATA_FOLDER}/.n8n:/home/node/.n8n
      - /local-files:/files
    links:
      - postgres
    command: /bin/sh -c "sleep 5; n8n start"

@cleveradmin Hey, the volumes for postgres and n8n need these additions:

  postgres:
    volumes:
      - ${DATA_FOLDER}/postgres-data:/var/lib/postgresql/data

  n8n:
    volumes:

- ${DATA_FOLDER}/.n8n:/home/node/.n8n

     - ${DATA_FOLDER}/.n8n:/root/.n8n
3 Likes

Yup that appears to have done the trick. Only issue is that the {DATA_FOLDER} needs to be updated to ${DATA_FOLDER} under postgres.

1 Like