π Complete Docker Swarm deployment solution for Papermark - the open-source DocSend alternative with built-in analytics and custom domains.
- π³ Production-Ready Docker Deployment - Optimized multi-stage builds
- π Automated CI/CD - GitHub Actions workflow with PR merging support
- π Traefik Integration - Automatic SSL certificates and load balancing
- ποΈ PostgreSQL Database - Included with automatic backups
- π¦ S3-Compatible Storage - AWS S3, MinIO, Backblaze B2, or any S3-compatible service
- π§ Email Support - Resend integration for transactional emails
- π OAuth Authentication - Google and GitHub login support
- π Optional Analytics - Tinybird integration for document tracking
- π High Availability - Multi-replica support with sticky sessions
- π Security Hardened - Rate limiting, security headers, and best practices
.
βββ .github/
β βββ workflows/
β βββ build-and-push.yml # Automated build and push workflow
βββ docker-compose.papermark.yml # Production stack configuration
βββ Dockerfile.papermark # Optimized multi-stage Dockerfile
βββ .env.example # Environment configuration template
βββ DEPLOYMENT.md # Comprehensive deployment guide
βββ setup.sh # Interactive setup script
βββ README.md # This file
- Docker Engine 20.10+ with Swarm mode
- Traefik v2+ reverse proxy
- Minimum 2GB RAM (4GB recommended)
- Domain name with DNS configured
git clone https://github.com/avnox-com/papermark-self-host.git
cd papermark-self-hostchmod +x setup.sh
./setup.shThe interactive script will help you configure:
- Domain name
- Database credentials (auto-generated)
- Storage backend (S3, MinIO, etc.)
- Email service (Resend)
- OAuth providers (Google, GitHub)
# Deploy to Docker Swarm
docker stack deploy -c docker-compose.papermark.yml papermark
# Check status
docker stack ps papermarkVisit https://your-domain.com and create your first account!
Copy .env.example to .env and configure:
# Core Settings
PAPERMARK_PUBLIC_URL=https://papermark.yourdomain.com
PAPERMARK_DOMAIN=papermark.yourdomain.com
NEXTAUTH_SECRET=your-secret-here
# Database
POSTGRES_PASSWORD=your-secure-password
# Storage (choose one)
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret
AWS_S3_BUCKET_NAME=your-bucket
# Email
RESEND_API_KEY=re_your-key
EMAIL_FROM=noreply@yourdomain.com
# Authentication (optional)
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-secretSee .env.example for all available options.
βββββββββββββββ
β Traefik β β Reverse Proxy + SSL
ββββββββ¬βββββββ
β
βββ ββββββββββββββββ
β β Papermark β β Next.js Application (Multi-replica)
β β (2 replicas)β
β ββββββββ¬ββββββββ
β β
β βββ ββββββββββββββ
β β β PostgreSQL β β Database
β β ββββββββββββββ
β β
β βββ ββββββββββββββ
β β Redis β β Caching
β ββββββββββββββ
β
βββ S3-Compatible Storage (AWS S3, MinIO, etc.)
The GitHub Actions workflow automatically:
- β Checks out your repository
- β Clones the latest Papermark source
- β Optionally merges PRs for testing
- β Builds optimized Docker images
- β Pushes to your container registry
- β Supports WireGuard for private registries
# Required
REGISTRY=ghcr.io
REGISTRY_USERNAME=your-github-username
REGISTRY_PASSWORD=your-github-token
IMAGE_PREFIX=ghcr.io/avnox-com
# Optional
REGISTRY_IP=10.0.0.1 # For private registry via WireGuard
WG_CONF=<wireguard-config> # Full wg0.conf contentEdit .github/workflows/build-and-push.yml:
env:
PAPERMARK_PRS: "123,456" # PR numbers to merge and testBLOB_STORAGE_TYPE=s3
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
AWS_S3_BUCKET_NAME=papermark-uploads
AWS_REGION=us-east-1# Add MinIO to docker-compose and configure:
BLOB_STORAGE_TYPE=s3
AWS_ACCESS_KEY_ID=minioadmin
AWS_SECRET_ACCESS_KEY=minioadmin
S3_ENDPOINT=http://minio:9000
S3_FORCE_PATH_STYLE=true
AWS_S3_BUCKET_NAME=papermarkBLOB_STORAGE_TYPE=s3
AWS_ACCESS_KEY_ID=your-key-id
AWS_SECRET_ACCESS_KEY=your-app-key
S3_ENDPOINT=https://s3.us-west-001.backblazeb2.com
AWS_S3_BUCKET_NAME=your-bucket
AWS_REGION=us-west-001- Create project at Google Cloud Console
- Enable Google+ API
- Create OAuth 2.0 credentials
- Add redirect URI:
https://yourdomain.com/api/auth/callback/google - Add credentials to
.env
- Go to GitHub Developer Settings
- Create new OAuth App
- Set callback:
https://yourdomain.com/api/auth/callback/github - Add credentials to
.env
# All services
docker stack ps papermark
# Specific service
docker service logs -f papermark_papermark
docker service logs -f papermark_postgres# Scale Papermark horizontally
docker service scale papermark_papermark=4
# Or edit .env and redeploy
PAPERMARK_REPLICAS=4
docker stack deploy -c docker-compose.papermark.yml papermark# Automatic via GitHub Actions
git push origin main
# Or manual
docker service update --image ghcr.io/avnox-com/papermark:latest papermark_papermarkBackups are automatic! Configure in .env:
BACKUP_PATH=./backups
BACKUP_SCHEDULE=@daily
BACKUP_KEEP_DAYS=7
BACKUP_KEEP_WEEKS=4
BACKUP_KEEP_MONTHS=6Manual backup:
docker exec -it $(docker ps -q -f name=papermark_postgres) \
pg_dump -U papermark papermark > backup-$(date +%Y%m%d).sql# Check service health
curl https://your-domain.com/api/health
# Service status
docker service ps papermark_papermark# Container stats
docker stats $(docker ps -q -f name=papermark)
# Service details
docker service inspect papermark_papermark --pretty# Check logs
docker service logs papermark_papermark --tail 100 --follow
# Inspect service
docker service ps papermark_papermark --no-trunc# Test connection
docker exec -it $(docker ps -q -f name=papermark_postgres) \
psql -U papermark -d papermark -c "SELECT version();"# Test AWS S3
aws s3 ls s3://your-bucket --profile papermark
# Test MinIO
docker exec -it $(docker ps -q -f name=minio) \
mc alias set local http://localhost:9000 minioadmin minioadminSee DEPLOYMENT.md for comprehensive troubleshooting.
β
Use strong, randomly generated secrets
β
Enable HTTPS only (enforced by Traefik)
β
Configure rate limiting (included)
β
Regular backups (automated)
β
Keep software updated
β
Use separate credentials for each service
β
Review logs for suspicious activity
β
Use firewall rules to restrict access
- Horizontal Scaling: Increase
PAPERMARK_REPLICAS - Resource Limits: Adjust CPU/Memory in docker-compose
- Redis Caching: Ensure Redis is running
- CDN: Consider CloudFlare or similar for static assets
- Database: Regular
VACUUM ANALYZEand indexing
Found a bug or have a feature request? Please open an issue!
Want to improve this deployment? PRs are welcome!
This deployment configuration is licensed under MIT.
Papermark itself is licensed under AGPL-3.0 - some features may require enterprise license for commercial use.
- Papermark - The amazing open-source project
- Traefik - Modern HTTP reverse proxy
- Docker - Container platform
Made with β€οΈ for the self-hosting community