overleaf: fix TEXMFHOME and mongo start_period
This commit is contained in:
+35
-12
@@ -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
|
- **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:
|
failure is an immediate exit with nothing useful logged. Check first:
|
||||||
`grep -o avx2 /proc/cpuinfo | head -1`
|
`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
|
- **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`
|
`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.
|
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
|
`docker compose pull` does not. A document that compiled last month stops
|
||||||
compiling and nothing tells you why.
|
compiling and nothing tells you why.
|
||||||
|
|
||||||
The fix is `TEXMFHOME`, which this stack bind-mounts to `${DATA_PATH}/texmf`.
|
The fix is user-mode installs plus a `TEXMFHOME` that both users agree on.
|
||||||
Install in user mode and packages land on the volume instead:
|
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
|
```bash
|
||||||
# once, to create the tree
|
docker exec overleaf tlmgr --usermode init-usertree # once
|
||||||
docker exec overleaf tlmgr init-usertree
|
|
||||||
|
|
||||||
# thereafter, for each package
|
|
||||||
docker exec overleaf tlmgr --usermode install booktabs
|
docker exec overleaf tlmgr --usermode install booktabs
|
||||||
```
|
```
|
||||||
|
|
||||||
Verify it took:
|
Verify as the user that actually compiles, not as root:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec overleaf kpsewhich booktabs.sty
|
docker exec -u www-data overleaf kpsewhich booktabs.sty
|
||||||
# /root/texmf/tex/latex/booktabs/booktabs.sty <- persisted
|
# /var/lib/overleaf/texmf/... correct, persisted
|
||||||
# /usr/local/texlive/... <- inside the image, will be lost
|
# /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
|
**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
|
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
|
that expect to modify the main tree won't work this way — install those with a
|
||||||
|
|||||||
+16
-5
@@ -18,10 +18,6 @@ services:
|
|||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- ${DATA_PATH:-./data}/overleaf:/var/lib/overleaf
|
- ${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:
|
environment:
|
||||||
OVERLEAF_APP_NAME: ${OVERLEAF_APP_NAME:-Overleaf}
|
OVERLEAF_APP_NAME: ${OVERLEAF_APP_NAME:-Overleaf}
|
||||||
@@ -40,6 +36,13 @@ services:
|
|||||||
# which is wrong the moment you use a port or a domain.
|
# which is wrong the moment you use a port or a domain.
|
||||||
OVERLEAF_SITE_URL: ${OVERLEAF_SITE_URL:-http://localhost:8020}
|
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"
|
ENABLED_LINKED_FILE_TYPES: "project_file,project_output_file"
|
||||||
ENABLE_CONVERSIONS: "true"
|
ENABLE_CONVERSIONS: "true"
|
||||||
EMAIL_CONFIRMATION_DISABLED: "true"
|
EMAIL_CONFIRMATION_DISABLED: "true"
|
||||||
@@ -71,8 +74,16 @@ services:
|
|||||||
healthcheck:
|
healthcheck:
|
||||||
test: echo 'db.stats().ok' | mongosh localhost:27017/test --quiet
|
test: echo 'db.stats().ok' | mongosh localhost:27017/test --quiet
|
||||||
interval: 10s
|
interval: 10s
|
||||||
timeout: 10s
|
timeout: 20s
|
||||||
retries: 5
|
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:
|
redis:
|
||||||
image: redis:6.2
|
image: redis:6.2
|
||||||
|
|||||||
Reference in New Issue
Block a user