Several documentation gaps found while self-hosting via Docker (first-time install)

Open
#156 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
52/100
Issue type
Documentation
Clarity
Mostly clear
Activity status
Active
Tech stack
docker, nginx

Research direction

Start with the Docker section of the admin guide, the entrypoint script behavior, and the existing Nginx example linked there. Verify the documented CPAD_CONF requirement, registration URL order, ports 3000 and 3003, Docker proxy setup, and security-header interaction. Done means the guide covers these first-install paths and includes an authoritative Docker-oriented Nginx example.

Written by the indexing model from the issue text.

Description

Several documentation gaps found while self-hosting via Docker (first-time install)

I just finished setting up a self-hosted CryptPad instance (Docker, Debian 12, Nginx reverse proxy, Let's Encrypt) for a small collaborative-writing project with the help of Claude (AI). The install ultimately succeeded, but Claude and I hit several points where the documentation didn't match what the Docker image actually does. This cost significant troubleshooting time. Here are Claude's suggestions for improving the admin guide:


1. CPAD_CONF isn't documented as required for Docker installs

The Docker section of the admin guide mentions CPAD_MAIN_DOMAIN and CPAD_SANDBOX_DOMAIN, but doesn't mention CPAD_CONF. Without it set, the entrypoint script's cp "$CPAD_HOME"/config/config.example.js "$CPAD_CONF" runs with an empty destination, and the container crash-loops with:

cp: can't create '': No such file or directory

There's no indication this is caused by a missing environment variable — it reads like a generic filesystem error. Explicitly documenting CPAD_CONF=/cryptpad/config/config.js as required (or defaulting it inside the image if unset) would prevent this entirely.

2. The first-run admin registration token URL isn't reachable in a natural install order

The printed registration URL uses whatever domain is set in CPAD_MAIN_DOMAIN — which, following the guide's order, is your real production domain, set before Nginx/TLS/port-forwarding exist. New self-hosters following the docs top-to-bottom will hit an unreachable URL at exactly this step. Suggest either: (a) an explicit note to access the token URL via the container's local IP/port during initial setup and switch to the real domain afterward, or (b) reordering the guide so reverse-proxy setup precedes first-run registration.

3. The Docker image's internal ports (3000 and 3003) aren't clearly documented

I initially found third-party guides referencing port 3001 for sandbox-domain traffic, which doesn't match the actual image (confirmed via docker compose exec cryptpad ss -tlnp, which shows 3000 and 3003). Turned out both domains are actually served from port 3000 regardless, distinguished by Host header — but this isn't stated anywhere I could find. An authoritative line in the official Docker docs ("the image listens on ports X and Y; here's what each is for") would prevent this rabbit hole.

4. No official Nginx reverse-proxy example for the Docker deployment specifically

Existing example configs (including the one linked from the admin guide) assume a bare-metal install where Nginx serves static files directly via root/try_files. That doesn't apply to the Docker image, which needs proxy_pass instead. A dedicated Docker-oriented reverse-proxy example alongside the existing one would remove a lot of guesswork for anyone containerizing.

5. Interaction between CryptPad's own security headers and a reverse proxy's headers isn't documented, and it's a real trap

CryptPad's Node process sends CORP/COEP/CSP headers on some responses, but apparently not consistently on every static asset — specifically not on inner.html, used by the sandbox iframe. If a reverse proxy doesn't independently guarantee Cross-Origin-Resource-Policy and Cross-Origin-Embedder-Policy on every response, cross-origin sandboxing silently breaks. The failure only surfaces in the browser console on a specific user action (e.g. opening account settings, which loads sandboxed content) rather than as an obvious page-load error, so it's easy to miss and hard to diagnose. A documentation note on this header interaction — and ideally a reference Nginx snippet that guarantees these headers via proxy_hide_header + add_header ... always — would save others the same debugging loop.


Genuinely happy with the result once everything clicked into place! :-)

Dominant language
HTML
Stars
39
Forks
22
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from cryptpad/documentation

All issues in cryptpad/documentation

Similar issues

More DevOps issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.