
This article provides a guide demonstrating how to deploy Docmost on Ubuntu VPS.
What is Docmost?
Docmost is an open-source, self-hosted collaborative wiki and documentation platform. In practical terms, it is software you can run on your own VPS or server to create an internal knowledge base, company wiki, SOP library, project documentation site, or team documentation portal.
It is commonly positioned as an alternative to tools like Confluence and Notion, especially for teams that want more control over their data and infrastructure.
Docmost is useful for:
- Internal company documentation
- Technical documentation
- Standard operating procedures
- Team knowledge bases
- Project notes
- Client or staff onboarding guides
- Private wikis
Key features include real-time collaborative editing, spaces for organizing content by team or department, permission controls, file attachments, search, and a modern web-based editor. Its documentation also notes that it is fully self-hosted and can run in air-gapped environments without external dependencies.
From a hosting perspective, Docmost is typically deployed with Docker, PostgreSQL, and Redis, then placed behind a reverse proxy such as Nginx with HTTPS. This makes it a good fit for an Ubuntu VPS deployment where the organization wants full ownership of the application, database, files, and access controls.
In plain English: Docmost is a self-hosted team documentation system for writing, organizing, and sharing knowledge privately, without relying on a proprietary SaaS platform.
Docmost is a self-hosted collaborative wiki and documentation platform. The official Docmost documentation recommends Docker for self-hosting and requires Docmost, PostgreSQL, Redis, persistent storage, APP_URL, APP_SECRET, DATABASE_URL, and REDIS_URL to be configured correctly. Docmost also provides a health check endpoint at /api/health.
This guide deploys Docmost on an Ubuntu VPS using:
- Ubuntu 22.04 or Ubuntu 24.04
- Docker and Docker Compose
- PostgreSQL container
- Redis container
- Nginx reverse proxy
- Letβs Encrypt SSL certificates
- Automated certificate renewal with Certbot
Compare Ubuntu VPS Plans
How to Deploy Docmost on Ubuntu VPS with Nginx Reverse Proxy and Automated SSL Renewal
To deploy Docmost on Ubuntu VPS, follow the steps outlined below:
-
Example Deployment Details
Replace these values with your own.
Domain: docmost.example.com Server IP: 192.0.2.10 Application directory: /opt/docmost Docmost internal port: 3000 Public access: https://docmost.example.com
-
Prerequisites
You need:
-
- A fresh Ubuntu VPS
- Root or sudo SSH access
- A domain or subdomain pointed to the VPS IP
- Ports 80 and 443 open
- At least 2 GB RAM recommended
Before continuing, create an
Arecord for your Docmost hostname.Example DNS record:
Type: A Name: docmost Value: 192.0.2.10 TTL: Automatic
Verify DNS resolution:
dig +short docmost.example.com
The result should return your VPS IP address.
-
-
Update the Ubuntu VPS
ssh root@192.0.2.10
Update system packages:
apt update apt upgrade -y
Install common utilities:
apt install -y ca-certificates curl gnupg lsb-release apt-transport-https software-properties-common ufw unzip nano
-
Configure the Firewall
Allow SSH, HTTP, and HTTPS:
ufw allow OpenSSH ufw allow 80/tcp ufw allow 443/tcp ufw enable
Check status:
ufw status
You should see rules for:
22/tcp 80/tcp 443/tcp
-
Install Docker Engine
Install Docker using Dockerβs official repository method.
Create the Docker keyring directory:
install -m 0755 -d /etc/apt/keyrings
Add Dockerβs GPG key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
Set permissions:
chmod a+r /etc/apt/keyrings/docker.gpg
Add the Docker repository:
echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \ > /etc/apt/sources.list.d/docker.list
Update package indexes:
apt update
Install Docker and Docker Compose plugin:
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Enable Docker:
systemctl enable --now docker
Verify Docker:
docker --version docker compose version
-
Create the Docmost Deployment Directory
Create a dedicated directory:
mkdir -p /opt/docmost cd /opt/docmost
-
Generate Secure Secrets
Generate a strong Docmost app secret:
openssl rand -hex 32
Generate a strong PostgreSQL password:
openssl rand -base64 32
Save both values temporarily. You will use them in the Compose file.
Docmost requires
APP_SECRETto be replaced with a long random secret of at least 32 characters; leaving the default value will cause the app to fail to start. -
Create the Docker Compose File
Create the Compose file:
nano /opt/docmost/docker-compose.yml
Paste the following configuration.
Replace:
docmost.example.com CHANGE_ME_APP_SECRET CHANGE_ME_DB_PASSWORD
with your actual values.
services: docmost: image: docmost/docmost:latest container_name: docmost depends_on: - db - redis environment: APP_URL: "https://docmost.example.com" APP_SECRET: "CHANGE_ME_APP_SECRET" DATABASE_URL: "postgresql://docmost:CHANGE_ME_DB_PASSWORD@db:5432/docmost" REDIS_URL: "redis://redis:6379" ports: - "127.0.0.1:3000:3000" restart: unless-stopped volumes: - docmost_storage:/app/data/storage db: image: postgres:18 container_name: docmost-db environment: POSTGRES_DB: docmost POSTGRES_USER: docmost POSTGRES_PASSWORD: "CHANGE_ME_DB_PASSWORD" restart: unless-stopped volumes: - docmost_db_data:/var/lib/postgresql redis: image: redis:8 container_name: docmost-redis command: ["redis-server", "--appendonly", "yes", "--maxmemory-policy", "noeviction"] restart: unless-stopped volumes: - docmost_redis_data:/data volumes: docmost_storage: docmost_db_data: docmost_redis_data:The current upstream Docmost Compose example uses the
docmost/docmost:latestimage, PostgreSQL, Redis, app storage, database storage, Redis storage, and port3000.Important Security Detail
The line below binds Docmost only to localhost:
ports: - "127.0.0.1:3000:3000"
This prevents direct public access to port
3000. Public traffic will go through Nginx over HTTPS. -
Start Docmost
From
/opt/docmost, start the containers:cd /opt/docmost docker compose up -d
Check container status:
docker compose ps
You should see containers for:
docmost docmost-db docmost-redis
Check logs:
docker compose logs -f docmost
Test locally:
curl -I http://127.0.0.1:3000
You should receive an HTTP response from Docmost.
-
Install Nginx
Install Nginx:
apt install -y nginx
Enable and start Nginx:
systemctl enable --now nginx
Check status:
systemctl status nginx
-
Create the Nginx Reverse Proxy Configuration
Create a new Nginx site file:
nano /etc/nginx/sites-available/docmost
Paste the following configuration:
server { listen 80; listen [::]:80; server_name docmost.example.com; client_max_body_size 100M; location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; 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_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 300; proxy_connect_timeout 300; proxy_send_timeout 300; } }Enable the site:
ln -s /etc/nginx/sites-available/docmost /etc/nginx/sites-enabled/docmost
Remove the default Nginx site if it is not needed:
rm -f /etc/nginx/sites-enabled/default
Test Nginx configuration:
nginx -t
Reload Nginx:
systemctl reload nginx
Visit:
http://docmost.example.com
Docmost: create workspace At this stage, the site should load over plain HTTP.
-
Install Certbot for Letβs Encrypt SSL
Install Certbot and the Nginx plugin:
apt install -y certbot python3-certbot-nginx
Request an SSL certificate:
certbot --nginx -d docmost.example.com
When prompted:
Enter your email address Agree to the Terms of Service Choose whether to share your email Select redirect HTTP to HTTPS when asked
Certbot will modify your Nginx configuration automatically.
After completion, visit:
https://docmost.example.com
-
Verify Automated SSL Renewal
Certbot typically installs a systemd timer for automatic renewal on Ubuntu.
Check the timer:
systemctl list-timers | grep certbot
Test renewal:
certbot renew --dry-run
If the dry run succeeds, automated SSL renewal is working.
You can also check Certbot renewal files:
ls -lah /etc/letsencrypt/renewal/
-
Confirm the Final Nginx Configuration
After Certbot runs, your Nginx file should look similar to this:
nano /etc/nginx/sites-available/docmost
Example HTTPS-ready configuration:
server { server_name docmost.example.com; client_max_body_size 100M; location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; 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_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 300; proxy_connect_timeout 300; proxy_send_timeout 300; } listen [::]:443 ssl ipv6only=on; listen 443 ssl; ssl_certificate /etc/letsencrypt/live/docmost.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/docmost.example.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; } server { if ($host = docmost.example.com) { return 301 https://$host$request_uri; } listen 80; listen [::]:80; server_name docmost.example.com; return 404; }Test and reload Nginx:
nginx -t systemctl reload nginx
-
Access Docmost and Complete Initial Setup
Open your browser:
https://docmost.example.com
Complete the initial Docmost setup by creating the first administrator account.
Docmost: home After setup, sign in and confirm that you can:
Create a workspace Create a page Edit documentation Upload an attachment Invite users, if needed
-
Check Docmost Health
Docmost provides a health check endpoint at:
https://docmost.example.com/api/health
The official documentation identifies
/api/healthas the dedicated health check endpoint.You can test it with:
curl -i https://docmost.example.com/api/health
-
Useful Docker Management Commands
View running containers:
cd /opt/docmost docker compose ps
View logs:
docker compose logs -f
View only Docmost logs:
docker compose logs -f docmost
Restart Docmost:
docker compose restart docmost
Restart the full stack:
docker compose restart
Stop the stack:
docker compose down
Start the stack:
docker compose up -d
-
Updating Docmost
To update Docmost to the latest image:
cd /opt/docmost docker compose pull docker compose up -d
Remove unused old images:
docker image prune -f
Check logs after updating:
docker compose logs -f docmost
-
Backup Strategy
Docmost data is stored in Docker volumes:
docmost_storage docmost_db_data docmost_redis_data
The most important backup targets are:
PostgreSQL database Docmost uploaded files/storage Docker Compose configuration
-
Create a Backup Directory
mkdir -p /opt/backups/docmost
-
Backup PostgreSQL Database
Run:
cd /opt/docmost docker compose exec -T db pg_dump -U docmost docmost > /opt/backups/docmost/docmost-db-$(date +%F).sql
-
Backup Docmost Storage Volume
Create a compressed archive of the Docmost storage volume:
docker run --rm \ -v docmost_docmost_storage:/data \ -v /opt/backups/docmost:/backup \ alpine \ tar czf /backup/docmost-storage-$(date +%F).tar.gz -C /data .
-
Backup Compose File
cp /opt/docmost/docker-compose.yml /opt/backups/docmost/docker-compose-$(date +%F).yml
-
Automated Daily Backups
Create a backup script:
nano /usr/local/bin/backup-docmost.sh
Paste:
#!/bin/bash set -e BACKUP_DIR="/opt/backups/docmost" DATE="$(date +%F-%H%M)" APP_DIR="/opt/docmost" mkdir -p "$BACKUP_DIR" cd "$APP_DIR" docker compose exec -T db pg_dump -U docmost docmost > "$BACKUP_DIR/docmost-db-$DATE.sql" docker run --rm \ -v docmost_docmost_storage:/data \ -v "$BACKUP_DIR":/backup \ alpine \ tar czf "/backup/docmost-storage-$DATE.tar.gz" -C /data . cp "$APP_DIR/docker-compose.yml" "$BACKUP_DIR/docker-compose-$DATE.yml" find "$BACKUP_DIR" -type f -mtime +14 -delete
Make it executable:
chmod +x /usr/local/bin/backup-docmost.sh
Test it:
/usr/local/bin/backup-docmost.sh
Create a cron job:
crontab -e
Add:
30 2 * * * /usr/local/bin/backup-docmost.sh >/var/log/docmost-backup.log 2>&1
This runs the backup daily at 2:30 AM and deletes backups older than 14 days.
-
Restore from Backup
-
Stop Docmost
cd /opt/docmost docker compose down
-
Start Only the Database
docker compose up -d db
Wait a few seconds:
docker compose ps
-
Restore PostgreSQL
Replace the filename with your backup:
cat /opt/backups/docmost/docmost-db-YYYY-MM-DD-HHMM.sql | docker compose exec -T db psql -U docmost docmost
-
Restore Storage
Replace the archive name:
docker run --rm \ -v docmost_docmost_storage:/data \ -v /opt/backups/docmost:/backup \ alpine \ sh -c "rm -rf /data/* && tar xzf /backup/docmost-storage-YYYY-MM-DD-HHMM.tar.gz -C /data"
-
Start the Stack
docker compose up -d
Check logs:
docker compose logs -f
-
-
Optional: Add SMTP Email Configuration
For invitations, password resets, and notifications, configure SMTP.
Docmost has separate self-hosting documentation for email configuration and environment variables.
Edit:
nano /opt/docmost/docker-compose.yml
Inside the
docmost.environmentsection, add SMTP variables according to your mail providerβs requirements.Example structure:
MAIL_DRIVER: "smtp" SMTP_HOST: "mail.example.com" SMTP_PORT: "587" SMTP_USERNAME: "smtp-user@example.com" SMTP_PASSWORD: "SMTP_PASSWORD_HERE" MAIL_FROM_ADDRESS: "docmost@example.com" MAIL_FROM_NAME: "Docmost"Then restart Docmost:
cd /opt/docmost docker compose up -d
Check logs:
docker compose logs -f docmost
-
Optional: Harden Nginx with Security Headers
Edit the Nginx site:
nano /etc/nginx/sites-available/docmost
Inside the HTTPS
serverblock, add:add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header X-XSS-Protection "1; mode=block" always;
Then test and reload:
nginx -t systemctl reload nginx
Avoid adding an overly strict Content Security Policy until you have tested Docmost thoroughly, because aggressive CSP rules can break modern web apps.
-
Optional: Increase Upload Limit
The earlier Nginx config included:
client_max_body_size 100M;
To allow larger uploads, increase it:
client_max_body_size 250M;
Then reload:
nginx -t systemctl reload nginx
Troubleshooting
-
Problem: Docmost Does Not Start
Check logs:
cd /opt/docmost docker compose logs -f docmost
Common causes:
APP_SECRET was not changed DATABASE_URL password does not match POSTGRES_PASSWORD Redis container is not running PostgreSQL container is not running APP_URL is incorrect
Check containers:
docker compose ps
-
Problem: 502 Bad Gateway
A 502 from Nginx usually means Nginx cannot reach Docmost.
Check Docmost:
docker compose ps docker compose logs -f docmost
Check local port:
curl -I http://127.0.0.1:3000
If that fails, Docmost is not running correctly.
Restart:
cd /opt/docmost docker compose restart
-
Problem: SSL Certificate Fails
Check DNS:
dig +short docmost.example.com
Check that ports 80 and 443 are open:
ufw status
Check Nginx:
nginx -t systemctl status nginx
Retry Certbot:
certbot --nginx -d docmost.example.com
-
Problem: Browser Redirects Incorrectly
Make sure
APP_URLis set to the public HTTPS URL:APP_URL: "https://docmost.example.com"
Then restart:
cd /opt/docmost docker compose up -d
-
Problem: Uploads Fail
Check Nginx upload size:
client_max_body_size 100M;
Check Docmost logs:
docker compose logs -f docmost
Check available disk space:
df -h
Maintenance Checklist
Run these periodically:
apt update && apt upgrade -y
cd /opt/docmost docker compose pull docker compose up -d docker image prune -f
certbot renew --dry-run
/usr/local/bin/backup-docmost.sh
docker compose logs --tail=100
Final Verification Checklist
Before considering the deployment complete, verify:
DNS points to the VPS Nginx is active Docmost containers are running Docmost is bound only to 127.0.0.1:3000 HTTPS works HTTP redirects to HTTPS Certbot dry-run renewal succeeds /api/health responds Admin account is created Backups run successfully Restore process is documented
Useful commands:
docker compose ps
curl -I https://docmost.example.com
curl -i https://docmost.example.com/api/health
certbot renew --dry-run
At this point, Docmost should be running securely on your Ubuntu VPS behind Nginx with automated Letβs Encrypt SSL renewal.
Conclusion
You now know how to deploy Docmost on Ubuntu VPS.











