Rewrite Paperclip on the upstream PR-5298 layout (hooks-based)#9
Closed
raccommode wants to merge 1 commit intomasterfrom
Closed
Rewrite Paperclip on the upstream PR-5298 layout (hooks-based)#9raccommode wants to merge 1 commit intomasterfrom
raccommode wants to merge 1 commit intomasterfrom
Conversation
Adopt the structure validated in getumbrel/umbrel-apps#5298 (the PR adding Paperclip to the official Umbrel store), adapted to this community store's id `raccommode-paperclip`. The previous in-compose shell-wrapper approach is replaced by Umbrel-native pre-start / post-start hooks, which run on the host before/after the container and have full access to the host filesystem and `docker exec`. Changes: - `hooks/pre-start`: seeds a complete `instances/default/config.json` with `auth.baseUrlMode=explicit` + `auth.publicBaseUrl= http://${DEVICE_DOMAIN_NAME}:${APP_PROXY_PORT}` so the server boots in `authenticated` + `private` mode without the previous startup errors. Also chowns the data dir to 1000:1000 (replaces the inline shell wrapper). - `hooks/post-start`: polls `/api/health`, parses `bootstrapStatus` and `bootstrapInviteActive`, and runs `npx paperclipai auth bootstrap-ceo` exactly once. The generated invite URL is logged and persisted to `${APP_DATA_DIR}/data/bootstrap-invite-url.txt`. Idempotent because `bootstrap-ceo` itself short-circuits if an admin already exists, and `bootstrapInviteActive=true` means a previous invite is still valid. - `exports.sh`: discovers the host's LAN IPs via `hostname --all-ip-addresses` and exports them as `APP_RACCOMMODE_PAPERCLIP_LOCAL_IPS`, so Paperclip's `PAPERCLIP_ALLOWED_HOSTNAMES` allowlist covers raw-IP access without falling back to `exposure=public`. - `docker-compose.yml`: * Image pinned by digest (sha-a072377), no more `:latest`. * `user: 1000:1000` instead of the gosu / USER_UID dance. * `entrypoint: node` + bare command to skip `docker-entrypoint.sh` (no longer needed once chown is in pre-start). * `PROXY_AUTH_ADD: false` on `app_proxy` so users get a single Paperclip login instead of nested Umbrel + Paperclip auth. * `PAPERCLIP_DEPLOYMENT_EXPOSURE` back to `private` (the safer default) with a populated `PAPERCLIP_ALLOWED_HOSTNAMES` including `${DEVICE_DOMAIN_NAME}`, `${DEVICE_HOSTNAME}`, `${APP_DOMAIN}`, `${APP_HIDDEN_SERVICE}`, the discovered LAN IPs, and the internal Docker hostname — with and without the `:${APP_PROXY_PORT}` suffix. * `BETTER_AUTH_SECRET=${APP_SEED}` (Umbrel-derived stable secret) instead of the per-install random file. * Telemetry flags off. * `data/.gitkeep` so the volume mount target is present in the package. - `umbrel-app.yml`: bump `version` to `2026.403.0` matching the pinned upstream image; release notes updated to reflect the new bootstrap mechanism. Net effect: clean install on Umbrel from this store creates the admin invite automatically, prints it to the app log viewer, and reaches it via `http://umbrel.local:<port>` without manual SSH or exposure-public workarounds. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Owner
Author
|
Superseded — content committed directly to master in ebc0977. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adopt the file layout from getumbrel/umbrel-apps#5298 (the PR adding Paperclip to the official Umbrel store), adapted to this community store's id
raccommode-paperclip. Replaces the in-compose shell-wrapper approach with Umbrel-nativepre-start/post-starthooks andexports.sh.Why
The previous setup (merged in #6 + #7 + #8) embedded the chown, secret bootstrap, allowed-hostname juggle, and bootstrap-CEO runner inside the container's CMD. It worked but:
exposure=publicbecause the LAN IP wasn't known at compose time,The upstream PR uses Umbrel's hook system instead: scripts run on the host, can
docker exec, and have full access to host networking — so the LAN IPs can be discovered viahostname --all-ip-addressesand the bootstrap can be triggered after/api/healthreportsbootstrap_pending. Cleaner and validated by the upstream submitter against fresh installs, restart persistence, and uninstall/reinstall.What changed
New files
raccommode-paperclip/exports.sh— exportsAPP_RACCOMMODE_PAPERCLIP_LOCAL_IPS(comma-separated host LAN IPs) soPAPERCLIP_ALLOWED_HOSTNAMEScan include them.raccommode-paperclip/hooks/pre-start— seedsinstances/default/config.jsonwithauth.baseUrlMode=explicit+publicBaseUrl=http://\${DEVICE_DOMAIN_NAME}:\${APP_PROXY_PORT}, then chowns the data dir to1000:1000.raccommode-paperclip/hooks/post-start— polls/api/health, parsesbootstrapStatus+bootstrapInviteActive, runsnpx paperclipai auth bootstrap-ceoonce if needed, persists the invite URL to\${APP_DATA_DIR}/data/bootstrap-invite-url.txtand logs it.raccommode-paperclip/data/.gitkeep— ensures the volume target exists in the package.Rewritten
raccommode-paperclip/docker-compose.yml:sha-a072377(no more:latest).user: \"1000:1000\"directly, removing the gosu / USER_UID / shell wrapper indirection.entrypoint: node+ bare command —docker-entrypoint.shis no longer needed since chown moved to pre-start.PROXY_AUTH_ADD: falseonapp_proxy→ single Paperclip login instead of nested Umbrel + Paperclip auth.PAPERCLIP_DEPLOYMENT_EXPOSUREreverts toprivate(safer default) with a populatedPAPERCLIP_ALLOWED_HOSTNAMES:\${DEVICE_DOMAIN_NAME},\${DEVICE_HOSTNAME},\${APP_DOMAIN},\${APP_HIDDEN_SERVICE}, the discovered LAN IPs, and the internal Docker hostname — with and without:\${APP_PROXY_PORT}suffix.BETTER_AUTH_SECRET=\${APP_SEED}(Umbrel-derived stable secret) instead of the runtime-generated/paperclip/.better-auth-secret.PAPERCLIP_TELEMETRY_DISABLED=1,DO_NOT_TRACK=1).Updated
raccommode-paperclip/umbrel-app.yml:versionbumped fromlatestto2026.403.0to match the pinned image; release notes updated.Test plan
Paperclip bootstrap invite: http://umbrel.local:<port>/invite/pcp_bootstrap_*shortly after start.bootstrap not required(oralready active), no duplicate invite.http://<lan-ip>:\${APP_PROXY_PORT}without 403 (LAN IPs covered by allowed-hostnames viaexports.sh).\${APP_DATA_DIR}/data/bootstrap-invite-url.txtcontains the URL on the host.Credits
Layout and hook scripts adapted from @aidencole98's umbrel-apps#5298.
🤖 Generated with Claude Code