Skip to content

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

Description

@notator

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! :-)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions