diff --git a/overleaf/README.md b/overleaf/README.md index 17d3e6b..742083b 100644 --- a/overleaf/README.md +++ b/overleaf/README.md @@ -159,6 +159,15 @@ ln -s overleaf.env .env - **Mongo 8.0 needs AVX.** Mongo 5.0+ won't start on CPUs without it, and the failure is an immediate exit with nothing useful logged. Check first: `grep -o avx2 /proc/cpuinfo | head -1` +- **`start_period` on Mongo's healthcheck is load-bearing.** Without it, slow + checks during startup count against `retries` straight away — five of them + (~50s) mark Mongo unhealthy, and the app's `condition: service_healthy` + refuses to start it. Mongo then recovers on its next check, so by morning + everything looks fine except the app, which is simply down. This bites on + backup scripts that stop and start containers: Mongo comes back while the + disks are still busy, `mongosh` is a Node process and answers slowly, and the + stack loses a race nobody knew it was running. Upstream's sample has no + `start_period` either. - **A healthy Mongo does not mean the replica set is up.** The healthcheck runs `db.stats().ok`, which passes without one — so `depends_on: service_healthy` is satisfied and the app starts anyway, then fails its own DB check. @@ -189,27 +198,41 @@ TeX Live lives at `/usr/local/texlive/2026/`, **inside the image**. A `docker compose pull` does not. A document that compiled last month stops compiling and nothing tells you why. -The fix is `TEXMFHOME`, which this stack bind-mounts to `${DATA_PATH}/texmf`. -Install in user mode and packages land on the volume instead: +The fix is user-mode installs plus a `TEXMFHOME` that both users agree on. +That second half matters more than it looks: **tlmgr runs as root, but the +compiles run as `www-data`**, and by default those two resolve `TEXMFHOME` +differently: + +``` +root /root/texmf <- where a plain `tlmgr --usermode install` lands +www-data /var/www/texmf <- where LaTeX actually looks +``` + +So the install succeeds, reports no error, and the package still isn't found — +and `/root` isn't even readable by `www-data`, so no amount of mounting that +path helps. This stack therefore sets: + +```yaml +TEXMFHOME: /var/lib/overleaf/texmf +``` + +which is inside the persisted volume, so both users agree and the packages +survive image updates. Then: ```bash -# once, to create the tree -docker exec overleaf tlmgr init-usertree - -# thereafter, for each package +docker exec overleaf tlmgr --usermode init-usertree # once docker exec overleaf tlmgr --usermode install booktabs ``` -Verify it took: +Verify as the user that actually compiles, not as root: ```bash -docker exec overleaf kpsewhich booktabs.sty -# /root/texmf/tex/latex/booktabs/booktabs.sty <- persisted -# /usr/local/texlive/... <- inside the image, will be lost +docker exec -u www-data overleaf kpsewhich booktabs.sty +# /var/lib/overleaf/texmf/... correct, persisted +# /usr/local/texlive/... inside the image, lost on update +# nothing installed somewhere the compiler can't see ``` -The path in the output tells you which mode you used. - **Caveats.** User mode handles ordinary style packages cleanly. Packages that install fonts or need map-file updates may also want `updmap-user`, and a few that expect to modify the main tree won't work this way — install those with a diff --git a/overleaf/compose.yaml b/overleaf/compose.yaml index 3810bcb..821afcb 100644 --- a/overleaf/compose.yaml +++ b/overleaf/compose.yaml @@ -18,10 +18,6 @@ services: volumes: - ${DATA_PATH:-./data}/overleaf:/var/lib/overleaf - # TEXMFHOME. Packages installed with `tlmgr --usermode install` land here - # instead of inside the image, so they survive an image update. See the - # README -- without this, every upgrade silently drops them. - - ${DATA_PATH:-./data}/texmf:/root/texmf environment: OVERLEAF_APP_NAME: ${OVERLEAF_APP_NAME:-Overleaf} @@ -40,6 +36,13 @@ services: # which is wrong the moment you use a port or a domain. OVERLEAF_SITE_URL: ${OVERLEAF_SITE_URL:-http://localhost:8020} + # Where `tlmgr --usermode install` puts packages. Overridden to a path on + # the persisted volume so they survive an image update -- and so that root + # (which runs tlmgr) and www-data (which runs the compiles) agree on one + # location. Left at the default they disagree, and packages install to a + # directory the compiler never searches. See the README. + TEXMFHOME: /var/lib/overleaf/texmf + ENABLED_LINKED_FILE_TYPES: "project_file,project_output_file" ENABLE_CONVERSIONS: "true" EMAIL_CONFIRMATION_DISABLED: "true" @@ -71,8 +74,16 @@ services: healthcheck: test: echo 'db.stats().ok' | mongosh localhost:27017/test --quiet interval: 10s - timeout: 10s + timeout: 20s retries: 5 + # Without this, failures during startup count against `retries` + # immediately: five slow checks (~50s) mark Mongo unhealthy, and the app's + # `condition: service_healthy` then refuses to start. Mongo recovers a + # moment later, so by morning nothing looks wrong. `mongosh` is a Node + # process and is slow to answer on a loaded box -- e.g. right after a + # backup job. During start_period a failure is not counted, and a success + # promotes to healthy straight away. + start_period: 120s redis: image: redis:6.2