One StatefulSet with two containers (web + sidekiq) sharing one RWO PVC at /rails/storage. Two separate workloads would need an RWX volume; the shared volume is the reason, not the style. Precedent: patchmon with its guacd sidecar.
appVersion: 0.7.4, chart 1.0.0+up0.7.4. The alpha channel is deliberately not tracked.
AI features are not modelled as values.OPENAI_*, EXTERNAL_ASSISTANT_* and the assistant timeouts are reachable through the additive env block (including secretKeyRef for the token) and documented in NOTES.txt and the wiki. No ai: section, no extra schema surface.
Postgres and Redis stay external, as in every comparable chart here.
Work items
sure/ from template-chart, every xxx replaced, icon: set
StatefulSet with web + worker containers, PVC at /rails/storage, emptyDirs for /rails/tmp and /rails/log so the root filesystem stays read-only
Hardening per the standard — the image already runs as 1000, so no documented deviation should be needed. If one turns out to be unavoidable, it is commented in values.yaml
Three OnePasswordItem CRs: app (SECRET_KEY_BASE), database (host, port, database, username, password as fields), redis (connection-url)
Ingress per the standard, TLS secret tls-<release>-sure-ingress
ingress.domain stays required even when ingress.enabled is false — it is also read for RAILS_ASSUME_SSL/WEBAUTHN_RP_ID, which is the §12.1 case
Probes: liveness on /up, readiness on a path that provably fails without the database, startup budget covering db:prepare; a probe for the sidekiq container that needs no HTTP
replicas plus the chart-global scaleDown
Strict values.schema.json, null-safe fallbacks reproducing this chart's defaults
NOTES.txt: access URL, the exact 1Password fields, the migration-on-start trap, SECRET_KEY_BASE rotation consequences, no real domain
.github/workflows/publish-sure.yml
sure added to the chart-name choice list in change-app-version.yml
ci/sure/ fixtures: throwaway Postgres 16 and Redis, dummy secrets, INSTALL_TIMEOUT raised for the first-start migration
renovate.json5 block with versioning: semver, so -alpha/-rc/-hotfix count as unstable and never automerge; the moving tags stay outside the pattern
README chart row
Wiki page sure, row in Charts, entry in _Sidebar.md
Open points that must be answered, not assumed
Does /up fail when Postgres is down? Rails' Rails::HealthController#show is a boot check and is widely believed to test the database; that belief is what §12.3 exists to catch. The readiness path must be one that demonstrably breaks without the database, and the chart comment must say what was measured versus read from the source.
Which probe form the sidekiq container supports — whether a cheap exec check is possible with what the image ships. Booting Rails per probe is not acceptable.
No Docker daemon in the work environment, so no local k3d run is possible: the runtime proof is the PR install-test. Anything not verified must be written down as unverified rather than as fine.
Acceptance
helm lint --strict sure clean, the chart renders, the PR pipeline green including the install-test, and the wiki page exists before the merge is requested.
A new chart for **Sure** (`we-promise/sure`, the maintained Maybe-finance fork), a self-hosted personal finance app.
Upstream hosting doc: https://github.com/we-promise/sure/blob/main/docs/hosting/docker.md
This body is the approved plan, so there is no separate plan comment.
## Verified upstream facts
Everything below was read off the registry, the Dockerfile, the entrypoint, `compose.example.yml` and `config/routes.rb` — not from memory.
| | |
|---|---|
| Image | `ghcr.io/we-promise/sure` |
| Runtime user | `USER 1000:1000` (`rails`), `WORKDIR /rails`, `EXPOSE 3000` |
| Tags | semver tags exist (`0.7.4`) alongside the moving `stable`, `latest` (upstream calls it alpha) and `nightly`. Prereleases are `-alpha.N`, `-rc.N`, `-hotfix.N` |
| `stable` today | resolves to the **same digest** as `0.7.4` (`sha256:391b2c52…`), so a pinned version tag loses nothing |
| Start behaviour | the entrypoint runs `./bin/rails db:prepare` **only** when the command is `./bin/rails server` — the web process migrates, the worker does not |
| Processes | `web` (Puma) and `worker` (`bundle exec sidekiq`), same image |
| Storage | `/rails/storage` (Active Storage), mounted into **both** processes upstream |
| External services | PostgreSQL (compose uses 16) and Redis — neither belongs in this chart |
| Required env | `SECRET_KEY_BASE`, `SELF_HOSTED=true`, `DB_HOST`, `DB_PORT`, `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`, `REDIS_URL` |
| Health route | `get "up" => "rails/health#show"` |
## Decisions taken (approved)
1. **One StatefulSet with two containers** (web + sidekiq) sharing one RWO PVC at `/rails/storage`. Two separate workloads would need an RWX volume; the shared volume is the reason, not the style. Precedent: patchmon with its guacd sidecar.
2. **`appVersion: 0.7.4`**, chart `1.0.0+up0.7.4`. The alpha channel is deliberately not tracked.
3. **AI features are not modelled as values.** `OPENAI_*`, `EXTERNAL_ASSISTANT_*` and the assistant timeouts are reachable through the additive `env` block (including `secretKeyRef` for the token) and documented in `NOTES.txt` and the wiki. No `ai:` section, no extra schema surface.
4. Postgres and Redis stay external, as in every comparable chart here.
## Work items
- [ ] `sure/` from `template-chart`, every `xxx` replaced, `icon:` set
- [ ] StatefulSet with web + worker containers, PVC at `/rails/storage`, emptyDirs for `/rails/tmp` and `/rails/log` so the root filesystem stays read-only
- [ ] Hardening per the standard — the image already runs as 1000, so no documented deviation should be needed. If one turns out to be unavoidable, it is commented in `values.yaml`
- [ ] Three `OnePasswordItem` CRs: app (`SECRET_KEY_BASE`), database (host, port, database, username, password as fields), redis (`connection-url`)
- [ ] Ingress per the standard, TLS secret `tls-<release>-sure-ingress`
- [ ] **`ingress.domain` stays required even when `ingress.enabled` is false** — it is also read for `RAILS_ASSUME_SSL`/`WEBAUTHN_RP_ID`, which is the §12.1 case
- [ ] Probes: liveness on `/up`, readiness on a path that provably fails without the database, startup budget covering `db:prepare`; a probe for the sidekiq container that needs no HTTP
- [ ] `replicas` plus the chart-global `scaleDown`
- [ ] Strict `values.schema.json`, null-safe fallbacks reproducing *this* chart's defaults
- [ ] `NOTES.txt`: access URL, the exact 1Password fields, the migration-on-start trap, `SECRET_KEY_BASE` rotation consequences, no real domain
- [ ] `.github/workflows/publish-sure.yml`
- [ ] `sure` added to the `chart-name` choice list in `change-app-version.yml`
- [ ] `ci/sure/` fixtures: throwaway Postgres 16 and Redis, dummy secrets, `INSTALL_TIMEOUT` raised for the first-start migration
- [ ] `renovate.json5` block with `versioning: semver`, so `-alpha`/`-rc`/`-hotfix` count as unstable and never automerge; the moving tags stay outside the pattern
- [ ] README chart row
- [ ] Wiki page `sure`, row in `Charts`, entry in `_Sidebar.md`
## Open points that must be answered, not assumed
- **Does `/up` fail when Postgres is down?** Rails' `Rails::HealthController#show` is a boot check and is widely believed to test the database; that belief is what §12.3 exists to catch. The readiness path must be one that demonstrably breaks without the database, and the chart comment must say what was **measured** versus **read from the source**.
- **Which probe form the sidekiq container supports** — whether a cheap `exec` check is possible with what the image ships. Booting Rails per probe is not acceptable.
- **No Docker daemon in the work environment**, so no local k3d run is possible: the runtime proof is the PR install-test. Anything not verified must be written down as unverified rather than as fine.
## Acceptance
`helm lint --strict sure` clean, the chart renders, the PR pipeline green including the install-test, and the wiki page exists before the merge is requested.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
A new chart for Sure (
we-promise/sure, the maintained Maybe-finance fork), a self-hosted personal finance app.Upstream hosting doc: https://github.com/we-promise/sure/blob/main/docs/hosting/docker.md
This body is the approved plan, so there is no separate plan comment.
Verified upstream facts
Everything below was read off the registry, the Dockerfile, the entrypoint,
compose.example.ymlandconfig/routes.rb— not from memory.ghcr.io/we-promise/sureUSER 1000:1000(rails),WORKDIR /rails,EXPOSE 30000.7.4) alongside the movingstable,latest(upstream calls it alpha) andnightly. Prereleases are-alpha.N,-rc.N,-hotfix.Nstabletoday0.7.4(sha256:391b2c52…), so a pinned version tag loses nothing./bin/rails db:prepareonly when the command is./bin/rails server— the web process migrates, the worker does notweb(Puma) andworker(bundle exec sidekiq), same image/rails/storage(Active Storage), mounted into both processes upstreamSECRET_KEY_BASE,SELF_HOSTED=true,DB_HOST,DB_PORT,POSTGRES_DB,POSTGRES_USER,POSTGRES_PASSWORD,REDIS_URLget "up" => "rails/health#show"Decisions taken (approved)
/rails/storage. Two separate workloads would need an RWX volume; the shared volume is the reason, not the style. Precedent: patchmon with its guacd sidecar.appVersion: 0.7.4, chart1.0.0+up0.7.4. The alpha channel is deliberately not tracked.OPENAI_*,EXTERNAL_ASSISTANT_*and the assistant timeouts are reachable through the additiveenvblock (includingsecretKeyReffor the token) and documented inNOTES.txtand the wiki. Noai:section, no extra schema surface.Work items
sure/fromtemplate-chart, everyxxxreplaced,icon:set/rails/storage, emptyDirs for/rails/tmpand/rails/logso the root filesystem stays read-onlyvalues.yamlOnePasswordItemCRs: app (SECRET_KEY_BASE), database (host, port, database, username, password as fields), redis (connection-url)tls-<release>-sure-ingressingress.domainstays required even wheningress.enabledis false — it is also read forRAILS_ASSUME_SSL/WEBAUTHN_RP_ID, which is the §12.1 case/up, readiness on a path that provably fails without the database, startup budget coveringdb:prepare; a probe for the sidekiq container that needs no HTTPreplicasplus the chart-globalscaleDownvalues.schema.json, null-safe fallbacks reproducing this chart's defaultsNOTES.txt: access URL, the exact 1Password fields, the migration-on-start trap,SECRET_KEY_BASErotation consequences, no real domain.github/workflows/publish-sure.ymlsureadded to thechart-namechoice list inchange-app-version.ymlci/sure/fixtures: throwaway Postgres 16 and Redis, dummy secrets,INSTALL_TIMEOUTraised for the first-start migrationrenovate.json5block withversioning: semver, so-alpha/-rc/-hotfixcount as unstable and never automerge; the moving tags stay outside the patternsure, row inCharts, entry in_Sidebar.mdOpen points that must be answered, not assumed
/upfail when Postgres is down? Rails'Rails::HealthController#showis a boot check and is widely believed to test the database; that belief is what §12.3 exists to catch. The readiness path must be one that demonstrably breaks without the database, and the chart comment must say what was measured versus read from the source.execcheck is possible with what the image ships. Booting Rails per probe is not acceptable.Acceptance
helm lint --strict sureclean, the chart renders, the PR pipeline green including the install-test, and the wiki page exists before the merge is requested.