Skip to main content

Prerequisites

Before starting, ensure you have:
  • Docker 20.10 or later
  • Docker Compose v2.0 or later
  • SMTP credentials for sending emails
  • At least 2GB of available RAM
  • A domain name (for production deployments)
Verify your installation:
docker --version
docker compose version

Quick Start

1. Download Compose File

Download the production Docker Compose file:
mkdir documenso && cd documenso
curl -O https://raw.githubusercontent.com/documenso/documenso/release/docker/production/compose.yml
Alternatively, clone the full repository:
git clone https://github.com/documenso/documenso.git
cd documenso/docker/production

2. Create Environment File

Create a .env file:
touch .env
Add the following required configuration:
# Database credentials
POSTGRES_USER=documenso
POSTGRES_PASSWORD=your-secure-database-password
POSTGRES_DB=documenso

# Application secrets (generate with: openssl rand -base64 32)
NEXTAUTH_SECRET=your-nextauth-secret
NEXT_PRIVATE_ENCRYPTION_KEY=your-encryption-key-min-32-characters
NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY=your-secondary-key-min-32-characters

# Public URL where Documenso is accessible
NEXT_PUBLIC_WEBAPP_URL=https://sign.example.com
NEXT_PRIVATE_INTERNAL_WEBAPP_URL=http://localhost:3000

# Database connection (uses Docker service name)
NEXT_PRIVATE_DATABASE_URL=postgresql://documenso:your-secure-database-password@database:5432/documenso

# Email configuration
NEXT_PRIVATE_SMTP_TRANSPORT=smtp-auth
NEXT_PRIVATE_SMTP_HOST=smtp.example.com
NEXT_PRIVATE_SMTP_PORT=587
NEXT_PRIVATE_SMTP_USERNAME=your-smtp-username
NEXT_PRIVATE_SMTP_PASSWORD=your-smtp-password
NEXT_PRIVATE_SMTP_FROM_NAME=Documenso
NEXT_PRIVATE_SMTP_FROM_ADDRESS=noreply@example.com

# Signing certificate
NEXT_PRIVATE_SIGNING_PASSPHRASE=your-certificate-password
Generate secure secrets using: openssl rand -base64 32

3. Generate Secrets

Generate the required secrets:
# Generate NEXTAUTH_SECRET
echo "NEXTAUTH_SECRET=$(openssl rand -base64 32)"

# Generate encryption keys
echo "NEXT_PRIVATE_ENCRYPTION_KEY=$(openssl rand -base64 32)"
echo "NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY=$(openssl rand -base64 32)"

# Generate database password
echo "POSTGRES_PASSWORD=$(openssl rand -base64 24)"

4. Set Up Signing Certificate

Place your .p12 signing certificate on the host machine:
sudo mkdir -p /opt/documenso
sudo cp /path/to/your/cert.p12 /opt/documenso/cert.p12
sudo chown 1001:1001 /opt/documenso/cert.p12
sudo chmod 400 /opt/documenso/cert.p12
The Documenso container runs as UID 1001. The certificate must be readable by this user.

5. Start Services

Start all services:
docker compose --env-file .env up -d
Check container status:
docker compose ps
Expected output:
NAME                             STATUS              PORTS
documenso-production-database-1  running (healthy)   5432/tcp
documenso-production-documenso-1 running             0.0.0.0:3000->3000/tcp

6. View Logs

Monitor the startup process:
docker compose logs -f documenso
Look for:
  • “Running database migrations…”
  • “Starting Documenso server…”
  • “Ready” or “Listening on port 3000”

Docker Compose File Reference

The production compose.yml includes two services:
name: documenso-production

services:
  database:
    image: postgres:15
    environment:
      - POSTGRES_USER=${POSTGRES_USER:?err}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?err}
      - POSTGRES_DB=${POSTGRES_DB:?err}
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER}']
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - database:/var/lib/postgresql/data

  documenso:
    image: documenso/documenso:latest
    depends_on:
      database:
        condition: service_healthy
    environment:
      # All NEXT_* variables from .env file
    ports:
      - ${PORT:-3000}:${PORT:-3000}
    volumes:
      - /opt/documenso/cert.p12:/opt/documenso/cert.p12:ro

volumes:
  database:

Service Descriptions

ServicePurpose
databasePostgreSQL 15 database with persistent storage
documensoMain application container, waits for database to be healthy
The documenso service uses a health check dependency to ensure the database is ready before starting.

Configuration

Required Environment Variables

VariableDescription
POSTGRES_USERDatabase username
POSTGRES_PASSWORDDatabase password
POSTGRES_DBDatabase name
NEXTAUTH_SECRETNextAuth.js encryption secret
NEXT_PRIVATE_ENCRYPTION_KEYPrimary encryption key (min 32 chars)
NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEYSecondary encryption key (min 32 chars)
NEXT_PUBLIC_WEBAPP_URLPublic URL of your Documenso instance
NEXT_PRIVATE_DATABASE_URLDatabase connection string
NEXT_PRIVATE_SMTP_TRANSPORTEmail transport type (smtp-auth, smtp-api, resend)
NEXT_PRIVATE_SMTP_FROM_NAMESender name for emails
NEXT_PRIVATE_SMTP_FROM_ADDRESSSender email address

Optional Environment Variables

# Application port (default: 3000)
PORT=3000

# Disable public signups
NEXT_PUBLIC_DISABLE_SIGNUP=false

# Storage (default: database)
NEXT_PUBLIC_UPLOAD_TRANSPORT=database

# Document upload limit in MB
NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT=5
For the complete list of environment variables, see the Environment Variables reference.

Accessing Documenso

Once containers are running:
  • Local access: Open http://localhost:3000
  • Remote access: Use the URL configured in NEXT_PUBLIC_WEBAPP_URL

First Account Setup

  1. Navigate to the signup page
  2. Create your account
  3. Verify your email address
All accounts created through signup are regular user accounts. Admin access must be granted directly in the database. Once your accounts are set up, consider disabling public signups by setting NEXT_PUBLIC_DISABLE_SIGNUP=true.

Managing Services

View Logs

# View all service logs
docker compose logs -f

# View specific service logs
docker compose logs -f documenso
docker compose logs -f database

Restart Services

# Restart all services
docker compose --env-file .env restart

# Restart specific service
docker compose --env-file .env restart documenso

Stop Services

# Stop without removing containers
docker compose stop

# Stop and remove containers (preserves volumes)
docker compose down
Using docker compose down -v deletes the database volume. Always backup your data first!

Update Documenso

  1. Pull the latest image:
docker compose pull
  1. Recreate containers:
docker compose --env-file .env up -d
Database migrations run automatically on container startup.
Always backup your database before upgrading. See Backups.

Production Recommendations

Use a Reverse Proxy

Place Documenso behind a reverse proxy for SSL termination. See the Reverse Proxy guide for detailed configurations.

Pin Docker Image Version

Instead of using latest, pin to a specific version:
services:
  documenso:
    image: documenso/documenso:1.5.0  # Replace with specific version

Set Resource Limits

Add resource limits to prevent container resource exhaustion:
services:
  documenso:
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G
        reservations:
          cpus: '0.5'
          memory: 512M
  
  database:
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 1G
        reservations:
          cpus: '0.25'
          memory: 256M

Use External Database

For production, consider using a managed PostgreSQL service:
  1. Remove the database service from compose.yml
  2. Update environment variables:
NEXT_PRIVATE_DATABASE_URL=postgresql://user:password@your-db-host:5432/documenso
NEXT_PRIVATE_DIRECT_DATABASE_URL=postgresql://user:password@your-db-host:5432/documenso
Supported managed database providers:
  • AWS RDS for PostgreSQL
  • Google Cloud SQL
  • Azure Database for PostgreSQL
  • DigitalOcean Managed Databases

Configure S3 Storage

For high-volume deployments, use S3-compatible storage:
NEXT_PUBLIC_UPLOAD_TRANSPORT=s3
NEXT_PRIVATE_UPLOAD_BUCKET=your-bucket
NEXT_PRIVATE_UPLOAD_REGION=us-east-1
NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID=your-access-key
NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY=your-secret-key
See Storage Configuration for details.

Set Up Database Backups

Create regular backups:
# Manual backup
docker compose exec database pg_dump -U documenso documenso > backup-$(date +%Y%m%d).sql

# Restore from backup
docker compose exec -T database psql -U documenso documenso < backup.sql
See Backups for automated backup strategies.

Troubleshooting

Container Fails to Start

Check logs:
docker compose logs documenso
Common causes:
  • Missing environment variables (ensure all required variables are in .env)
  • Database not ready (the container waits for database health check)
  • Port conflict (change PORT in .env if 3000 is in use)

Database Connection Errors

Verify the database is healthy:
docker compose ps database
Test connection:
docker compose exec database psql -U documenso -d documenso -c "SELECT 1"

Certificate Errors

Check certificate status:
curl http://localhost:3000/api/certificate-status
Common issues:
  • File not found: Verify volume mount in compose.yml
  • Permission denied: Run sudo chown 1001:1001 on the certificate file
  • No password: The certificate must have a password set via NEXT_PRIVATE_SIGNING_PASSPHRASE

Emails Not Sending

Verify SMTP configuration:
# Check logs for SMTP errors
docker compose logs documenso | grep -i smtp
Common issues:
  • NEXT_PRIVATE_SMTP_TRANSPORT doesn’t match your setup
  • Incorrect host, port, username, or password
  • Firewall blocking outbound SMTP traffic

Application Unreachable

Check:
  1. Containers are running: docker compose ps
  2. Port mapping matches your .env
  3. Local health check: curl http://localhost:3000/api/health
  4. Firewall rules allow traffic on the configured port

Out of Disk Space

Check disk usage:
docker system df
Clean up unused resources:
docker system prune -a

See Also