Run the per-member key seed from the image, not the volume #2
No files matched your search
@@ -26,7 +26,7 @@
|
|||||||
"scheduler": {
|
"scheduler": {
|
||||||
"librechat_key_sync": {
|
"librechat_key_sync": {
|
||||||
"schedule": "*/10 * * * *",
|
"schedule": "*/10 * * * *",
|
||||||
"command": "cd /app/code/librechat/api && node /app/data/sync-keys.js"
|
"command": "cd /app/code/librechat/api && node /app/code/sync-keys.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
+9
-1
@@ -15,7 +15,9 @@
|
|||||||
# built from this repo on every deploy (the base FROM stays the appstore
|
# built from this repo on every deploy (the base FROM stays the appstore
|
||||||
# image we validated). A stale dockerImage pin silently redeploys an old
|
# image we validated). A stale dockerImage pin silently redeploys an old
|
||||||
# build — that is what broke the sandbox on 2026-10-18/19.
|
# build — that is what broke the sandbox on 2026-10-18/19.
|
||||||
# 3. This image changes ONLY static brand assets. All behavior lives on the
|
# 3. This image changes ONLY static brand assets plus operational scripts that
|
||||||
|
# must not depend on the persistent volume (currently sync-keys.js, run by
|
||||||
|
# the manifest's scheduler task). All other behavior lives on the
|
||||||
# persistent volume (/app/data/librechat.yaml, /app/data/env,
|
# persistent volume (/app/data/librechat.yaml, /app/data/env,
|
||||||
# /app/data/mcp/) and survives image updates unchanged.
|
# /app/data/mcp/) and survives image updates unchanged.
|
||||||
FROM cloudron/ai.librechat.cloudronapp:202610150224320000
|
FROM cloudron/ai.librechat.cloudronapp:202610150224320000
|
||||||
@@ -41,6 +43,12 @@ COPY assets/custom.css /app/code/librechat/client/dist/assets/custom.css
|
|||||||
# rebuild trigger
|
# rebuild trigger
|
||||||
COPY assets/custom2.js /app/code/librechat/client/dist/assets/custom2.js
|
COPY assets/custom2.js /app/code/librechat/client/dist/assets/custom2.js
|
||||||
|
|
||||||
|
# Per-member key seed (manifest scheduler task `librechat_key_sync`). Shipping it
|
||||||
|
# in the image rather than on the volume means it cannot vanish with a volume
|
||||||
|
# restore and cannot drift from this repo; the script prints its own md5 prefix
|
||||||
|
# on every run so the running revision is auditable.
|
||||||
|
COPY sync-keys.js /app/code/sync-keys.js
|
||||||
|
|
||||||
# Co-op UI strings: rename the "MCP Servers" button to "Tools" and replace
|
# Co-op UI strings: rename the "MCP Servers" button to "Tools" and replace
|
||||||
# the LibreChat footer tagline with the co-op footer. Non-fatal at build.
|
# the LibreChat footer tagline with the co-op footer. Non-fatal at build.
|
||||||
COPY patch_ui_strings.py /app/code/patch_ui_strings.py
|
COPY patch_ui_strings.py /app/code/patch_ui_strings.py
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ md5sum librechat.yaml mcp/server.py mcp/image_server.py
|
|||||||
| Env vars (env-file wins!) | `/app/data/env` (volume, sourced LAST by start.sh) | yes | documented below |
|
| Env vars (env-file wins!) | `/app/data/env` (volume, sourced LAST by start.sh) | yes | documented below |
|
||||||
| Env vars (Cloudron-managed) | `cloudron env` (process env) | yes | documented below |
|
| Env vars (Cloudron-managed) | `cloudron env` (process env) | yes | documented below |
|
||||||
| MCP servers | `/app/data/mcp/server.py` + `mcp/image_server.py` (volume) | yes | `mcp/` |
|
| MCP servers | `/app/data/mcp/server.py` + `mcp/image_server.py` (volume) | yes | `mcp/` |
|
||||||
| Per-member key seed | `/app/data/sync-keys.js` (volume; run by the manifest's `scheduler` task) | yes | `sync-keys.js` |
|
| Per-member key seed | `sync-keys.js` baked into the image at `/app/code/sync-keys.js` (run by the manifest's `scheduler` task) | no — rebuilt per image | `sync-keys.js` |
|
||||||
| Brand assets + branding CSS/JS | baked into image overlay | no — rebuilt per image | `assets/` |
|
| Brand assets + branding CSS/JS | baked into image overlay | no — rebuilt per image | `assets/` |
|
||||||
| `CloudronManifest.json` | repo only (controls what `cloudron update` deploys) | n/a | official appstore manifest **except `dockerImage`** |
|
| `CloudronManifest.json` | repo only (controls what `cloudron update` deploys) | n/a | official appstore manifest **except `dockerImage`** |
|
||||||
|
|
||||||
@@ -333,11 +333,21 @@ member's own portal-provisioned key automatically:
|
|||||||
"scheduler": {
|
"scheduler": {
|
||||||
"librechat_key_sync": {
|
"librechat_key_sync": {
|
||||||
"schedule": "*/10 * * * *",
|
"schedule": "*/10 * * * *",
|
||||||
"command": "cd /app/code/librechat/api && node /app/data/sync-keys.js"
|
"command": "cd /app/code/librechat/api && node /app/code/sync-keys.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The script is **baked into the image** (`COPY sync-keys.js /app/code/…`), so it
|
||||||
|
cannot be lost with a volume restore and cannot drift from this repo.
|
||||||
|
|
||||||
|
**Ordering matters on the first deploy of this change:** build the image → deploy
|
||||||
|
(pin the new tag in the manifest first — the manifest's repointed command ships
|
||||||
|
in the same `cloudron update`) → verify (`./release.sh verify` checks that the
|
||||||
|
command path exists in the running image) → only then delete the volume copy
|
||||||
|
`/app/data/sync-keys.js`, because rolling back to the previous image tag needs it
|
||||||
|
back. After that, a change to this script requires a rebuild, not a volume push.
|
||||||
|
|
||||||
Seeding therefore depends on nothing outside this app — it previously ran from a
|
Seeding therefore depends on nothing outside this app — it previously ran from a
|
||||||
steward cron on another machine, which made a member-facing function depend on
|
steward cron on another machine, which made a member-facing function depend on
|
||||||
that machine's uptime and paths.
|
that machine's uptime and paths.
|
||||||
|
|||||||
Reference in new issue
Block a user