A full-stack demo application (React frontend + Express backend) designed to be packaged and deployed on air-gapped Kubernetes clusters using Zarf.
The repository covers the complete lifecycle: local development, container image publishing to AWS ECR, Zarf packaging in CI, and deployment to a k3s cluster with no external connectivity required at deploy time.
├── backend/ Express.js REST API
├── frontend/ React (Vite) single-page app
├── helm/airgapped-demo/ Helm chart (deployed by Zarf)
├── terraform/ AWS infrastructure (ECR, IAM, OIDC)
├── .github/workflows/ CI/CD pipelines
├── zarf.yaml Zarf package definition
├── Makefile Local development targets
├── ZARF.md Air-gap packaging & deployment guide
├── CI.md CI/CD pipeline reference
└── SETUP.md Initial infrastructure setup guide
docker compose up
# Frontend: http://localhost:5173
# Backend: http://localhost:3001/api/healthmake registry # start local Docker registry on localhost:5001
make package-local # build images → push → create Zarf tarball
make deploy # deploy to k3s cluster + post-deploy fixesSee ZARF.md for the complete local and USB air-gap workflow.
| Workflow | Trigger | What it does |
|---|---|---|
| Build & Push Images | push to main |
Builds frontend + backend images, pushes to ECR with tag sha-<7char> |
| Zarf Package | after Build & Push succeeds | Creates a .tar.zst bundle with images + Helm chart; uploads as a GitHub Actions artifact |
| Deploy | after Zarf Package succeeds | Downloads the bundle, deploys to the k3s cluster, verifies running tags match |
See CI.md for secrets, permissions, and pipeline details.
| Method | Path | Description |
|---|---|---|
GET |
/api/health |
Health check — returns status, version, timestamp |
GET |
/api/info |
Runtime info — app name, version, hostname, environment |
GET |
/api/items |
Sample item list |
Managed with Terraform in terraform/. Resources:
| Resource | Purpose |
|---|---|
| ECR repositories | airgapped-demo/backend, airgapped-demo/frontend |
| IAM OIDC provider | Federated identity for GitHub Actions |
| IAM roles | cicd (push images, no long-lived credentials) |
See SETUP.md for provisioning steps.
The Zarf bundle (~66 MB) is self-contained — it embeds the container images and the Helm chart. The target cluster requires no internet access or ECR credentials at deploy time.
For offline delivery to a machine with no internet access, see ZARF.md § Air-Gap USB Deployment.