156 lines
7.4 KiB
Markdown
156 lines
7.4 KiB
Markdown
|
|
# Image Build & Push to Scaleway Registry
|
||
|
|
|
||
|
|
## Goal
|
||
|
|
Build runner profile container images from `ansible/files/dockerfiles/linux-runners/`, scan for vulnerabilities, and push to the Scaleway container registry (`a13labs` namespace).
|
||
|
|
|
||
|
|
## Decisions
|
||
|
|
|
||
|
|
| Decision | Choice | Rationale |
|
||
|
|
|---|---|---|
|
||
|
|
| Registry namespace | `a13labs` (existing) | Clean project branding |
|
||
|
|
| Tagging strategy | Git tag + SHA + latest | Full traceability and history |
|
||
|
|
| Initial scope | Runner profiles only (7 → 4) | Consolidated image-build, infra-tools, security-scan into cicd-base |
|
||
|
|
| Trivy scan severity | Warn only | Review manually, never block builds |
|
||
|
|
| Update consumers | Not this iteration | Build+push pipeline first, consumers later |
|
||
|
|
| Path filtering | In-workflow check | Gitea paths filter unreliable with tags |
|
||
|
|
| PR scanning | Disabled | Keep PR builds fast |
|
||
|
|
|
||
|
|
## Image Inventory & Dependencies
|
||
|
|
|
||
|
|
```
|
||
|
|
docker.io/gitea/runner:latest
|
||
|
|
↓
|
||
|
|
gitea-runner-base (build stage 1, pushed first)
|
||
|
|
↓
|
||
|
|
┌─────────────────────────────┐
|
||
|
|
│ cicd-base, cpp-build, go-build │ (build stage 2, all parallel)
|
||
|
|
└─────────────────────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
| Image | Dockerfile | Base |
|
||
|
|
|---|---|---|
|
||
|
|
| gitea-runner-base | `Dockerfile.gitea-runner-base` | `docker.io/gitea/runner:latest` |
|
||
|
|
| cicd-base | `Dockerfile.cicd-base` | `local/gitea-runner-base:latest` |
|
||
|
|
| cpp-build | `Dockerfile.cpp-build` | `local/gitea-runner-base:latest` |
|
||
|
|
| go-build | `Dockerfile.go-build` | `local/gitea-runner-base:latest` |
|
||
|
|
|
||
|
|
> **Note:** `image-build`, `infra-tools`, and `security-scan` runners were decommissioned and their tooling consolidated into `cicd-base`. All workflows now run on `cicd-base` or the language-specific runners (`cpp-build`, `go-build`).
|
||
|
|
|
||
|
|
## Registry Naming
|
||
|
|
|
||
|
|
Images pushed as `fr-par-2.registry.scaleway.com/a13labs/{image-name}:{tag}`
|
||
|
|
|
||
|
|
## Phases
|
||
|
|
|
||
|
|
### Phase A: Prepare CI Runner (DONE)
|
||
|
|
|
||
|
|
**Step 1 — Add build tools to `Dockerfile.cicd-base`**
|
||
|
|
|
||
|
|
DONE. Added the following packages to the existing cicd-base image:
|
||
|
|
- Build packages: `buildah`, `fuse-overlayfs`, `podman`, `shadow-uidmap`, `skopeo`, `slirp4netns`, `iptables` (from `Dockerfile.image-build`)
|
||
|
|
- Storage config: `storage.conf` (vfs driver) and `containers.conf` (from `Dockerfile.image-build`)
|
||
|
|
- Trivy binary download (from `Dockerfile.security-scan`, v0.72.0)
|
||
|
|
|
||
|
|
**Step 2 — Register updated cicd-base on Gitea runner** (DONE)
|
||
|
|
|
||
|
|
cicd-base image rebuilt on `ci-01` and Gitea runner container registration updated.
|
||
|
|
|
||
|
|
### Phase B: Scaleway IaC Changes (DONE - code changes, manual apply needed)
|
||
|
|
|
||
|
|
**Step 3 — Add CI IAM app** (`terraform/iac/scaleway/iam.tf`) - DONE
|
||
|
|
- New `scaleway_iam_application` "ci_app" with `RegistryFullAccess` permission set
|
||
|
|
- New `scaleway_iam_policy` "registry_full_access" granting ci_app registry access
|
||
|
|
- New `scaleway_iam_api_key` "ci_app_api" for ci_app credentials
|
||
|
|
|
||
|
|
**Step 4 — Add registry outputs** (`terraform/iac/scaleway/outputs.tf`) - DONE
|
||
|
|
- `registry_endpoint` — from `scaleway_registry_namespace.a13labs.endpoint`
|
||
|
|
- `ci_app_api_access_key`, `ci_app_api_secret_key` — sensitive
|
||
|
|
|
||
|
|
**Step 5 — No `sectool.env` changes needed** - DONE
|
||
|
|
The CI app resources are hardcoded, no TF_VAR mappings required.
|
||
|
|
|
||
|
|
**Step 6 — Apply and extract secrets** (MANUAL)
|
||
|
|
- Add `SCALEWAY_CI_ACCESS_KEY` and `SCALEWAY_CI_SECRET_KEY` to Bitwarden
|
||
|
|
- Run `sectool exec tofu apply` in `terraform/iac/scaleway/`
|
||
|
|
- Add `SCALEWAY_REGISTRY_ENDPOINT`, `SCALEWAY_CI_ACCESS_KEY`, `SCALEWAY_CI_SECRET_KEY` as Gitea repo secrets
|
||
|
|
|
||
|
|
### Phase C: Gitea Actions & Workflow (DONE)
|
||
|
|
|
||
|
|
**Step 7 — Create `.gitea/actions/setup-scaleway-registry/action.yml`** - DONE
|
||
|
|
Composite action that:
|
||
|
|
- Creates `~/.docker/config.json` with Scaleway registry auth
|
||
|
|
- Configures buildah storage and network settings for rootless operation
|
||
|
|
- Inputs: `registry-endpoint`, `registry-username`, `registry-password`
|
||
|
|
|
||
|
|
**Step 8 — Create `.gitea/workflows/build-and-push-images.yml`** - DONE
|
||
|
|
|
||
|
|
Jobs:
|
||
|
|
- `check-paths`: Determines if dockerfiles changed (handles push, PR, tag events)
|
||
|
|
- `auth`: Sets up registry authentication (gates on path check)
|
||
|
|
- `build-base`: Builds and pushes `gitea-runner-base`
|
||
|
|
- `build-images`: Matrix build of 6 dependent images
|
||
|
|
|
||
|
|
Tagging strategy:
|
||
|
|
- Push to main: `{sha}` + `latest`
|
||
|
|
- Push tag (v*): `{tag}` + `{sha}` + `latest`
|
||
|
|
- PR: `pr-{number}` (no scanning)
|
||
|
|
|
||
|
|
**Step 9 — Create `.gitea/workflows/weekly-image-rebuild.yml`** - DONE
|
||
|
|
Scheduled weekly (`cron: "0 6 * * 1"` — Monday 6AM):
|
||
|
|
- Same build jobs but only tag `:latest`
|
||
|
|
- Uses `--pull-always` to force rebuild against updated upstream base images
|
||
|
|
- Full Trivy scan (warn only, artifacts)
|
||
|
|
|
||
|
|
## Build Order & Dependency Resolution
|
||
|
|
|
||
|
|
Each dependent Dockerfile says `FROM local/gitea-runner-base:latest`. The workflow replaces `local/gitea-runner-base` with the full registry URL in a temp copy before building, so buildah pulls the freshly pushed base image.
|
||
|
|
|
||
|
|
## Manual Setup Checklist
|
||
|
|
|
||
|
|
Before the workflows can run successfully, complete these steps:
|
||
|
|
|
||
|
|
- [ ] Push code changes to repo (note: `registry.tf` changed `is_public` from `false` to `true` on `a13labs` namespace)
|
||
|
|
- [x] SSH to `ci-01`, rebuild `cicd-base` image locally, update Gitea runner container — DONE
|
||
|
|
- [ ] Add `SCALEWAY_CI_ACCESS_KEY` and `SCALEWAY_CI_SECRET_KEY` to Bitwarden (leave blank initially, they'll be populated after IaC apply)
|
||
|
|
- [ ] Apply Scaleway IaC: `sectool exec tofu apply` in `terraform/iac/scaleway/`
|
||
|
|
- [ ] From IaC outputs, extract `registry_endpoint`, `ci_app_api_access_key`, `ci_app_api_secret_key`
|
||
|
|
- [ ] Add as Gitea repo secrets: `SCALEWAY_REGISTRY_ENDPOINT`, `SCALEWAY_CI_ACCESS_KEY`, `SCALEWAY_CI_SECRET_KEY`
|
||
|
|
- [ ] Push a test commit touching `ansible/files/dockerfiles/linux-runners/` to trigger workflow
|
||
|
|
- [ ] Verify workflow runs and images appear in Scaleway registry
|
||
|
|
|
||
|
|
## Gitea Secrets Required
|
||
|
|
|
||
|
|
| Secret | Source | Used by |
|
||
|
|
|---|---|---|
|
||
|
|
| `SCALEWAY_REGISTRY_ENDPOINT` | IaC output `registry_endpoint` | build-and-push, weekly-rebuild |
|
||
|
|
| `SCALEWAY_CI_ACCESS_KEY` | IaC output `ci_app_api_access_key` | build-and-push, weekly-rebuild |
|
||
|
|
| `SCALEWAY_CI_SECRET_KEY` | IaC output `ci_app_api_secret_key` | build-and-push, weekly-rebuild |
|
||
|
|
|
||
|
|
## File Summary
|
||
|
|
|
||
|
|
| Action | File | Status |
|
||
|
|
|---|---|---|
|
||
|
|
| Modify | `ansible/files/dockerfiles/linux-runners/Dockerfile.cicd-base` | DONE |
|
||
|
|
| Modify | `terraform/iac/scaleway/iam.tf` | DONE |
|
||
|
|
| Modify | `terraform/iac/scaleway/outputs.tf` | DONE |
|
||
|
|
| Modify | `terraform/iac/scaleway/sectool.env` | DONE |
|
||
|
|
| Create | `.gitea/actions/setup-scaleway-registry/action.yml` | DONE |
|
||
|
|
| Create | `.gitea/workflows/build-and-push-images.yml` | DONE |
|
||
|
|
| Create | `.gitea/workflows/weekly-image-rebuild.yml` | DONE |
|
||
|
|
|
||
|
|
## Post-Iteration (NOT now)
|
||
|
|
|
||
|
|
- Update runner Dockerfiles to use registry base URLs
|
||
|
|
- Update Ansible playbooks to `pull` from registry instead of `build`
|
||
|
|
- Add PR close job to clean up `pr-{number}` tags from registry
|
||
|
|
- Expand to AI service Dockerfiles (comfyui, ollama, llamacpp variants)
|
||
|
|
|
||
|
|
## Consolidation
|
||
|
|
|
||
|
|
`image-build`, `infra-tools`, and `security-scan` runner profiles have been decommissioned. Their tooling was already absorbed into `cicd-base`:
|
||
|
|
- **image-build** tools (buildah, podman, storage config) → merged into `Dockerfile.cicd-base`
|
||
|
|
- **security-scan** tools (trivy) → merged into `Dockerfile.cicd-base`
|
||
|
|
- **infra-tools** tools (ansible, pip packages) → installed at workflow runtime via `requirements/ansible.txt`
|
||
|
|
|
||
|
|
Unused Dockerfiles removed: `Dockerfile.image-build`, `Dockerfile.infra-tools`, `Dockerfile.security-scan`
|