services: broker: image: docker.io/library/redis:7-alpine restart: unless-stopped volumes: - type: ${PAPERLESS_REDISDATA_PATH:+bind} # If PAPERLESS_REDISDATA_PATH is set, use bind mount source: ${PAPERLESS_REDISDATA_PATH:-redisdata} # Use path from ENV, otherwise 'redisdata' (named volume) target: /data # Set "volume" type explicitly if no path is provided and it should be a named volume # This is handled by Docker Compose automatically if source is a named volume. - type: ${PAPERLESS_REDISDATA_PATH:-volume} # This line is primarily illustrative for clarity; Docker Compose infers correctly. source: ${PAPERLESS_REDISDATA_PATH:-redisdata} target: /data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 30s timeout: 10s retries: 3 db: image: docker.io/library/postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: ${PAPERLESS_DBNAME} POSTGRES_USER: ${PAPERLESS_DBUSER} POSTGRES_PASSWORD: ${PAPERLESS_DBPASS} volumes: - type: ${PAPERLESS_PGDATA_PATH:+bind} # If PAPERLESS_PGDATA_PATH is set, use bind mount source: ${PAPERLESS_PGDATA_PATH:-pgdata} # Use path from ENV, otherwise 'pgdata' (named volume) target: /var/lib/postgresql/data - type: ${PAPERLESS_PGDATA_PATH:-volume} source: ${PAPERLESS_PGDATA_PATH:-pgdata} target: /var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${PAPERLESS_DBUSER} -d ${PAPERLESS_DBNAME}"] interval: 10s timeout: 5s retries: 5 webserver: image: ghcr.io/paperless-ngx/paperless-ngx:latest # Consider pinning a specific version for production, e.g., :1.17.4 restart: unless-stopped environment: PAPERLESS_SECRET_KEY: ${PAPERLESS_SECRET_KEY} PAPERLESS_URL: ${PAPERLESS_URL} PAPERLESS_ALLOWED_HOSTS: ${PAPERLESS_ALLOWED_HOSTS} PAPERLESS_CSRF_TRUSTED_ORIGINS: ${PAPERLESS_CSRF_TRUSTED_ORIGINS} PAPERLESS_TIME_ZONE: ${PAPERLESS_TIME_ZONE} PAPERLESS_OCR_LANGUAGE: ${PAPERLESS_OCR_LANGUAGE} PAPERLESS_OCR_LANGUAGES: ${PAPERLESS_OCR_LANGUAGES} PAPERLESS_ADMIN_USER: ${PAPERLESS_ADMIN_USER} PAPERLESS_ADMIN_PASSWORD: ${PAPERLESS_ADMIN_PASSWORD} PAPERLESS_DBHOST: ${PAPERLESS_DBHOST} PAPERLESS_DBENGINE: ${PAPERLESS_DBENGINE} PAPERLESS_DBNAME: ${PAPERLESS_DBNAME} PAPERLESS_DBUSER: ${PAPERLESS_DBUSER} PAPERLESS_DBPASS: ${PAPERLESS_DBPASS} PAPERLESS_REDIS: ${PAPERLESS_REDIS} USERMAP_UID: ${USERMAP_UID} USERMAP_GID: ${USERMAP_GID} # Optional: Email consumption (uncomment and configure if needed) # PAPERLESS_CONSUMPTION_MAIL_HOST: ${PAPERLESS_CONSUMPTION_MAIL_HOST} # PAPERLESS_CONSUMPTION_MAIL_PORT: ${PAPERLESS_CONSUMPTION_MAIL_PORT} # PAPERLESS_CONSUMPTION_MAIL_USER: ${PAPERLESS_CONSUMPTION_MAIL_USER} # PAPERLESS_CONSUMPTION_MAIL_PASS: ${PAPERLESS_CONSUMPTION_MAIL_PASS} # PAPERLESS_CONSUMPTION_MAIL_SSL: ${PAPERLESS_CONSUMPTION_MAIL_SSL} # PAPERLESS_CONSUMPTION_MAIL_INBOX: ${PAPERLESS_CONSUMPTION_MAIL_INBOX} # PAPERLESS_CONSUMPTION_MAIL_ACCOUNT: ${PAPERLESS_CONSUMPTION_MAIL_ACCOUNT} ports: - "8000:8000" volumes: - type: ${PAPERLESS_DATA_PATH:+bind} source: ${PAPERLESS_DATA_PATH:-data} target: /usr/src/paperless/data - type: ${PAPERLESS_DATA_PATH:-volume} source: ${PAPERLESS_DATA_PATH:-data} target: /usr/src/paperless/data - type: ${PAPERLESS_MEDIA_PATH:+bind} source: ${PAPERLESS_MEDIA_PATH:-media} target: /usr/src/paperless/media - type: ${PAPERLESS_MEDIA_PATH:-volume} source: ${PAPERLESS_MEDIA_PATH:-media} target: /usr/src/paperless/media - type: ${PAPERLESS_CONSUME_PATH:+bind} source: ${PAPERLESS_CONSUME_PATH:-./consume} # Default to local ./consume folder target: /usr/src/paperless/consume # Note: For consume/export, it's generally best to always use a bind mount to a known host path. # The "volume" fallback for these isn't as practical, as you'd still need to put files in them from the host. - type: ${PAPERLESS_EXPORT_PATH:+bind} source: ${PAPERLESS_EXPORT_PATH:-./export} # Default to local ./export folder target: /usr/src/paperless/export # Same note as for consume path. depends_on: broker: condition: service_healthy db: condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/api/healthcheck/"] interval: 30s timeout: 10s retries: 5 volumes: # Define named volumes. These will be used if the corresponding environment variable for a bind mount is NOT set. data: media: pgdata: redisdata: