Self-Hosting CryptPad with Docker Compose
End-to-End Encrypted Documents
Most self-hosted office suites encrypt data at rest. CryptPad encrypts it before it ever leaves the browser. The server stores only ciphertext — even as the admin, you can’t read your users’ documents. CryptPad supports rich text documents, spreadsheets, presentations, Kanban boards, whiteboards, forms, and code editing, all with real-time collaboration and zero-knowledge encryption.
It’s AGPL-3.0 licensed, requires no external database, and runs on modest hardware. If privacy is your primary concern, CryptPad is the only serious option.
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 512 MB RAM minimum (2 GB recommended)
- 10 GB free disk space
- Two domains or subdomains (security requirement — see below)
| Resource | Minimum | Recommended |
|---|---|---|
| RAM | 512 MB | 2 GB |
| CPU | 1 core | 2 cores |
| Disk | 200 MB (app) | 10+ GB (grows with docs) |
| Idle RAM | ~150 MB | ~300 MB |
CryptPad is lightweight. It’s a Node.js application with file-based storage — no PostgreSQL, no Redis, no external dependencies.
The Dual-Domain Requirement
CryptPad’s security model requires two separate origins (different domains or subdomains):
- Main domain (
cryptpad.example.com) — handles account authentication and cryptographic operations - Sandbox domain (
sandbox.example.com) — loads the editing UI in an isolated context
This prevents XSS attacks in the editor from accessing your encryption keys. Both domains must point to the same server and be served via HTTPS.
Example DNS setup:
cryptpad.example.com A your-server-ip
sandbox.example.com A your-server-ip
Docker Compose Configuration
Create the data directories first — CryptPad runs as UID 4001 inside the container:
mkdir -p data/{blob,block,files,data} customize
chown -R 4001:4001 data/
Create a docker-compose.yml:
services:
cryptpad:
image: cryptpad/cryptpad:2026.2.0
container_name: cryptpad
environment:
- CPAD_MAIN_DOMAIN=https://cryptpad.example.com
- CPAD_SANDBOX_DOMAIN=https://sandbox.example.com
- CPAD_CONF=/cryptpad/config/config.js
ports:
- "3000:3000" # HTTP
- "3003:3003" # WebSocket (real-time sync)
volumes:
- ./data/blob:/cryptpad/blob
- ./data/block:/cryptpad/block
- ./data/files:/cryptpad/datastore
- ./data/data:/cryptpad/data
- ./customize:/cryptpad/customize
ulimits:
nofile:
soft: 1000000
hard: 1000000
restart: unless-stopped
Start it:
docker compose up -d
No .env file needed — CryptPad’s configuration is minimal. The domains are the only required settings.
Reverse Proxy Configuration
CryptPad needs a reverse proxy that:
- Serves HTTPS on both domains
- Forwards HTTP to port 3000
- Forwards WebSocket connections (
/cryptpad_websocket) to port 3003
Caddy (simplest — auto-SSL for both domains):
cryptpad.example.com, sandbox.example.com {
reverse_proxy cryptpad:3000
@websocket {
path /cryptpad_websocket
}
reverse_proxy @websocket cryptpad:3003
}
Nginx Proxy Manager: Create two proxy hosts (one per domain) pointing to port 3000. Add a custom Nginx location for WebSocket forwarding:
location /cryptpad_websocket {
proxy_pass http://cryptpad:3003;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
See Reverse Proxy Setup for detailed configuration.
Initial Setup
- Open
https://cryptpad.example.comin your browser - Click Register to create the first account
- Important: The first registered account is NOT automatically an admin. To grant admin access, edit
config.js
Setting Up Admin Access
Get the public signing key of your account:
- Log in to CryptPad
- Open User Menu → Settings → Account
- Copy the Public Signing Key (starts with a bracket, like
[cryptpad-user1@...])
Then add it to the config:
docker exec -it cryptpad vi /cryptpad/config/config.js
Find adminKeys and add your key:
adminKeys: [
"[your-public-signing-key-here]",
],
Restart the container:
docker compose restart cryptpad
What You Can Create
| Document Type | Description | Collaboration |
|---|---|---|
| Rich Text | Word processor with formatting | Real-time, multi-cursor |
| Spreadsheet | Excel-like with formulas | Real-time |
| Presentation | Slide decks with themes | Real-time |
| Code/Markdown | Syntax-highlighted editor | Real-time |
| Kanban | Task boards with columns | Real-time |
| Whiteboard | Drawing and diagramming | Real-time |
| Form | Surveys and questionnaires | Creator + respondents |
| File Drive | Encrypted file storage | Upload/download |
All document types support sharing via links with configurable permissions (view, edit, or no access).
Configuration
Storage Limits
By default, registered users get unlimited storage. To set limits, edit config.js:
defaultStorageLimit: 50 * 1024 * 1024, // 50 MB per user
Admins can set per-user quotas through the admin panel.
Registration Controls
Disable open registration (invite-only mode):
restrictRegistration: true,
Existing admins can then generate invitation links.
Inactive Pad Cleanup
CryptPad stores every document version forever by default. To auto-expire unused documents:
inactiveTime: 90, // Days before a pad is considered inactive
archiveRetentionTime: 15, // Days to keep archived pads before deletion
OnlyOffice Integration
For better Office format compatibility, enable the ONLYOFFICE integration:
environment:
- CPAD_INSTALL_ONLYOFFICE=yes
volumes:
- ./onlyoffice-dist:/cryptpad/www/common/onlyoffice/dist
- ./onlyoffice-conf:/cryptpad/onlyoffice-conf
This embeds OnlyOffice editors inside CryptPad while maintaining CryptPad’s encryption layer.
Backup
CryptPad uses file-based storage. Back up the entire data/ directory:
tar czf cryptpad-backup-$(date +%Y%m%d).tar.gz data/
The data/block/ directory is the most critical — it contains document history. data/blob/ contains uploaded files.
Since there’s no database, backups are straightforward. See Backup Strategy for scheduling and rotation.
Troubleshooting
”This CryptPad instance is not configured correctly”
Symptom: Warning banner appears on every page.
Fix: The CPAD_MAIN_DOMAIN and CPAD_SANDBOX_DOMAIN must use https:// URLs and point to two different origins. If you’re using http:// or both domains resolve to the same origin, CryptPad flags a security misconfiguration. Set up your reverse proxy with SSL first.
Real-time sync not working
Symptom: Multiple users editing the same document don’t see each other’s changes.
Fix: The WebSocket connection on port 3003 must be forwarded through your reverse proxy. Check that /cryptpad_websocket requests reach port 3003. Test:
curl -i -N \
-H "Connection: Upgrade" \
-H "Upgrade: websocket" \
https://cryptpad.example.com/cryptpad_websocket
You should get a 101 Switching Protocols response.
Permission denied errors on startup
Symptom: Container crashes with “EACCES” errors.
Fix: CryptPad runs as UID 4001 inside the container. The data directories must be owned by this user:
chown -R 4001:4001 data/
Large file uploads silently fail
Symptom: File uploads in the Drive just stop without error.
Fix: The default max upload size is 20 MB. Increase it in config.js:
maxUploadSize: 100 * 1024 * 1024, // 100 MB
Also check your reverse proxy’s client_max_body_size (Nginx) or equivalent.
Storage grows indefinitely
Symptom: Disk usage keeps climbing even though users delete documents.
Fix: Deleted documents go to a server-side archive, not true deletion. Configure archiveRetentionTime in config.js to auto-purge after a set number of days. Run the built-in eviction script to clean up immediately.
CryptPad vs ONLYOFFICE
| Feature | CryptPad | ONLYOFFICE |
|---|---|---|
| Encryption | End-to-end (zero-knowledge) | At-rest only |
| Office format support | Limited (.docx import/export) | Excellent (native .docx/.xlsx/.pptx) |
| RAM requirement | 512 MB | 4 GB |
| External dependencies | None | PostgreSQL + RabbitMQ |
| Best for | Privacy-first teams | Office format compatibility |
| Real-time collaboration | Yes | Yes |
| Kanban/Whiteboard | Built-in | No |
Verdict
CryptPad is the only self-hosted office suite with true end-to-end encryption. The server never sees your data in plaintext — not even the admin. If privacy is non-negotiable, nothing else comes close. The trade-off is Office format compatibility: CryptPad uses its own format internally, with import/export support for common formats but without pixel-perfect fidelity.
Use CryptPad if: Privacy is your top priority, you don’t need heavy .docx/.xlsx editing, or you want built-in Kanban/whiteboard/forms alongside documents.
Look elsewhere if: You need seamless Microsoft Office compatibility (ONLYOFFICE is better), need to integrate with Nextcloud’s file management, or need a full-featured spreadsheet (CryptPad’s spreadsheet is functional but basic compared to ONLYOFFICE or Collabora).
Related
Get self-hosting tips in your inbox
New guides, comparisons, and setup tutorials — delivered weekly. No spam.