Skip to content

fix: hub pinned at specific tag/digest#7923

Merged
pandeymangg merged 2 commits into
epic/v5from
fix/pinning-hub
May 5, 2026
Merged

fix: hub pinned at specific tag/digest#7923
pandeymangg merged 2 commits into
epic/v5from
fix/pinning-hub

Conversation

@pandeymangg
Copy link
Copy Markdown
Contributor

@pandeymangg pandeymangg commented May 4, 2026

What does this PR do?

Fixes ENG-767

Pins the ghcr.io/formbricks/hub image so dev, CI, and production deployments all resolve to a known, reproducible image instead of silently reusing whatever
:latest happens to be cached locally.

Today every reference to the Hub image uses :latest. Docker does not re-pull a tag that already exists locally, so devs (and CI) can run a Hub image months
out of sync with the current branch. We hit this in practice: a stale :latest cache was missing the goose/river migration binaries the newer compose expects,
and pnpm go failed with Migration tools (goose/river) not in image. Same class of issue blocks reproducibility for onboarding and breaks the
chain-of-custody story for the Hub image.

This PR:

  • Dev compose (docker-compose.dev.yml): both hub and hub-migrate now reference ghcr.io/formbricks/hub:${HUB_IMAGE_TAG:-0.2.0}. Single shared
    variable so the two services cannot drift apart. Override via HUB_IMAGE_TAG in the repo-root .env (auto-loaded by docker compose) or shell.
  • Prod compose (docker/docker-compose.yml): both hub and hub-migrate now reference
    ghcr.io/formbricks/hub@${HUB_IMAGE_DIGEST:-sha256:14db7b3d285b6e9165b55693f9b83d08beff840a255fd77dd12882ee0a62f5cb}. Pinned by immutable digest with a single
    override knob.
  • Helm chart: added hub.image.digest to values.yaml and a new formbricks.hubImage helper template. Hub deployment (init container + main container)
    and hub migration job all render through the helper, so the deployment, init container, and migration job always resolve to the exact same image. When digest
    is set it takes precedence over tag; tag remains as a dev fallback.
  • Fixed a pre-existing bug: charts/formbricks/values.yaml had tag: "1.0.0" but the registry only publishes 0.1.0, 0.2.0, and latest. The default
    helm install would have 404'd on the image pull. Corrected to 0.2.0, which matches the pinned digest above.
  • Docs: docker/README.md documents the new override knobs (HUB_IMAGE_DIGEST for prod, HUB_IMAGE_TAG for dev) alongside the existing
    HUB_DATABASE_URL / CUBEJS_DB_* overrides. .env.example adds a commented HUB_IMAGE_TAG line so devs see the knob.

The digest sha256:14db7b3d285b6e9165b55693f9b83d08beff840a255fd77dd12882ee0a62f5cb corresponds to ghcr.io/formbricks/hub:0.2.0 (verified directly against
ghcr.io/v2/formbricks/hub/manifests/0.2.0).

Fixes #(issue)

How should this be tested?

Dev compose (docker-compose.dev.yml):

  • pnpm db:down && docker image rm ghcr.io/formbricks/hub:latest ghcr.io/formbricks/hub:0.2.0 || true
  • pnpm go and confirm both hub and hub-migrate containers come up healthy and hub-migrate exits 0.
  • docker inspect $(docker compose -f docker-compose.dev.yml ps -q hub) --format '{{.Image}}' and ... ps -q hub-migrate — confirm both report the same image
    ID (no drift).
  • Set HUB_IMAGE_TAG=0.1.0 in repo-root .env, re-run pnpm db:up, and confirm both services pull 0.1.0.

Prod compose (docker/docker-compose.yml):

  • cd docker && HUB_API_KEY=test CUBEJS_API_SECRET=test docker compose config | grep "ghcr.io/formbricks/hub" — confirm both hub and hub-migrate resolve
    to the same @sha256:... digest.
  • Override path: echo "HUB_IMAGE_DIGEST=sha256:<other>" >> docker/.env && docker compose config and confirm both services pick up the override.

Helm chart:

  • helm template charts/formbricks --set hub.enabled=true | grep "image:.*hub" — confirm 3 occurrences (deployment init container, deployment main container,
    migration job), all rendering the same repo@sha256:....
  • Clear digest: helm template charts/formbricks --set hub.image.digest="" | grep "image:.*hub" — confirm fallback to repo:0.2.0.

Checklist

Required

  • Filled out the "How to test" section in this PR
  • Read How we Code at Formbricks
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand bits
  • Ran pnpm build
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues
  • First PR at Formbricks? Please sign the CLA! Without it we wont be able to merge it 🙏

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR (no UI changes)
  • Updated the Formbricks Docs if changes were necessary (docker/README.md)

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 2026

Walkthrough

The pull request updates container image pinning for the Formbricks Hub across multiple configuration and template files. In production (Helm charts and docker-compose.yml), the Hub image moves to immutable digest-based pinning via HUB_IMAGE_DIGEST environment variable with a default hash. In development (docker-compose.dev.yml and .env.example), it uses semver tag pinning via HUB_IMAGE_TAG environment variable (defaulting to 0.2.0). A new Helm helper template is introduced to handle digest/tag resolution. Documentation is updated to reflect these pinning strategies across both setups.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title directly describes the main change: pinning the Hub image to specific tags/digests for reproducibility across dev, CI, and production environments.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed PR provides comprehensive description, detailed test instructions, and mostly completes required checklist; however, two required items remain unchecked.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@charts/formbricks/templates/_helpers.tpl`:
- Around line 109-115: The helper formbricks.hubImage currently falls back to a
mutable "latest" tag when both .Values.hub.image.digest and
.Values.hub.image.tag are empty; update the template logic in the
formbricks.hubImage definition to detect the case where .Values.hub.image.digest
is empty/undefined AND .Values.hub.image.tag is empty/undefined and call fail
with a clear error message (e.g., instructing to set either hub.image.digest or
hub.image.tag) instead of printing ":latest", keeping the existing behavior of
using repository@digest when digest exists and repository:tag when tag is
provided.

In `@docker/README.md`:
- Around line 36-37: Update the README to clarify the required format for the
HUB_IMAGE_DIGEST override: state that HUB_IMAGE_DIGEST must be a full digest
including the "sha256:" prefix (not a bare tag), give a concrete example format
(e.g. sha256:<64-hex-chars>), and explain briefly how to obtain it (e.g. via
docker buildx imagetools inspect ghcr.io/formbricks/hub:0.3.0) and where to
place it (docker/.env) so that using HUB_IMAGE_DIGEST results in a valid image
reference like ghcr.io/formbricks/hub@sha256:...
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7af6424a-2717-4666-b07b-c132285fd17c

📥 Commits

Reviewing files that changed from the base of the PR and between ea92ef9 and e11ce9f.

📒 Files selected for processing (9)
  • .env.example
  • charts/formbricks/README.md
  • charts/formbricks/templates/_helpers.tpl
  • charts/formbricks/templates/hub-deployment.yaml
  • charts/formbricks/templates/hub-migration-job.yaml
  • charts/formbricks/values.yaml
  • docker-compose.dev.yml
  • docker/README.md
  • docker/docker-compose.yml

Comment thread charts/formbricks/templates/_helpers.tpl
Comment thread docker/README.md Outdated
Copy link
Copy Markdown
Contributor

@BhagyaAmarasinghe BhagyaAmarasinghe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The production compose file now pins Hub to a fixed digest, but docker/formbricks.sh update_formbricks still only runs docker compose pull/down/up. New installs will keep this exact Hub digest forever while ghcr.io/formbricks/formbricks:latest continues advancing, so a normal self-host update can run a newer app against an old Hub/migration image. Either the update flow needs to refresh/rewrite the Hub digest, or the production compose default should remain a moving tag with an explicit opt-in digest pin.

@pandeymangg
Copy link
Copy Markdown
Contributor Author

The production compose file now pins Hub to a fixed digest, but docker/formbricks.sh update_formbricks still only runs docker compose pull/down/up. New installs will keep this exact Hub digest forever while ghcr.io/formbricks/formbricks:latest continues advancing, so a normal self-host update can run a newer app against an old Hub/migration image. Either the update flow needs to refresh/rewrite the Hub digest, or the production compose default should remain a moving tag with an explicit opt-in digest pin.

Fixed by the later suggestion, removed the digest pinning from prod compose and added explicit opt-in digest pin, also updated the README

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 5, 2026

@pandeymangg pandeymangg merged commit 59f5cdf into epic/v5 May 5, 2026
13 checks passed
@pandeymangg pandeymangg deleted the fix/pinning-hub branch May 5, 2026 07:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants