Administrator Guide

Administrator Guide

This guide covers deploying, configuring, and maintaining Paperless Vault.

Installation Requirements

System Requirements

Component Minimum Recommended
CPU 2 cores 4+ cores
RAM 4 GB 8+ GB
Storage 20 GB 100+ GB SSD
Docker 20.10+ Latest
Docker Compose 2.0+ Latest

Network Requirements

Deployment

Quick Start

# Clone the repository
git clone git@bitbucket.org:wilsonify/paperless-vault.git
cd paperless-vault

# Deploy development environment
cd deploy/01_dev
cp .env.example .env
# Edit .env with your settings
docker compose up -d

Environment Configuration

Each environment has its own .env file:

# Core Settings
PAPERLESS_SECRET_KEY=your-secret-key-here
PAPERLESS_ADMIN_USER=admin
PAPERLESS_ADMIN_PASSWORD=secure-password

# Database
POSTGRES_PASSWORD=database-password

# Cloudflare Tunnel
CLOUDFLARE_TUNNEL_TOKEN=your-tunnel-token

# Document Processing
PAPERLESS_OCR_LANGUAGE=eng
PAPERLESS_CONSUMER_POLLING=30
PAPERLESS_TIME_ZONE=America/New_York

# Tika & Gotenberg (Office document support)
PAPERLESS_TIKA_ENABLED=true
PAPERLESS_TIKA_ENDPOINT=http://tika:9998
PAPERLESS_TIKA_GOTENBERG_ENDPOINT=http://gotenberg:3000

Environment Variables Reference

Essential Settings

Variable Description Default
PAPERLESS_SECRET_KEY Django secret key (required) -
PAPERLESS_ADMIN_USER Initial admin username admin
PAPERLESS_ADMIN_PASSWORD Initial admin password -
PAPERLESS_URL Public URL for the instance -

Database Configuration

Variable Description Default
PAPERLESS_DBHOST PostgreSQL host db
PAPERLESS_DBPORT PostgreSQL port 5432
PAPERLESS_DBNAME Database name paperless
PAPERLESS_DBUSER Database user paperless
PAPERLESS_DBPASS Database password -

OCR Settings

Variable Description Default
PAPERLESS_OCR_LANGUAGE OCR languages eng
PAPERLESS_OCR_MODE skip, redo, force skip
PAPERLESS_OCR_PAGES Max pages to OCR 0 (all)
PAPERLESS_OCR_OUTPUT_TYPE Output format pdfa

Consumer Settings

Variable Description Default
PAPERLESS_CONSUMER_POLLING Poll interval (seconds) 30
PAPERLESS_CONSUMER_DELETE_DUPLICATES Delete duplicate files false
PAPERLESS_CONSUMER_RECURSIVE Watch subdirectories false

Service Architecture

Docker Services

services:
  webserver:    # Main Paperless application
  db:           # PostgreSQL database
  redis:        # Redis message broker
  tunnel:       # Cloudflare Tunnel
  gotenberg:    # Document conversion (Office → PDF)
  tika:         # Content extraction

Volume Mounts

Volume Purpose Container Path
data Application data /usr/src/paperless/data
media Document storage /usr/src/paperless/media
consume Import folder /usr/src/paperless/consume
export Export folder /usr/src/paperless/export
pgdata Database files /var/lib/postgresql/data
redisdata Redis persistence /data

Backup & Restore

Database Backup

# Create backup
docker compose exec db pg_dump -U paperless paperless > backup.sql

# With timestamp
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
docker compose exec db pg_dump -U paperless paperless > backup-${TIMESTAMP}.sql

Database Restore

# Stop the webserver first
docker compose stop webserver

# Restore database
docker compose exec -T db psql -U paperless -d postgres -c "DROP DATABASE IF EXISTS paperless;"
docker compose exec -T db psql -U paperless -d postgres -c "CREATE DATABASE paperless;"
docker compose exec -T db psql -U paperless paperless < backup.sql

# Restart webserver
docker compose start webserver

Media Backup

# Backup media files
tar -czvf media-backup.tar.gz ./media/

# Or use rsync for incremental backups
rsync -avz ./media/ /backup/location/media/

Full System Backup Script

#!/bin/bash
BACKUP_DIR="/backups/paperless"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# Create backup directory
mkdir -p "${BACKUP_DIR}/${TIMESTAMP}"

# Database backup
docker compose exec -T db pg_dump -U paperless paperless > "${BACKUP_DIR}/${TIMESTAMP}/database.sql"

# Media backup
tar -czvf "${BACKUP_DIR}/${TIMESTAMP}/media.tar.gz" ./media/

# Configuration backup
cp .env "${BACKUP_DIR}/${TIMESTAMP}/.env"
cp docker-compose.yml "${BACKUP_DIR}/${TIMESTAMP}/docker-compose.yml"

echo "Backup complete: ${BACKUP_DIR}/${TIMESTAMP}"

Environment Promotion

Dev → Stage

# From prod directory, create backup
cd deploy/03_prod
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
docker compose exec -T db pg_dump -U paperless paperless > ../prod-db-${TIMESTAMP}.sql

# Copy to stage
cd ../02_stage
docker compose stop webserver

# Restore database
docker compose exec -T db psql -U paperless -d postgres -c "DROP DATABASE IF EXISTS paperless;"
docker compose exec -T db psql -U paperless -d postgres -c "CREATE DATABASE paperless OWNER paperless;"
docker compose exec -T db psql -U paperless paperless < ../prod-db-${TIMESTAMP}.sql

# Sync media files
rsync -avz ../03_prod/media/ ./media/

# Start services
docker compose start webserver

Stage → Prod

Follow the same process, replacing source and destination directories.

Monitoring

Check Service Status

# View all services
docker compose ps

# Check logs
docker compose logs -f webserver
docker compose logs -f --tail=100 webserver

# Check specific service
docker compose logs gotenberg
docker compose logs tika

Health Checks

# Check Paperless
curl -I http://localhost:18000/api/

# Check Gotenberg
curl http://localhost:3000/health

# Check Tika
curl http://localhost:9998/tika

Resource Usage

# Container stats
docker stats

# Disk usage
docker system df

Troubleshooting

Common Issues

502 Bad Gateway

Cause: Webserver not running or unhealthy

# Check webserver status
docker compose ps webserver

# View logs
docker compose logs webserver

# Restart
docker compose restart webserver

Document Import Failures

Cause: Corrupt files, unsupported formats, or service issues

# Check consumer logs
docker compose logs webserver | grep -i consumer

# Check for Tika errors
docker compose logs tika

# Check for Gotenberg errors
docker compose logs gotenberg

OCR Not Working

Cause: Missing language packs or Tesseract issues

# Check OCR settings
docker compose exec webserver printenv | grep OCR

# Install additional language
# Add to Dockerfile: apt-get install tesseract-ocr-deu

Database Connection Errors

Cause: Database not ready or credentials mismatch

# Check database status
docker compose ps db
docker compose logs db

# Test connection
docker compose exec webserver python manage.py dbshell

Debug Mode

Enable detailed logging:

# In .env
PAPERLESS_DEBUG=true
PAPERLESS_LOGGING_LEVEL=DEBUG

Reset Admin Password

docker compose exec webserver python manage.py changepassword admin

Rebuild Index

docker compose exec webserver document_index reindex

Security Best Practices

Secrets Management

  1. Never commit .env files to version control
  2. Use strong, unique passwords for each environment
  3. Rotate PAPERLESS_SECRET_KEY periodically
  4. Use different credentials for dev/stage/prod

Network Security

  1. Use Cloudflare Tunnel instead of exposing ports
  2. Enable Cloudflare Access for additional authentication
  3. Keep Docker and services updated
  4. Use internal networks for service communication

File Permissions

# Ensure proper ownership
chown -R 1000:1000 media/ data/ consume/

# Restrict permissions
chmod 700 media/ data/
chmod 750 consume/

Maintenance Tasks

Regular Maintenance

Task Frequency Command
Backup database Daily pg_dump
Backup media Weekly rsync
Update containers Monthly docker compose pull
Prune Docker Monthly docker system prune
Check logs Weekly docker compose logs

Update Procedure

# Pull latest images
docker compose pull

# Recreate containers
docker compose up -d

# Check logs for issues
docker compose logs -f

Cleanup Old Data

# Remove unused Docker resources
docker system prune -a

# Clean up old backups (keep last 30 days)
find /backups -type f -mtime +30 -delete

Cloudflare Tunnel Setup

Create Tunnel

  1. Go to Cloudflare Zero Trust Dashboard
  2. Navigate to Networks → Tunnels
  3. Create a new tunnel
  4. Copy the tunnel token

Configure Tunnel

Create config.yml:

tunnel: your-tunnel-id
credentials-file: /etc/cloudflared/credentials.json

ingress:
  - hostname: paperless-dev.example.com
    service: http://webserver:8000
  - hostname: paperless-stage.example.com
    service: http://webserver:8000
  - hostname: paperless-prod.example.com
    service: http://webserver:8000
  - service: http_status:404

DNS Configuration

Cloudflare automatically creates DNS records when using tunnels. Verify:

  1. Go to DNS settings in Cloudflare
  2. Confirm CNAME records point to tunnel
  3. Enable proxy (orange cloud)

Quick Reference

Common Commands

# Start services
docker compose up -d

# Stop services
docker compose down

# View logs
docker compose logs -f

# Restart service
docker compose restart webserver

# Execute command in container
docker compose exec webserver python manage.py [command]

# Backup database
docker compose exec db pg_dump -U paperless paperless > backup.sql

# Restore database
docker compose exec -T db psql -U paperless paperless < backup.sql

Important Paths

Path Description
/deploy/01_dev/ Development environment
/deploy/02_stage/ Staging environment
/deploy/03_prod/ Production environment
./media/ Document storage
./consume/ Import folder
./export/ Export folder

Support Resources