Skip to content

Commit b44031d

Browse files
committed
Add release workflow
Signed-off-by: Dan Webb <dan.webb@damacus.io>
1 parent 67e99f7 commit b44031d

File tree

6 files changed

+411
-0
lines changed

6 files changed

+411
-0
lines changed

.github/workflows/release.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ on:
88
permissions:
99
contents: write
1010
pull-requests: write
11+
packages: write
1112

1213
jobs:
1314
release-please:
@@ -80,3 +81,56 @@ jobs:
8081
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8182
run: |
8283
gh release upload ${{ needs.release-please.outputs.tag_name }} dist/*
84+
85+
docker:
86+
name: Build and Push Container Images
87+
needs: release-please
88+
if: ${{ needs.release-please.outputs.release_created }}
89+
runs-on: ubuntu-latest
90+
strategy:
91+
matrix:
92+
include:
93+
- image: ironbuckets
94+
context: .
95+
dockerfile: Dockerfile
96+
- image: minio-community
97+
context: ./docker/minio
98+
dockerfile: ./docker/minio/Dockerfile
99+
steps:
100+
- uses: actions/checkout@v6
101+
102+
- name: Set up QEMU
103+
uses: docker/setup-qemu-action@v3
104+
105+
- name: Set up Docker Buildx
106+
uses: docker/setup-buildx-action@v3
107+
108+
- name: Log in to GitHub Container Registry
109+
uses: docker/login-action@v3
110+
with:
111+
registry: ghcr.io
112+
username: ${{ github.actor }}
113+
password: ${{ secrets.GITHUB_TOKEN }}
114+
115+
- name: Extract metadata
116+
id: meta
117+
uses: docker/metadata-action@v5
118+
with:
119+
images: ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}
120+
tags: |
121+
type=semver,pattern={{version}},value=${{ needs.release-please.outputs.tag_name }}
122+
type=semver,pattern={{major}}.{{minor}},value=${{ needs.release-please.outputs.tag_name }}
123+
type=semver,pattern={{major}},value=${{ needs.release-please.outputs.tag_name }}
124+
type=raw,value=latest
125+
126+
- name: Build and push
127+
uses: docker/build-push-action@v6
128+
with:
129+
context: ${{ matrix.context }}
130+
file: ${{ matrix.dockerfile }}
131+
platforms: linux/amd64,linux/arm64
132+
push: true
133+
tags: ${{ steps.meta.outputs.tags }}
134+
labels: ${{ steps.meta.outputs.labels }}
135+
cache-from: type=gha
136+
cache-to: type=gha,mode=max

kubernetes/README.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# IronBuckets Kubernetes Deployment
2+
3+
This directory contains Kubernetes manifests for deploying IronBuckets using
4+
[Flux](https://fluxcd.io/) and the
5+
[bjw-s app-template](https://github.com/bjw-s/helm-charts/tree/main/charts/library/common)
6+
Helm chart.
7+
8+
## Architecture
9+
10+
The deployment runs two containers in a single pod:
11+
12+
- **ironbuckets** - The main web UI application (port 8080)
13+
- **minio** - MinIO object storage server (ports 9000, 9001)
14+
15+
## Container Images
16+
17+
Images are published to GitHub Container Registry on each release:
18+
19+
- `ghcr.io/damacus/ironbuckets:latest`
20+
- `ghcr.io/damacus/minio-community:latest`
21+
22+
Both images support `linux/amd64` and `linux/arm64` architectures.
23+
24+
## Prerequisites
25+
26+
- Kubernetes cluster with Flux installed
27+
- [bjw-s HelmRepository](https://github.com/bjw-s/helm-charts) configured
28+
- External Secrets Operator (optional, for secret management)
29+
- Gateway API or Ingress controller
30+
31+
## Directory Structure
32+
33+
```text
34+
kubernetes/
35+
└── apps/
36+
└── ironbuckets/
37+
├── ks.yaml # Flux Kustomization
38+
└── app/
39+
├── HelmRelease.yaml # App-template HelmRelease
40+
├── externalsecret.yaml # External secret for credentials
41+
└── kustomization.yaml # Kustomize resources
42+
```
43+
44+
## Configuration
45+
46+
### Required Secrets
47+
48+
Create a secret named `ironbuckets-secret` with:
49+
50+
- `MINIO_ACCESS_KEY` - MinIO access key / username
51+
- `MINIO_SECRET_KEY` - MinIO secret key / password
52+
53+
If using External Secrets Operator, update `externalsecret.yaml` with your
54+
secret store configuration.
55+
56+
### Manual Secret Creation
57+
58+
```bash
59+
kubectl create secret generic ironbuckets-secret \
60+
--from-literal=MINIO_ACCESS_KEY=your-access-key \
61+
--from-literal=MINIO_SECRET_KEY=your-secret-key
62+
```
63+
64+
### Customization
65+
66+
Edit `HelmRelease.yaml` to customize:
67+
68+
- **Image tags** - Pin to specific versions instead of `latest`
69+
- **Resource limits** - Adjust CPU/memory based on your needs
70+
- **Persistence** - Configure storage class and size
71+
- **Routes/Ingress** - Update hostnames for your domain
72+
73+
## Standalone Deployment
74+
75+
If not using Flux, you can deploy with Helm directly:
76+
77+
```bash
78+
helm repo add bjw-s https://bjw-s.github.io/helm-charts
79+
helm repo update
80+
81+
# Extract values from HelmRelease.yaml and apply
82+
helm install ironbuckets bjw-s/app-template \
83+
--values <your-values.yaml>
84+
```
85+
86+
## Services
87+
88+
The deployment creates three services:
89+
90+
| Service | Port | Description |
91+
| -------------------------- | ---- | ------------------------ |
92+
| ironbuckets-app | 8080 | IronBuckets web UI |
93+
| ironbuckets-minio-api | 9000 | MinIO S3 API |
94+
| ironbuckets-minio-console | 9001 | MinIO web console |
95+
96+
## Health Checks
97+
98+
Both containers have liveness and readiness probes configured:
99+
100+
- **IronBuckets**: `GET /health` on port 8080
101+
- **MinIO**: `GET /minio/health/live` and `/minio/health/ready` on port 9000
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json
2+
apiVersion: helm.toolkit.fluxcd.io/v2
3+
kind: HelmRelease
4+
metadata:
5+
name: ironbuckets
6+
spec:
7+
interval: 30m
8+
chart:
9+
spec:
10+
chart: app-template
11+
version: 4.4.0
12+
sourceRef:
13+
kind: HelmRepository
14+
name: bjw-s
15+
namespace: flux-system
16+
install:
17+
remediation:
18+
retries: 3
19+
upgrade:
20+
cleanupOnFail: true
21+
remediation:
22+
retries: 3
23+
strategy: uninstall
24+
uninstall:
25+
keepHistory: false
26+
values:
27+
controllers:
28+
ironbuckets:
29+
annotations:
30+
reloader.stakater.com/auto: "true"
31+
containers:
32+
app:
33+
image:
34+
repository: ghcr.io/damacus/ironbuckets
35+
tag: latest # Replace with specific version
36+
env:
37+
MINIO_ENDPOINT: minio.${SECRET_DOMAIN}:443
38+
MINIO_USE_SSL: "true"
39+
# Credentials should be provided via secrets
40+
MINIO_ACCESS_KEY:
41+
valueFrom:
42+
secretKeyRef:
43+
name: ironbuckets-secret
44+
key: MINIO_ACCESS_KEY
45+
MINIO_SECRET_KEY:
46+
valueFrom:
47+
secretKeyRef:
48+
name: ironbuckets-secret
49+
key: MINIO_SECRET_KEY
50+
probes:
51+
liveness:
52+
enabled: true
53+
custom: true
54+
spec:
55+
httpGet:
56+
path: /health
57+
port: 8080
58+
initialDelaySeconds: 5
59+
periodSeconds: 10
60+
readiness:
61+
enabled: true
62+
custom: true
63+
spec:
64+
httpGet:
65+
path: /health
66+
port: 8080
67+
initialDelaySeconds: 5
68+
periodSeconds: 10
69+
resources:
70+
requests:
71+
cpu: 10m
72+
memory: 64Mi
73+
limits:
74+
memory: 256Mi
75+
securityContext:
76+
allowPrivilegeEscalation: false
77+
readOnlyRootFilesystem: true
78+
capabilities: { drop: ["ALL"] }
79+
80+
minio:
81+
image:
82+
repository: ghcr.io/damacus/minio-community
83+
tag: latest # Replace with specific version
84+
args:
85+
- server
86+
- /data
87+
- --console-address
88+
- ":9001"
89+
env:
90+
MINIO_ROOT_USER:
91+
valueFrom:
92+
secretKeyRef:
93+
name: ironbuckets-secret
94+
key: MINIO_ACCESS_KEY
95+
MINIO_ROOT_PASSWORD:
96+
valueFrom:
97+
secretKeyRef:
98+
name: ironbuckets-secret
99+
key: MINIO_SECRET_KEY
100+
probes:
101+
liveness:
102+
enabled: true
103+
custom: true
104+
spec:
105+
httpGet:
106+
path: /minio/health/live
107+
port: 9000
108+
initialDelaySeconds: 10
109+
periodSeconds: 30
110+
readiness:
111+
enabled: true
112+
custom: true
113+
spec:
114+
httpGet:
115+
path: /minio/health/ready
116+
port: 9000
117+
initialDelaySeconds: 10
118+
periodSeconds: 30
119+
resources:
120+
requests:
121+
cpu: 50m
122+
memory: 256Mi
123+
limits:
124+
memory: 1Gi
125+
securityContext:
126+
allowPrivilegeEscalation: false
127+
readOnlyRootFilesystem: false # MinIO needs to write to /data
128+
capabilities: { drop: ["ALL"] }
129+
130+
pod:
131+
securityContext:
132+
runAsNonRoot: true
133+
runAsUser: 1000
134+
runAsGroup: 1000
135+
fsGroup: 1000
136+
fsGroupChangePolicy: Always
137+
seccompProfile: { type: RuntimeDefault }
138+
139+
service:
140+
app:
141+
controller: ironbuckets
142+
ports:
143+
http:
144+
port: 8080
145+
minio-api:
146+
controller: ironbuckets
147+
ports:
148+
s3:
149+
port: 9000
150+
minio-console:
151+
controller: ironbuckets
152+
ports:
153+
console:
154+
port: 9001
155+
156+
route:
157+
app:
158+
hostnames: ["ironbuckets.${SECRET_DOMAIN}"]
159+
parentRefs:
160+
- name: internal
161+
namespace: kube-system
162+
sectionName: https
163+
minio:
164+
hostnames: ["minio.${SECRET_DOMAIN}", "s3.${SECRET_DOMAIN}"]
165+
parentRefs:
166+
- name: internal
167+
namespace: kube-system
168+
sectionName: https
169+
rules:
170+
- backendRefs:
171+
- identifier: minio-api
172+
port: 9000
173+
minio-console:
174+
hostnames: ["minio-console.${SECRET_DOMAIN}"]
175+
parentRefs:
176+
- name: internal
177+
namespace: kube-system
178+
sectionName: https
179+
rules:
180+
- backendRefs:
181+
- identifier: minio-console
182+
port: 9001
183+
184+
persistence:
185+
data:
186+
enabled: true
187+
type: persistentVolumeClaim
188+
accessMode: ReadWriteOnce
189+
size: 10Gi
190+
advancedMounts:
191+
ironbuckets:
192+
minio:
193+
- path: /data
194+
# Temp directory for ironbuckets app (read-only root filesystem)
195+
tmp:
196+
enabled: true
197+
type: emptyDir
198+
advancedMounts:
199+
ironbuckets:
200+
app:
201+
- path: /tmp
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1beta1.json
2+
apiVersion: external-secrets.io/v1beta1
3+
kind: ExternalSecret
4+
metadata:
5+
name: ironbuckets-secret
6+
spec:
7+
secretStoreRef:
8+
kind: ClusterSecretStore
9+
name: onepassword-connect # Adjust to your secret store
10+
target:
11+
name: ironbuckets-secret
12+
creationPolicy: Owner
13+
data:
14+
- secretKey: MINIO_ACCESS_KEY
15+
remoteRef:
16+
key: ironbuckets
17+
property: MINIO_ACCESS_KEY
18+
- secretKey: MINIO_SECRET_KEY
19+
remoteRef:
20+
key: ironbuckets
21+
property: MINIO_SECRET_KEY
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
# yaml-language-server: $schema=https://json.schemastore.org/kustomization
3+
apiVersion: kustomize.config.k8s.io/v1beta1
4+
kind: Kustomization
5+
resources:
6+
- ./HelmRelease.yaml
7+
- ./externalsecret.yaml

0 commit comments

Comments
 (0)