SmartDocs
Current page as Markdown (.md) Includes verification proof.
Partially verified · 16 of 42 code blocks verified
Verified as of 15 Oct 2026 Jump to verified block →
Proof coverage 16/42 blocks Code block 1 — verified · 15 Oct 2026 Code block 2 — verified · 15 Oct 2026 Code block 3 — verified · 15 Oct 2026 Code block 4 — verified · 15 Oct 2026 Code block 5 — verified · 15 Oct 2026 Code block 6 — verified · 15 Oct 2026 Code block 7 — verified · 15 Oct 2026 Code block 8 — verified · 15 Oct 2026 Code block 10 — verified · 15 Oct 2026 Code block 11 — verified · 15 Oct 2026 Code block 13 — verified · 15 Oct 2026 Code block 14 — verified · 15 Oct 2026 Code block 30 — verified · 15 Oct 2026 Code block 31 — verified · 15 Oct 2026 Code block 32 — verified · 15 Oct 2026 Code block 34 — verified · 15 Oct 2026
26 blocks not verified Code block 9 — unverified Code block 12 — unverified Code block 15 — unverified Code block 16 — unverified Code block 17 — unverified Code block 18 — unverified Code block 19 — unverified Code block 20 — unverified Code block 21 — unverified Code block 22 — unverified Code block 23 — unverified Code block 24 — unverified Code block 25 — unverified Code block 26 — unverified Code block 27 — unverified Code block 28 — unverified Code block 29 — unverified Code block 33 — unverified Code block 35 — unverified Code block 36 — unverified Code block 37 — unverified Code block 38 — unverified Code block 39 — unverified Code block 40 — unverified Code block 41 — unverified Code block 42 — unverified
On this page

Install Docmost on a Debian VM with Docker Compose

This guide installs Docmost on a Debian 12 VM using Docker Compose. It covers Docker installation, a production-ready Compose setup, optional Nginx and HTTPS, backups, and upgrades.

Prerequisites

  • Debian 12 (Bookworm) or Debian 11 VM
  • A user with sudo access
  • 2 vCPU, 2 GB RAM, and at least 20 GB disk space recommended
  • Optional: a domain name pointing to the VM, for example docs.example.com
  • Open firewall ports: 22 for SSH, and either 3000 for direct access or 80/443 when using a reverse proxy

1. Update Debian and install prerequisites

bash
sudo apt update
sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 fc03f7dee52f · matches the published text
This proof supports the code shown above.

2. Install Docker Engine and Docker Compose

Add Docker’s official GPG key:

bash
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 62f3fb568c94 · matches the published text
This proof supports the code shown above.

Add the Docker apt repository:

bash
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 feeba042b261 · matches the published text
This proof supports the code shown above.

Install Docker Engine and the Compose plugin:

bash
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 b6b4d49eef0b · matches the published text
This proof supports the code shown above.

Verify the installation:

bash
sudo docker run hello-world
docker compose version
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 3bc3ca7bfe0f · matches the published text
This proof supports the code shown above.

Optional: run Docker as your non-root user.

bash
sudo usermod -aG docker $USER
newgrp docker
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 c49a9ef1b232 · matches the published text
This proof supports the code shown above.

Log out and back in if newgrp does not take effect in your current session.

3. Create the Docmost directory and .env

bash
sudo mkdir -p /opt/docmost
sudo chown -R $USER:$USER /opt/docmost
cd /opt/docmost
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 877285939059 · matches the published text
This proof supports the code shown above.

Generate secrets:

bash
openssl rand -hex 32
openssl rand -hex 24
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 849837850b9f · matches the published text
This proof supports the code shown above.

Use the first value for APP_SECRET and the second for POSTGRES_PASSWORD.

Create the .env file:

bash
nano .env

Example content:

dotenv.env
APP_URL=http://203.0.113.10:3000
APP_SECRET=replace_with_openssl_rand_hex_32
POSTGRES_DB=docmost
POSTGRES_USER=docmost
POSTGRES_PASSWORD=replace_with_openssl_rand_hex_24
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 48852499afc1 · matches the published text
This proof supports the code shown above.

Replace 203.0.113.10 with your VM’s public IP or domain name. Keep APP_SECRET stable and private.

Secure the file:

bash
chmod 600 .env
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 ff0f99fcaefa · matches the published text
This proof supports the code shown above.

4. Create the Docker Compose file

Create compose.yaml:

bash
nano compose.yaml

Paste the following:

yamlcompose.yaml
services:
  docmost:
    image: docmost/docmost:latest
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    environment:
      APP_URL: ${APP_URL}
      APP_SECRET: ${APP_SECRET}
      DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public
      REDIS_URL: redis://redis:6379
    ports:
      - "3000:3000"
    restart: unless-stopped
    volumes:
      - docmost_data:/app/data/storage

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    restart: unless-stopped
    volumes:
      - db_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  docmost_data:
  db_data:
  redis_data:
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 2d6b997c4738 · matches the published text
This proof supports the code shown above.

If your database password contains characters such as @, :, /, or #, use a hex password as shown above or URL-encode the password in DATABASE_URL.

5. Start Docmost

bash
docker compose up -d
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 331e4dcccd52 · matches the published text
This proof supports the code shown above.

Check containers and logs:

bash
docker compose ps
docker compose logs -f docmost

Open http://YOUR_VM_IP:3000 and complete the initial setup to create the first admin account.

If you use UFW and access Docmost directly:

bash
sudo ufw allow OpenSSH
sudo ufw allow 3000/tcp
sudo ufw enable

6. Optional: Nginx reverse proxy and HTTPS

Install Nginx and Certbot:

bash
sudo apt install -y nginx certbot python3-certbot-nginx

Create the Nginx site configuration:

bash
sudo nano /etc/nginx/sites-available/docmost

Paste the following, replacing docs.example.com with your domain:

nginx
server {
    listen 80;
    server_name docs.example.com;

    client_max_body_size 100M;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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_read_timeout 300s;
        proxy_send_timeout 300s;
    }
}

Enable the site and reload Nginx:

bash
sudo ln -s /etc/nginx/sites-available/docmost /etc/nginx/sites-enabled/docmost
sudo nginx -t
sudo systemctl reload nginx

Obtain an HTTPS certificate:

bash
sudo certbot --nginx -d docs.example.com

Update .env:

dotenv
APP_URL=https://docs.example.com

Restart Docmost:

bash
docker compose up -d

For better security, make Docmost listen only on localhost when using a reverse proxy. Change the port mapping in compose.yaml from:

yaml
    ports:
      - "3000:3000"

to:

yaml
    ports:
      - "127.0.0.1:3000:3000"

Then restart:

bash
docker compose up -d

7. Optional: email and SMTP

Docmost uses SMTP for invitations, password resets, and notifications. Add these values to .env:

dotenv
MAIL_DRIVER=smtp
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USERNAME=user@example.com
SMTP_PASSWORD=your-smtp-password
SMTP_SECURE=false
MAIL_FROM_ADDRESS=docmost@example.com
MAIL_FROM_NAME=Docmost

Add the matching variables to the docmost.environment section in compose.yaml:

yaml
      MAIL_DRIVER: ${MAIL_DRIVER}
      SMTP_HOST: ${SMTP_HOST}
      SMTP_PORT: ${SMTP_PORT}
      SMTP_USERNAME: ${SMTP_USERNAME}
      SMTP_PASSWORD: ${SMTP_PASSWORD}
      SMTP_SECURE: ${SMTP_SECURE}
      MAIL_FROM_ADDRESS: ${MAIL_FROM_ADDRESS}
      MAIL_FROM_NAME: ${MAIL_FROM_NAME}

Restart Docmost:

bash
docker compose up -d

Use SMTP_SECURE=true for port 465. Use SMTP_SECURE=false for port 587.

8. Backups

Create a backup directory:

bash
mkdir -p /opt/docmost/backups
cd /opt/docmost
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 2a3aad30aa5a · matches the published text
This proof supports the code shown above.

Back up the database:

bash
docker compose exec -T db pg_dump -U docmost docmost > "backups/docmost-db-$(date +%F).sql"
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 b0da705ac581 · matches the published text
This proof supports the code shown above.

Find the Docmost storage volume name:

bash
docker volume ls | grep docmost
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 f157e66ff8f4 · matches the published text
This proof supports the code shown above.

Example output:

text
local     docmost_docmost_data

Back up the storage volume using the name from the previous command:

bash
docker run --rm \
  -v docmost_docmost_data:/data \
  -v "$PWD/backups:/backup" \
  alpine tar czf "/backup/docmost-storage-$(date +%F).tar.gz" -C /data .
Proven
Proof of run
status
✓ Verified
env
signal
http GET http://localhost:3000 expect 200
checked
15 Oct 2026
sha256 10a0cc2bc358 · matches the published text
This proof supports the code shown above.

Restore the database:

bash
cat backups/docmost-db-2025-01-01.sql | docker compose exec -T db psql -U docmost docmost

Stop Docmost before restoring the storage volume.

9. Upgrade Docmost

Back up first, then run:

bash
cd /opt/docmost
docker compose pull
docker compose up -d
docker compose logs -f docmost

10. Troubleshooting

  • Check logs:

    bash
    docker compose logs -f docmost
    docker compose logs -f db
    docker compose logs -f redis
    
  • docker compose command not found: install the docker-compose-plugin package.

  • Permission denied when running Docker: add your user to the docker group and log out and back in.

    bash
    sudo usermod -aG docker $USER
    
  • Port 3000 is already in use: change the port mapping to 127.0.0.1:3000:3000 or another available port.

  • Database connection errors: verify POSTGRES_DB, POSTGRES_USER, and POSTGRES_PASSWORD in .env. The database hostname in DATABASE_URL must be db, not localhost.

  • Incorrect links, redirects, or login issues: confirm APP_URL matches the public URL exactly, including https:// and without a trailing slash, then restart Docmost.

  • WebSocket or real-time collaboration issues behind Nginx: ensure the Upgrade and Connection headers are present in the Nginx configuration.

  • Email not sending: verify SMTP settings and restart Docmost.

  • Reset all data, including the database and storage volumes:

    bash
    docker compose down -v
    

    This is destructive and cannot be undone.

11. Uninstall

Stop and remove the containers:

bash
cd /opt/docmost
docker compose down

Remove the database and storage volumes:

bash
docker compose down -v

Remove the directory:

bash
sudo rm -rf /opt/docmost

Security notes

  • Keep .env private and use chmod 600 .env.
  • Do not expose PostgreSQL or Redis ports. The Compose file keeps them internal to the Docker network.
  • Use HTTPS in production.
  • Keep APP_SECRET stable and secret. Changing it can invalidate sessions.
  • Run regular database and storage backups.