Docker Compose
Deploy Documenso with Docker Compose, including PostgreSQL. This production-ready setup is suitable for most self-hosted deployments.
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 versionClone and Configure
Download the compose file
Download the production Docker Compose file:
mkdir documenso && cd documenso
curl -O https://raw.githubusercontent.com/documenso/documenso/release/docker/production/compose.ymlAlternatively, clone the full repository:
git clone https://github.com/documenso/documenso.git
cd documenso/docker/productionCreate environment file
Create a .env file in the same directory as compose.yml:
touch .envAdd the required configuration (see Environment Configuration below).
The compose.yml in the repository may be outdated. Use it as a starting point and verify the
configuration against the environment variables documented here.
Docker Compose File Overview
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:
# See environment configuration below
ports:
- ${PORT:-3000}:${PORT:-3000}
volumes:
- /opt/documenso/cert.p12:/opt/documenso/cert.p12:ro
volumes:
database:| Service | Purpose |
|---|---|
database | PostgreSQL 15 database with persistent storage |
documenso | Main application container, waits for database to be healthy |
The Documenso container waits for the database health check to pass before starting.
Environment Configuration
Create a .env file with the following variables:
Required Variables
# Database (used by both database and documenso services)
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.comOptional Variables
# Application port (default: 3000)
PORT=3000
# Signing certificate (see Signing Certificate section)
NEXT_PRIVATE_SIGNING_PASSPHRASE=your-certificate-password
# Disable public signups
NEXT_PUBLIC_DISABLE_SIGNUP=falseopenssl rand -base64 32For the complete list of environment variables, see Environment Variables.
Generating 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)"Signing Certificate
A signing certificate is required for document signing. Generate a .p12 certificate on your host machine and mount it into the container. See Local Certificate for how to generate one.
Place the certificate on the host and set permissions so the container can read it (UID 1001):
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.p12The compose.yml mounts this path into the container. Add the passphrase to your .env file:
NEXT_PRIVATE_SIGNING_PASSPHRASE=your-certificate-passwordIf file mounting is not available, you can set NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS with the base64-encoded certificate string instead.
For production deployments that require Adobe Approved Trust List recognition, consider using a Google Cloud HSM or another external HSM.
Do not generate or store the signing certificate inside the container. If the container is destroyed and rebuilt, or if you run multiple instances, the certificate will be lost or inconsistent. Always provide the certificate externally.
Starting Services
Start all services:
docker compose --env-file .env up -dCheck that containers are running:
docker compose psExpected output:
NAME STATUS PORTS
documenso-production-database-1 running (healthy) 5432/tcp
documenso-production-documenso-1 running 0.0.0.0:3000->3000/tcpWait for the database to be healthy and for migrations to complete. Check the logs:
docker compose logs -f documensoLook for "Ready" or "Listening on port 3000" in the output.
Accessing Documenso
Once the containers are running:
- Local access: Open http://localhost:3000
- Remote access: Use the URL configured in
NEXT_PUBLIC_WEBAPP_URL
First Account Setup
Navigate to the signup page and create your account. Verify your email address — if emails are not being delivered, check the container logs for SMTP errors.
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 -fView logs for a specific service:
docker compose logs -f documenso
docker compose logs -f databaseRestart Services
Restart all services:
docker compose --env-file .env restartRestart a specific service:
docker compose --env-file .env restart documensoStop Services
Stop without removing containers:
docker compose stopStop and remove containers (preserves volumes):
docker compose downStop, remove containers, and delete data:
docker compose down -vUsing down -v deletes the database volume. Back up your data first.
Update Documenso
Pull the latest image:
docker compose pullRecreate containers:
docker compose --env-file .env up -dDatabase migrations run automatically on container startup.
Back up your database before upgrading. See Backups.
Production Considerations
Reverse Proxy
For production, place Documenso behind a reverse proxy for SSL termination:
nginx example:
server {
listen 443 ssl http2;
server_name sign.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}Caddy example:
sign.example.com {
reverse_proxy localhost:3000
}Database Backups
Set up automated database backups:
# Manual backup
docker compose exec database pg_dump -U documenso documenso > backup.sql
# Restore from backup
docker compose exec -T database psql -U documenso documenso < backup.sqlSee Backups for automated backup strategies.
Resource Limits
Add resource limits to prevent container resource exhaustion:
services:
documenso:
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '0.5'
memory: 512MExternal 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/documensoS3 Storage
For high-volume deployments, configure 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-keyTroubleshooting
See Also
- Environment Variables - Full configuration reference
- Signing Certificate - Certificate setup details
- Email Configuration - SMTP and email provider setup
- Storage Configuration - S3 storage setup
- Backups - Backup strategies
- Upgrades - Upgrade procedures