From e6176999c177231e64f244420db39b6fa6e34508 Mon Sep 17 00:00:00 2001 From: Andriy Oblivantsev Date: Thu, 19 Feb 2026 21:19:31 +0000 Subject: [PATCH] Add containerisation strategy details and CI image build step Expand architecture doc section 4.5 with image building process, container registry management, and deployment pipeline prose. Add Docker build & push to Gitea OCI registry in CI workflow. Co-authored-by: Cursor --- .github/workflows/release.yaml | 11 ++++++ .gitignore | 1 + docs/architecture-design-company-inc.md | 50 +++++++++++++++++++++++-- docs/architecture-hld.md | 4 +- 4 files changed, 61 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 06b3ef5..55b60d5 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -121,6 +121,17 @@ jobs: mv fleetdm-stack-*.tgz .tmp/ ls -la .tmp/ + - name: Build and push container image + run: | + TAG="${{ steps.version.outputs.new_tag }}" + IMAGE="git.produktor.io/${{ gitea.repository }}/fleetdm-stack" + + echo "${{ gitea.token }}" | docker login git.produktor.io -u "${{ gitea.actor }}" --password-stdin + docker build -t "${IMAGE}:${TAG}" -t "${IMAGE}:latest" . + docker push "${IMAGE}:${TAG}" + docker push "${IMAGE}:latest" + echo "Pushed ${IMAGE}:${TAG}" + - name: Create tag run: | git config user.name "Gitea Actions" diff --git a/.gitignore b/.gitignore index 57ee6b1..e39bbed 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ fleetdm-stack/charts/*.tgz .helm/ *.log /*-flamingo +.idea diff --git a/docs/architecture-design-company-inc.md b/docs/architecture-design-company-inc.md index e742976..ad448cf 100644 --- a/docs/architecture-design-company-inc.md +++ b/docs/architecture-design-company-inc.md @@ -125,13 +125,55 @@ flowchart LR **Cost impact:** Near-zero — both slots share the same node pool; the idle slot consumes minimal resources until traffic is switched. Argo Rollouts automates the full lifecycle within ArgoCD. -### 4.5 Containerisation and CI/CD +### 4.5 Containerisation Strategy + +#### Image Building Process + +Each service (Flask backend, React frontend) has its own **multi-stage Dockerfile**: + +1. **Build stage** — installs dependencies and compiles artefacts in a full SDK image (e.g. `python:3.12`, `node:20`). +2. **Runtime stage** — copies only the built artefacts into a minimal base image (e.g. `python:3.12-slim`, `nginx:alpine`). This cuts image size by 60–80% and removes build tools from the attack surface. +3. **Non-root user** — the runtime stage runs as a dedicated unprivileged user (`appuser`), never as root. +4. **Reproducible builds** — dependency lock files (`requirements.txt` / `package-lock.json`) are copied and installed before application code to maximise Docker layer caching. + +**Tagging convention:** images are tagged with the **git SHA** for traceability and a `latest` alias for convenience. Semantic version tags (e.g. `v1.3.0`) are added on release. + +#### Container Registry Management + +All container images are stored in **GCP Artifact Registry** in the `company-inc-shared` project: + +- **Single source of truth** — one registry serves both staging and production via cross-project IAM pull permissions. +- **Vulnerability scanning** — Artifact Registry's built-in scanning is enabled; CI fails if critical CVEs are detected. +- **Image retention policy** — keep the latest 10 tagged images per service; automatically garbage-collect untagged manifests older than 30 days. +- **Access control** — CI service account has `roles/artifactregistry.writer`; GKE node service accounts have `roles/artifactregistry.reader`. No human push access. + +*For self-hosted Git platforms (e.g. Gitea), the built-in OCI container registry can serve the same role at zero additional cost, with Trivy added as a CI step for vulnerability scanning.* + +#### Deployment Pipelines (CI/CD Integration) + +The pipeline follows a **GitOps** model with clear separation between CI and CD: + +| Phase | Tool | What happens | +|-------|------|-------------| +| **Lint & Test** | Gitea / GitHub Actions | Unit tests, linting, Helm lint on every push | +| **Build & Push** | Gitea / GitHub Actions | `docker build` → tag with git SHA → push to registry | +| **Security Scan** | Trivy (in CI) | Scan image for OS and library CVEs; block on critical findings | +| **Manifest Update** | CI job | Update image tag in the GitOps manifests repo (or Helm values) | +| **Sync & Deploy** | ArgoCD | Detects manifest drift → triggers blue-green rollout via Argo Rollouts | +| **Promotion** | Argo Rollouts | Automated analysis (metrics, health checks) → promote or rollback | + +**Key properties:** +- **CI never touches the cluster directly** — it only builds images and updates manifests. ArgoCD is the sole deployer. +- **Rollback is instant** — revert the manifest repo to the previous commit; ArgoCD syncs automatically. +- **Audit trail** — every deployment maps to a git commit in the manifests repo. + +### 4.6 CI/CD Summary | Aspect | Approach | |-------|----------| -| **Image build** | Dockerfile per service; multi-stage builds; non-root user | -| **Registry** | Artifact Registry in `company-inc-shared` | -| **CI** | GitHub/Gitea Actions — build, test, security scan | +| **Image build** | Multi-stage Dockerfile; layer caching; non-root; git-SHA tags | +| **Registry** | Artifact Registry in `company-inc-shared` (or Gitea built-in OCI registry) | +| **CI** | Gitea / GitHub Actions — lint, test, build, scan, push | | **CD** | ArgoCD + Argo Rollouts — GitOps with blue-green strategy | | **Secrets** | External Secrets Operator + GCP Secret Manager | diff --git a/docs/architecture-hld.md b/docs/architecture-hld.md index 0ddba03..f1066a5 100644 --- a/docs/architecture-hld.md +++ b/docs/architecture-hld.md @@ -94,10 +94,12 @@ flowchart LR flowchart LR Dev[Developer] -->|push| Repo[Git Repo] Repo -->|webhook| CI[CI Pipeline
lint · test · build] - CI -->|push image| Registry[Artifact Registry] + CI -->|docker build + push| Registry[Container Registry
Artifact Registry / Gitea OCI] + CI -->|scan image| Trivy[Trivy
CVE scan] CI -->|update manifests| GitOps[GitOps Repo] GitOps -->|sync| Argo[ArgoCD] Argo -->|blue-green deploy| GKE[GKE Cluster] + GKE -->|pull image| Registry ``` ## Network Security Layers