productivity · Deploy guide
Self-host Docmost
Open-source collaborative wiki and documentation software. Here's how to run Docmost on your own infrastructure — no marketing puffery, honest pitfalls, one recommended stack.
Every guide on SwapToSaaS runs on servers we actually pay for. Docmost's footprint fits comfortably on this class of instance. Different provider preference? The steps below work anywhere Docker runs.
Provision a server →Before you start
Docmost is the sleeper hit of the Notion-alternatives space — modern collaborative wiki, AGPL-3.0, deploys cleanly on a €3.79/month Hetzner CX22. This guide goes from empty server to editing your first page in about 30 minutes.
You'll need:
- A domain (e.g.
wiki.yourcompany.com) with DNS pointing to your server. - An SMTP account (Postmark, Resend, SES). Docmost uses it for invitations and password resets.
Step 1 · Provision (5 min)
ssh root@YOUR_SERVER_IP
adduser deploy && usermod -aG sudo deploy
rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart ssh Step 2 · DNS (5 min)
wiki.yourcompany.com → YOUR_SERVER_IP Step 3 · Docker (5 min)
sudo apt-get update && sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update && sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker $USER && newgrp docker Step 4 · Compose stack (10 min)
mkdir -p ~/docmost && cd ~/docmost
mkdir -p caddy_data caddy_config docmost_data postgres_data redis_data ~/docmost/docker-compose.yml:
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: docmost
POSTGRES_USER: docmost
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- ./postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U docmost -d docmost"]
interval: 10s
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
- ./redis_data:/data
docmost:
image: docmost/docmost:latest
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
environment:
APP_URL: https://${DOCMOST_HOST}
APP_SECRET: ${APP_SECRET}
DATABASE_URL: postgresql://docmost:${POSTGRES_PASSWORD}@postgres:5432/docmost
REDIS_URL: redis://redis:6379
MAIL_DRIVER: smtp
SMTP_HOST: smtp.postmarkapp.com
SMTP_PORT: 587
SMTP_USERNAME: ${SMTP_TOKEN}
SMTP_PASSWORD: ${SMTP_TOKEN}
MAIL_FROM_ADDRESS: [email protected]
MAIL_FROM_NAME: Wiki
STORAGE_DRIVER: local
volumes:
- ./docmost_data:/app/data/storage
expose:
- "3000"
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./caddy_data:/data
- ./caddy_config:/config
depends_on:
- docmost
~/docmost/Caddyfile:
${DOCMOST_HOST} {
reverse_proxy docmost:3000
} ~/docmost/.env:
DOCMOST_HOST=wiki.yourcompany.com
POSTGRES_PASSWORD=RANDOM_32_CHARS
APP_SECRET=RANDOM_HEX_32_CHARS
SMTP_TOKEN=YOUR_POSTMARK_SERVER_TOKEN openssl rand -hex 32 for APP_SECRET.
Step 5 · Bring it up (5 min)
docker compose up -d
docker compose logs -f docmost Wait for Nest application successfully started. Ctrl+C.
Open https://wiki.yourcompany.com. Sign up as the first user — that user becomes workspace owner.
Step 6 · Firewall and backups
sudo ufw allow 22/tcp && sudo ufw allow 80/tcp && sudo ufw allow 443/tcp && sudo ufw --force enable Nightly backup — Postgres and uploaded files:
sudo tee /etc/cron.daily/docmost-backup > /dev/null <<'EOF'
#!/bin/bash
set -e
BACKUP_DIR=/home/deploy/backups
mkdir -p "$BACKUP_DIR"
docker exec docmost-postgres-1 pg_dump -U docmost docmost | gzip > "$BACKUP_DIR/docmost-pg-$(date +%Y%m%d).sql.gz"
tar czf "$BACKUP_DIR/docmost-files-$(date +%Y%m%d).tar.gz" -C /home/deploy/docmost docmost_data
find "$BACKUP_DIR" -name "docmost-*" -mtime +14 -delete
EOF
sudo chmod +x /etc/cron.daily/docmost-backup Common pitfalls
- SMTP is required for real use. Skipping the mailer config means invites and password resets don't work. Postmark's free tier is enough for a small team.
- File uploads land in
docmost_data. If you outgrow local storage, switch toSTORAGE_DRIVER: s3with an S3-compatible bucket (Backblaze B2, Cloudflare R2, MinIO). Your backup strategy must cover it either way. - Real-time collaboration uses WebSockets. Caddy handles the upgrade automatically. If you swap in nginx, add explicit
proxy_http_version 1.1and Upgrade/Connection headers. - Search is Postgres full-text by default. Works fine to ~50k pages. Beyond that consider swapping in Meilisearch — Docmost supports it.
Notion import
Export your Notion workspace as Markdown + CSV (Settings → Export → Export all workspace content). Use Docmost's built-in Notion importer (Settings → Import → Notion) and upload the ZIP. Pages import reliably; databases become tables. Rebuild views, permissions, and relations by hand.
Updating
cd ~/docmost
docker compose pull
docker compose up -d
docker image prune -f What you're paying vs Notion
- Docmost on Hetzner CX22: €45/year (~$50) + minimal maintenance.
- Notion Team, 5 users: $600/year.
- Notion Business, 5 users: $1,080/year.
Docmost is the honest choice when your Notion use case is "team wiki with search and permissions." Deploys in an evening, runs quietly, doesn't need weekly attention.
Hosts that work well for Docmost
Some links are affiliate. We only include hosts we deploy production workloads on. Rankings above are independent of these links.