Self-Hosting DocuSeal with Docker Compose
What DocuSeal Does
DocuSeal is an open-source document signing platform that lets you create PDF forms with a drag-and-drop builder, send them to recipients, and collect e-signatures through a mobile-optimized interface. It replaces services like DocuSign, Adobe Sign, and HelloSign with something you control entirely.
Built with Ruby on Rails, DocuSeal supports 12 field types (signature, date, file, checkbox, and more), multiple submitters per document, and SMTP-based email notifications. It stores files on disk or optionally in S3-compatible cloud storage.
Prerequisites
- A Linux server (Ubuntu 22.04+ or Debian 12+)
- Docker and Docker Compose installed (Docker Compose guide)
- 1 GB RAM minimum (2 GB recommended with PostgreSQL)
- 2 GB of free disk space, plus storage for uploaded documents
- A domain name for remote access (optional but recommended)
Docker Compose Configuration
Create a directory for DocuSeal and a docker-compose.yml file:
mkdir -p ~/docuseal && cd ~/docuseal
services:
app:
image: docuseal/docuseal:2.4.0
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
ports:
- "3000:3000"
volumes:
- docuseal-data:/data/docuseal
environment:
- DATABASE_URL=postgresql://docuseal:changeme-db-password@postgres:5432/docuseal
- SECRET_KEY_BASE=generate-a-64-char-random-string-here-use-openssl-rand-hex-32
postgres:
image: postgres:16
restart: unless-stopped
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_USER: docuseal
POSTGRES_PASSWORD: changeme-db-password # Must match DATABASE_URL above
POSTGRES_DB: docuseal
healthcheck:
test: ["CMD-SHELL", "pg_isready -U docuseal"]
interval: 5s
timeout: 5s
retries: 5
volumes:
docuseal-data:
postgres-data:
Generate a secret key before starting:
openssl rand -hex 32
Replace generate-a-64-char-random-string-here-use-openssl-rand-hex-32 with the output, and change changeme-db-password to a strong password in both the app and postgres service sections.
Start the stack:
docker compose up -d
DocuSeal will be available at http://your-server-ip:3000.
Initial Setup
- Open
http://your-server-ip:3000in your browser - Create an admin account on first visit
- Navigate to Settings → Email to configure SMTP for sending signing requests (SMTP is configured through the web UI, not environment variables)
- Upload your first PDF document and use the form builder to add signature fields
Key Features
| Feature | Details |
|---|---|
| Form builder | WYSIWYG drag-and-drop with 12 field types |
| Multi-signer | Multiple submitters per document with configurable order |
| File storage | Local disk (default) or S3-compatible cloud storage |
| API | REST API and webhooks for automation |
| Embedding | React, Vue, Angular, and JavaScript SDKs for embedded signing |
| Languages | UI in 7 languages, signing interface in 14 languages |
| Database | PostgreSQL (recommended), MySQL, or SQLite |
S3 Storage Configuration
To store documents in S3-compatible storage instead of local disk, add these environment variables to the app service:
environment:
- AWS_ACCESS_KEY_ID=your-access-key
- AWS_SECRET_ACCESS_KEY=your-secret-key
- AWS_REGION=us-east-1
- AWS_BUCKET=your-bucket-name
This works with AWS S3, MinIO, DigitalOcean Spaces, and other S3-compatible providers.
Reverse Proxy
Place DocuSeal behind a reverse proxy for SSL termination. With Caddy:
sign.example.com {
reverse_proxy localhost:3000
}
See the full Reverse Proxy Setup Guide for Nginx Proxy Manager and Traefik configurations.
Backup
Back up these volumes regularly:
docuseal-data— uploaded documents and application datapostgres-data— the PostgreSQL database
# Database backup
docker compose exec postgres pg_dump -U docuseal docuseal > backup.sql
See Backup Strategy for automated backup approaches.
Troubleshooting
Container fails to start with database connection error
Symptom: PG::ConnectionBad: could not connect to server
Fix: Ensure POSTGRES_PASSWORD in the postgres service matches the password in DATABASE_URL. Wait for the health check — the depends_on condition ensures PostgreSQL is ready.
Emails not sending
Symptom: Signing requests don’t arrive via email Fix: Configure SMTP through the DocuSeal admin UI at Settings → Email. SMTP is not set via environment variables — it’s managed in the web interface.
Permission denied on volume mount
Symptom: Permission denied errors on /data/docuseal
Fix: The container runs as a non-root user. Ensure the volume directory is writable: sudo chown -R 1000:1000 ./docuseal if using bind mounts.
Resource Requirements
| Resource | Minimum | Recommended |
|---|---|---|
| RAM | 512 MB (with SQLite) | 1 GB (with PostgreSQL) |
| CPU | 1 vCPU | 2 vCPUs |
| Disk | 2 GB + document storage | 5 GB + document storage |
Verdict
DocuSeal is the most polished self-hosted document signing platform available. The WYSIWYG form builder is genuinely good — better than most commercial alternatives at the basic tier. It handles the common document signing workflow (upload PDF, place fields, send for signature) without any rough edges.
Choose DocuSeal if you sign documents regularly and want to stop paying DocuSign’s per-envelope pricing. The PostgreSQL setup is straightforward, SMTP configuration through the web UI is convenient, and the API is solid for automation. If you need a simpler setup with fewer features, look at DocuSeal vs Documenso for a comparison.
FAQ
Is DocuSeal free for commercial use?
Yes. DocuSeal Community Edition is AGPL-3.0 licensed. The Enterprise Edition (paid) adds advanced features like LDAP/SSO, custom branding, and audit reports. The free version covers all core signing functionality with no document or user limits.
Can I use DocuSeal without PostgreSQL?
Yes. DocuSeal supports SQLite out of the box — just remove the PostgreSQL service from docker-compose.yml and set DATABASE_URL to a SQLite file path. SQLite is fine for small teams but PostgreSQL is recommended for production.
Are signatures collected through DocuSeal legally binding?
Yes. Electronic signatures collected through DocuSeal are legally valid under ESIGN (US), UETA (US states), and eIDAS (EU). DocuSeal generates an audit trail with timestamps, IP addresses, and signer information for each document.
Can I store documents in S3 instead of local disk?
Yes. Set the S3 configuration environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_BUCKET, AWS_REGION) and DocuSeal stores all uploaded and signed documents in S3-compatible storage (AWS, MinIO, DigitalOcean Spaces, Backblaze B2).
Does DocuSeal have an API?
Yes. DocuSeal provides a REST API for creating templates, submitting documents for signing, and retrieving submission status. API tokens are managed in the admin panel. This enables automated signing workflows from your applications.
Can multiple people sign the same document?
Yes. DocuSeal supports multiple submitters per document — each signer gets their own signature fields and email notification. Signers complete their portions independently, and the final document includes all signatures.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments