Updated: 2026-03-12
All container images are published to GitHub Container Registry (ghcr.io):
| Image | Description |
|---|---|
ghcr.io/seebom-labs/seebom/ingestion-watcher |
CronJob: scans SBOM/VEX files, enqueues jobs |
ghcr.io/seebom-labs/seebom/parsing-worker |
Stateless worker: parses SBOMs, queries OSV, checks licenses |
ghcr.io/seebom-labs/seebom/api-gateway |
REST API (16 endpoints) |
ghcr.io/seebom-labs/seebom/cve-refresher |
CronJob: daily incremental CVE checks against OSV |
ghcr.io/seebom-labs/seebom/ui |
Angular frontend (Nginx) |
Images are built for linux/amd64 and linux/arm64.
git tag v0.1.2
git push origin v0.1.2The GitHub Actions workflow (.github/workflows/release.yml) triggers on any v* tag and:
- Builds all 5 container images (multi-arch: amd64 + arm64)
- Pushes them to ghcr.io with two tags each:
ghcr.io/seebom-labs/seebom/<component>:0.1.2(version)ghcr.io/seebom-labs/seebom/<component>:latest
- Packages the Helm chart with the matching version
- Pushes the Helm chart as an OCI artifact to
oci://ghcr.io/seebom-labs/seebom/charts - Creates a GitHub Release with:
- Auto-generated release notes from commits since the last tag
docker pullcommands for all 5 imageshelm installcommand for the chart- Pre-release flag for
-rc,-alpha,-betatags
Release notes are grouped by PR labels (see .github/release.yml):
- 🚀 Features (
enhancement,feature) - 🐛 Bug Fixes (
bug,fix) - 📖 Documentation (
docs) - 🧪 Tests (
test) - 🔧 Maintenance (
chore,dependencies,ci) - 🔒 Security (
security)
# Check images exist
docker pull ghcr.io/seebom-labs/seebom/api-gateway:0.1.2
# Check Helm chart
helm show chart oci://ghcr.io/seebom-labs/seebom/charts/seebom --version 0.1.2helm install seebom oci://ghcr.io/seebom-labs/seebom/charts/seebom \
--version 0.1.2 \
-f values-production.yamlhelm install seebom oci://ghcr.io/seebom-labs/seebom/charts/seebom \
--version 0.1.2 \
--set image.tag=0.1.2| Workflow | File | Trigger | What it does |
|---|---|---|---|
| CI | .github/workflows/ci.yml |
Push/PR to main |
Go build + test + vet, Angular build, Helm lint |
| Release | .github/workflows/release.yml |
Git tag v* |
Build + push 5 images (multi-arch), Helm chart, GitHub Release |
| Pre-Release | .github/workflows/pre-release.yml |
Manual (workflow_dispatch) |
Build images from any branch, create pre-release |
| Sync Labels | .github/workflows/sync-labels.yml |
Push to main (labels.yml changed) or manual |
Sync .github/labels.yml to GitHub repo labels |
| Auto-Label | .github/workflows/labeler.yml |
PR opened/updated | Auto-assigns labels based on changed files (.github/labeler.yml) |
If you contribute via a fork:
- Develop in your fork — push branches, open PRs against the main repo
- Merge the PR into
mainof the main repo - Tag in the main repo (not in the fork):
git tag v0.1.2 git push origin v0.1.2
Do not tag releases in your fork. The
GITHUB_TOKENin a fork cannot push images to the main repo's GHCR, and the GitHub Release would be created in the fork instead of the main repo.
Use the manual Pre-Release workflow to build and publish test images without merging to main:
- Go to Actions → Pre-Release (manual) in your repo
- Click Run workflow
- Select the branch and enter a version (e.g.
0.2.0-rc1) - Images are pushed to your repo's GHCR with that version tag
- A GitHub Pre-Release is created automatically
For testing before a release:
# Build all 5 images with tag "dev"
make images
# Build with a specific tag
make images TAG=0.2.0-rc1
# Build and push to GHCR (requires: docker login ghcr.io)
make images-push TAG=0.2.0-rc1# Backend images (multi-target Dockerfile)
docker build -t my-registry/seebom/api-gateway:test \
--target api-gateway backend/
docker build -t my-registry/seebom/parsing-worker:test \
--target parsing-worker backend/
docker build -t my-registry/seebom/ingestion-watcher:test \
--target ingestion-watcher backend/
# UI image
docker build -t my-registry/seebom/ui:test ui/The backend uses a single multi-stage Dockerfile (backend/Dockerfile) with three named targets:
golang:1.24-alpine (builder)
├── go build → /bin/ingestion-watcher
├── go build → /bin/parsing-worker
├── go build → /bin/api-gateway
└── go build → /bin/cve-refresher
alpine:3.21 (ingestion-watcher) ← FROM builder, COPY binary
alpine:3.21 (parsing-worker) ← FROM builder, COPY binary
alpine:3.21 (api-gateway) ← FROM builder, COPY binary
alpine:3.21 (cve-refresher) ← FROM builder, COPY binary
The UI uses a separate Dockerfile (ui/Dockerfile):
node:22-alpine (builder)
└── ng build → /app/dist/
nginx:1.27-alpine
└── COPY dist/ → /usr/share/nginx/html/
All runtime images run as nobody:nobody (backend) or nginx (UI) for security.
- Git tags:
v0.1.2,v0.2.0, etc. (SemVer) - Image tags:
0.1.3(withoutvprefix) +latest - Helm chart version: Matches the Git tag (auto-updated by CI)
values.yamldefaults to the latest released tag
To use a different registry, override in Helm:
helm install seebom oci://ghcr.io/seebom-labs/seebom/charts/seebom \
--set image.registry=my-registry.example.com \
--set image.repository=my-org/seebom \
--set image.tag=0.1.3Or build + push locally:
make images-push REGISTRY=my-registry.example.com REPO=my-org/seebom TAG=0.1.3