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:
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:
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
| Service | Purpose |
|---|
database | PostgreSQL 15 database with persistent storage |
documenso | Main 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
| Variable | Description |
|---|
POSTGRES_USER | Database username |
POSTGRES_PASSWORD | Database password |
POSTGRES_DB | Database name |
NEXTAUTH_SECRET | NextAuth.js encryption secret |
NEXT_PRIVATE_ENCRYPTION_KEY | Primary encryption key (min 32 chars) |
NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY | Secondary encryption key (min 32 chars) |
NEXT_PUBLIC_WEBAPP_URL | Public URL of your Documenso instance |
NEXT_PRIVATE_DATABASE_URL | Database connection string |
NEXT_PRIVATE_SMTP_TRANSPORT | Email transport type (smtp-auth, smtp-api, resend) |
NEXT_PRIVATE_SMTP_FROM_NAME | Sender name for emails |
NEXT_PRIVATE_SMTP_FROM_ADDRESS | Sender 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:
First Account Setup
- Navigate to the signup page
- Create your account
- 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
- Pull the latest image:
- 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:
- Remove the
database service from compose.yml
- 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
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:
- Containers are running:
docker compose ps
- Port mapping matches your
.env
- Local health check:
curl http://localhost:3000/api/health
- Firewall rules allow traffic on the configured port
Out of Disk Space
Check disk usage:
Clean up unused resources:
See Also