Skip to content

Self-hosting instructions need improvement #17

@AMDphreak

Description

@AMDphreak

I set Docmost up on a VPS. I ran into many issues, and had to rely on AI to correct your installation instructions. You are missing details in the instructions and explanations.

https://docmost.com/docs/installation/

Currently working: https://docmost.ryanjohnson.dev

A placeholder for the Postgres DB password exists in the docker-compose.yml in two separate lines. You should be using a variable in a .env file and referring to the variable in the two places it is used in docker-compose.yml, so users don't have to copy/paste the same thing twice or make guesses about what your instructions mean.

The ports section configuration is not explained in the docs and is not self-explanatory (8000:8000--what does it do?).

Image


I had AI generate a bug report based on the troubleshooting session I had with it. It is reproduced below:

From a Google Doc

Bug Report: Docmost Docker Compose & Environment Variable Configuration Clarity

Product: Docmost (Self-Hosted via Docker Compose)

Version: 0.21.0 (as observed in provided logs)

Report Date: June 26, 2025

Overview

During the setup of Docmost using Docker Compose, several configuration points related to environment variables and external proxying (Cloudflare Tunnel) presented significant clarity issues and led to unexpected application startup failures. While some information exists, its prominence or precise integration with typical Docker Compose workflows could be improved to prevent common troubleshooting headaches.

Detailed Issues & Recommendations

1. APP_SECRET Length Validation Clarity

Issue: The APP_SECRET environment variable has a strict minimum length requirement of 32 characters, which is explicitly stated in the installation documentation (https://docmost.com/docs/installation). However, despite being documented, this remains a frequent point of failure (as observed in troubleshooting sessions), often due to users missing this specific detail or the provided docker-compose.yml.example using a placeholder that is shorter than the minimum.

Example Log Error:

{"minLength":"APP_SECRET must be longer than or equal to 32 characters"}

Recommendation:

  • docker-compose.yml.example Improvement: Consider using a generated, valid-length placeholder in the docker-compose.yml.example (e.g., APP_SECRET: 'REPLACE_ME_WITH_A_LONG_RANDOM_SECRET_KEY_MIN_32_CHARS') or add a direct comment next to the APP_SECRET line within the example file itself reinforcing the 32-character minimum and perhaps the openssl command.

  • Documentation Prominence: While documented, its critical nature could be highlighted with a "Warning" or "Important" note near the APP_SECRET variable in the "Environment Variables" section.

2. DATABASE_URL Password Encoding for Special Characters

Issue: When the DB_PASSWORD (used for POSTGRES_PASSWORD and embedded in DATABASE_URL) contains special characters (e.g., !, #, ^, @), the DATABASE_URL validation fails. This is because characters in a URL's password component must be URL-encoded, a detail not specified in the documentation. Even if the POSTGRES_PASSWORD variable is loaded from .env, the direct substitution into DATABASE_URL without prior encoding causes the validation failure.

Example Log Error:

{"isUrl":"DATABASE_URL must be a valid postgres connection string"}

Followed by password authentication failed after fixing the isUrl issue, if POSTGRES_PASSWORD in db service definition wasn't also adjusted to use the encoded password (which Postgres often internally decodes).

Recommendation:

  • Documentation: Explicitly state that if DB_PASSWORD contains special characters, it must be URL-encoded when used within the DATABASE_URL string. Provide a clear example of URL encoding for common special characters (e.g., ! -> %21, # -> %23).

  • Best Practice Guidance: Recommend using URL-safe characters (alphanumeric, hyphens, underscores) for DB_PASSWORD to avoid encoding complexities altogether, especially in initial setup guides. Advise users to manage sensitive credentials via Docker Secrets for production environments.

3. Database Password Synchronization for Existing Volumes

Issue: If the db_data PostgreSQL volume exists from a previous docker-compose up command (e.g., with a different POSTGRES_PASSWORD or if the DB_PASSWORD was changed in .env after initial setup), changing the password in docker-compose.yml (or .env) for the db service will not automatically update the password within the existing PostgreSQL database. This leads to password authentication failed errors for the docmost user trying to connect.

Example Log Error:

error: password authentication failed for user "docmost"

code: '28P01'

Recommendation:

  • Installation Guide: In the "First-Time Deployment" section, explicitly warn users about this common issue.

  • Guidance for Fresh Installs: Clearly state that for a fresh install or to reset data, docker compose down -v (to remove named volumes) is necessary when changing database passwords to ensure a clean initialization.

  • Guidance for Existing Data: Provide explicit instructions on how to change the PostgreSQL user's password directly within the running postgres container using psql (e.g., docker compose exec db psql -U docmost docmost, then ALTER USER docmost WITH PASSWORD 'new_password';).

4. SMTP_SECURE Variable Clarity

Issue: The SMTP_SECURE variable in the .env configuration, while documented, can be counter-intuitive. SMTP_SECURE=false is used for SMTP_PORT=587 (STARTTLS), which is often the recommended secure method, whereas SMTP_SECURE=true is for SMTP_PORT=465 (implicit SSL/TLS). This boolean naming (false for "secure" STARTTLS) can lead to confusion.

Recommendation:

  • Documentation: Enhance the explanation of SMTP_SECURE to clearly define "implicit TLS/SSL" vs. "STARTTLS" and explicitly state which ports (465 vs. 587) are associated with each setting. Reiterate that both methods provide secure encryption, but 587 with SMTP_SECURE=false (for STARTTLS) is a common and recommended modern approach.

5. Cloudflare Tunnel Origin URL for Native cloudflared

Issue: For users running the cloudflared agent natively on the host system (not in a Docker container alongside Docmost), the Public Hostname URL in the Cloudflare Zero Trust dashboard configured as http://<docker_service_name>: will fail resolution. The native cloudflared agent cannot resolve Docker service names directly; it needs to access the service via localhost (or the host's private IP) and the exposed host port. This also includes potential issues if cloudflared attempts to connect via IPv6 loopback ([::1]) when the Docker service is primarily binding to IPv4 (127.0.0.1).

Example cloudflared Log Errors:

  • dial tcp: lookup docmost on 1.1.1.1:53: no such host (when using http://docmost:3000)

  • dial tcp [::1]:: connect: connection refused (when using http://localhost: but IPv6 loopback isn't fully functional or bound for the Docker service).

Recommendation:

  • Documentation: Add a dedicated section or prominent warning for Cloudflare Tunnel users.

  • Clear Guidance: Differentiate the Public Hostname URL configuration based on cloudflared deployment:

  • If cloudflared is a Docker service (sharing Docker network with app): Use http://<docker_service_name>:<internal_container_port> (e.g., http://docmost:3000).

  • If cloudflared is native on host: Use http://127.0.0.1:<host_published_port> (e.g., http://127.0.0.1:3000). Emphasize 127.0.0.1 for explicit IPv4 loopback to avoid potential IPv6 issues.

  • Troubleshooting: Include these specific cloudflared log errors and their corresponding fixes in the troubleshooting section.

By addressing these configuration gaps and providing clearer, more explicit guidance in the official documentation and example files, the setup experience for Docmost will be significantly improved for self-hosting users.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions