Skip to content

Setup helm chart for garage#1

Open
stplasim wants to merge 6 commits into
mainfrom
setup-helm-chart
Open

Setup helm chart for garage#1
stplasim wants to merge 6 commits into
mainfrom
setup-helm-chart

Conversation

@stplasim

@stplasim stplasim commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Setup of the AboutBits Garage Helm chart

Adds a Helm chart for deploying Garage (S3-compatible object storage).

Derived from the official chart, but trimmed to what we need: a single node. No node discovery, clustering, CRDs, or ClusterRoles. Just replication_factor=1, one StatefulSet replica.

First-boot bootstrap without an init container

Initially we assumed we'd need an init container (or a post-install Job) to create the initial bucket and access key. Turns out Garage v2.3.0 added native flags for exactly this: garage server --single-node --default-bucket reads GARAGE_DEFAULT_ACCESS_KEY / GARAGE_DEFAULT_SECRET_KEY / GARAGE_DEFAULT_BUCKET from the environment and provisions them on first boot. So the bootstrap is fully declarative; no init container, no extra Job, no CLI scripting.

Other stuff

  • External access via classic Ingress or Gateway API HTTPRoute (mutually exclusive).
  • Kept from upstream: security hardening (non-root, dropped caps, read-only rootfs) and optional Prometheus monitoring.

@stplasim stplasim requested review from ThoSap and alexlanz July 10, 2026 05:25

@alexlanz alexlanz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@stplasim You mentioned that we don't a job to create the buckets.

Initially we assumed we'd need an init container (or a post-install Job) to create the initial bucket and access key. Turns out Garage v2.3.0 added native flags for exactly this: garage server --single-node --default-bucket reads GARAGE_DEFAULT_ACCESS_KEY / GARAGE_DEFAULT_SECRET_KEY / GARAGE_DEFAULT_BUCKET from the environment and provisions them on first boot. So the bootstrap is fully declarative; no init container, no extra Job, no CLI scripting.

But what if we need multiple buckets or multiple users (ex. one with just read access). Can we handle that then with the current implementation?

# Set your own (any sufficiently random string) so it is known up front for
# managing buckets/keys via the admin API. Prefer --set / Terraform over
# committing it to git.
token: ""

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Like this the token is passed as plain text. Do you see no concerns with this approach?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not really. In Terraform we pull the token from 1Password and pass it through a sensitive = true variable, same as we already do for e.g. the Grafana admin password or SMTP credentials.

On the cluster side the chart puts it only into a Kubernetes Secret (config is Secret-mounted, no ConfigMap). So the only copies are TF state and Helm's release secret, which hold all our other credentials anyway. An existingSecret indirection wouldn't remove it from TF state either.

That said, we could improve it further by going the 1Password operator route like we do for Loki. But that would mean installing the 1Password Connect operator on the client clusters too, and I'm not sure that's planned.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sorry, you are right. Nevermind.

# Must start with "GK" by Garage convention (GK + 16 hex chars).
accessKey: ""
# -- Secret access key for the default bucket. Required when bootstrap.enabled=true.
secretKey: ""

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same here.

@stplasim

Copy link
Copy Markdown
Contributor Author

But what if we need multiple buckets or multiple users (ex. one with just read access). Can we handle that then with the current implementation?

You can create as many buckets and tokens as you need. This is only intended for the initial setup. The Helm chart should not reconcile these resources after bootstrapping.

Once the server is up, you can use the CLI to manage it however you want. You can also disable bootstrapping entirely and configure everything manually if you prefer.

@alexlanz

Copy link
Copy Markdown
Member

Oh, I see. This is where we then need the custom operator that manages all the setup of buckets and users right?

@alexlanz alexlanz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good!

@ThoSap ThoSap left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Awesome 🔥

Some very minor things.

runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@v5

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
- uses: actions/checkout@v5
- uses: actions/checkout@v7

token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}
- uses: aboutbits/github-actions-base/git-setup@v2
- name: Set up Helm
uses: azure/setup-helm@v4

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
uses: azure/setup-helm@v4
uses: azure/setup-helm@v5

- name: Set up Helm
uses: azure/setup-helm@v4
with:
version: 3.21.3

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

As Helm v4 is out since November 2025, we should think of upgrading to v4 in the future.

v3 is fine for now.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add an additional helm lint workflow for the PR CI.
https://helm.sh/docs/helm/helm_lint/

Comment thread garage/values.yaml
- host: s3.example.com
paths:
- path: /
pathType: Prefix

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If I remember correctly Prefix will log a warning in newer NGINX Ingress versions, we should use the default ImplementationSpecific instead

Suggested change
pathType: Prefix
pathType: ImplementationSpecific

Comment thread garage/values.yaml
Comment on lines +105 to +118
probes:
liveness:
httpGet:
path: /health
port: admin
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 6
readiness:
httpGet:
path: /health
port: admin
initialDelaySeconds: 5
periodSeconds: 5

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These won't work if someone decides to set admin.enabled: false as the named port will not be created, so the Garage StatefulSet will never start.

But I think this is a good start anyway, and a tradeoff we can accept for now.

- host: s3.example.com
paths:
- path: /
pathType: Prefix

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
pathType: Prefix
pathType: ImplementationSpecific

Comment thread garage/Chart.yaml
Comment on lines +5 to +6
version: 0.1.0
appVersion: "v2.3.0"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If we ever accidentally release a version like 1.0 instead of using SemVer 1.0.0, YAML will interpret it as a floating-point number if we don't quote it.

Suggested change
version: 0.1.0
appVersion: "v2.3.0"
version: "0.1.0"
appVersion: "v2.3.0"

Comment thread garage/Chart.yaml
Comment on lines +12 to +13
sources:
- https://git.deuxfleurs.fr/Deuxfleurs/garage

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's also add the GitHub URL.

Suggested change
sources:
- https://git.deuxfleurs.fr/Deuxfleurs/garage
sources:
- https://git.deuxfleurs.fr/Deuxfleurs/garage
- https://github.com/datahub-local/garage-helm

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.

3 participants