Nix container build for nettest (#214)
## Summary - Add `containers/nettest/default.nix` using `dockerTools.buildLayeredImage` with curl, jq, dnsutils, cacert, and bash — equivalent to the existing Dockerfile - Update `container-tag-and-release` to require `--nix` or `--dockerfile` flag when both build types exist for a container - Update `container-list` to show `[dockerfile+nix]` label when both exist ## Deployment and Testing - [ ] SSH to ringtail, run `nix build -f containers/nettest/default.nix -o result` to verify the nix expression builds - [ ] Tag `nettest-nix-v1.0.0`, confirm `build-container-nix` workflow runs on `nix-container-builder` runner and pushes to registry - [ ] Smoke test on ringtail k3s: `kubectl run nettest --image=registry.ops.eblu.me/blumeops/nettest:v1.0.0 --restart=Never && kubectl logs nettest` - [ ] Verify `mise run container-list` shows `[dockerfile+nix]` for nettest - [ ] Verify `mise run container-tag-and-release nettest v1.1.0` prompts for build type Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/214
This commit is contained in:
parent
b475a1fcd7
commit
695089499e
10 changed files with 244 additions and 130 deletions
|
|
@ -1,17 +1,17 @@
|
|||
# Nix container build workflow
|
||||
# Triggers on tags matching: <container>-nix-v<version>
|
||||
# Builds from containers/<container>/default.nix using nix build
|
||||
# Pushes to Zot registry via skopeo
|
||||
# Triggers on tags matching: <container>-v<version>
|
||||
# Builds from containers/<container>/default.nix if it exists, skips otherwise
|
||||
# Pushes to Zot registry via skopeo with -nix image tag suffix
|
||||
#
|
||||
# Examples:
|
||||
# nettest-nix-v1.0.0 -> builds containers/nettest/default.nix
|
||||
# myapp-nix-v2.1.0 -> builds containers/myapp/default.nix
|
||||
# nettest-v1.0.0 -> builds containers/nettest/default.nix, pushes :v1.0.0-nix
|
||||
# devpi-v2.1.0 -> skips (no default.nix)
|
||||
name: Build Container (Nix)
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*-nix-v[0-9]*'
|
||||
- '*-v[0-9]*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
|
@ -23,10 +23,10 @@ jobs:
|
|||
TAG="${GITHUB_REF_NAME}"
|
||||
echo "Tag: $TAG"
|
||||
|
||||
# Extract container name (everything before -nix-v)
|
||||
# e.g., "nettest-nix-v1.0.0" -> "nettest"
|
||||
CONTAINER="${TAG%-nix-v[0-9]*}"
|
||||
VERSION="${TAG#"${CONTAINER}"-nix-}"
|
||||
# Extract container name (everything before -v)
|
||||
# e.g., "nettest-v1.0.0" -> "nettest", "my-app-v2.0.0" -> "my-app"
|
||||
CONTAINER="${TAG%-v[0-9]*}"
|
||||
VERSION="${TAG#"${CONTAINER}"-}"
|
||||
|
||||
echo "container=$CONTAINER" >> "$GITHUB_OUTPUT"
|
||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
|
|
@ -46,33 +46,29 @@ jobs:
|
|||
echo "Found $CONTEXT/default.nix"
|
||||
echo "exists=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "No default.nix found at $CONTEXT/default.nix"
|
||||
echo "No default.nix found at $CONTEXT/default.nix — skipping"
|
||||
echo "exists=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Skip if container not found
|
||||
if: steps.check.outputs.exists != 'true'
|
||||
- name: Resolve nixpkgs
|
||||
if: steps.check.outputs.exists == 'true'
|
||||
id: nixpkgs
|
||||
run: |
|
||||
echo "========================================"
|
||||
echo "Nix container not found: ${{ steps.parse.outputs.container }}"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
echo "Tag '${{ github.ref_name }}' does not match any nix container in containers/"
|
||||
echo ""
|
||||
echo "Available nix containers:"
|
||||
for nix in containers/*/default.nix; do
|
||||
[ -f "$nix" ] && echo " - $(basename "$(dirname "$nix")")"
|
||||
done
|
||||
echo ""
|
||||
echo "Skipping build."
|
||||
# Resolve nixpkgs from the flake registry for <nixpkgs> lookup
|
||||
NIXPKGS_PATH=$(nix flake metadata nixpkgs --json | jq -r '.path')
|
||||
echo "Resolved nixpkgs: $NIXPKGS_PATH"
|
||||
echo "path=$NIXPKGS_PATH" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Build with nix
|
||||
if: steps.check.outputs.exists == 'true'
|
||||
id: build
|
||||
env:
|
||||
NIX_PATH: "nixpkgs=${{ steps.nixpkgs.outputs.path }}"
|
||||
run: |
|
||||
CONTAINER="${{ steps.parse.outputs.container }}"
|
||||
echo "Building containers/$CONTAINER/default.nix"
|
||||
nix build -f "containers/$CONTAINER/default.nix" -o result
|
||||
echo "NIX_PATH=$NIX_PATH"
|
||||
nix-build "containers/$CONTAINER/default.nix" -o result
|
||||
echo "Build complete: $(readlink result)"
|
||||
|
||||
- name: Push to registry
|
||||
|
|
@ -80,7 +76,7 @@ jobs:
|
|||
run: |
|
||||
CONTAINER="${{ steps.parse.outputs.container }}"
|
||||
VERSION="${{ steps.parse.outputs.version }}"
|
||||
IMAGE="registry.ops.eblu.me/blumeops/$CONTAINER:$VERSION"
|
||||
IMAGE="registry.ops.eblu.me/blumeops/$CONTAINER:$VERSION-nix"
|
||||
|
||||
echo "Pushing to $IMAGE"
|
||||
skopeo copy \
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ on:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
if: "!contains(github.ref_name, '-nix-v')"
|
||||
runs-on: k8s
|
||||
steps:
|
||||
- name: Parse tag
|
||||
|
|
|
|||
39
containers/nettest/default.nix
Normal file
39
containers/nettest/default.nix
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# Nix-built nettest container
|
||||
# Equivalent to the Dockerfile: curl, jq, bind (nslookup), ca-certs, bash
|
||||
# Built with dockerTools.buildLayeredImage for efficient layer caching
|
||||
{ pkgs ? import <nixpkgs> { } }:
|
||||
|
||||
let
|
||||
testScript = ./test-connectivity.sh;
|
||||
|
||||
tools = pkgs.buildEnv {
|
||||
name = "nettest-tools";
|
||||
paths = [
|
||||
pkgs.curl
|
||||
pkgs.jq
|
||||
pkgs.dnsutils # provides nslookup, dig
|
||||
pkgs.cacert
|
||||
pkgs.coreutils
|
||||
pkgs.hostname
|
||||
pkgs.bashInteractive
|
||||
];
|
||||
};
|
||||
in
|
||||
pkgs.dockerTools.buildLayeredImage {
|
||||
name = "blumeops/nettest";
|
||||
tag = "latest";
|
||||
|
||||
contents = [ tools ];
|
||||
|
||||
extraCommands = ''
|
||||
cp ${testScript} test-connectivity.sh
|
||||
chmod +x test-connectivity.sh
|
||||
'';
|
||||
|
||||
config = {
|
||||
Entrypoint = [ "/bin/bash" "/test-connectivity.sh" ];
|
||||
Env = [
|
||||
"SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
Added Nix container build for nettest, validating the full nix-container-builder pipeline on ringtail. One git tag now triggers both Dockerfile and Nix workflows — each skips if its build file is absent. Rewrote container-tag-and-release as a typer CLI with --dry-run support. Added container policy.json and registries.conf to ringtail for skopeo.
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: Build Container Image
|
||||
modified: 2026-02-15
|
||||
modified: 2026-02-19
|
||||
last-reviewed: 2026-02-15
|
||||
tags:
|
||||
- how-to
|
||||
|
|
@ -14,30 +14,35 @@ How to create a custom container image in BlumeOps, build it locally, and releas
|
|||
|
||||
## Prerequisites
|
||||
|
||||
- [Dagger CLI](https://docs.dagger.io/install) installed locally
|
||||
- A Dockerfile for the service you want to build
|
||||
- [Dagger CLI](https://docs.dagger.io/install) installed locally (for Dockerfile builds)
|
||||
- A `Dockerfile` and/or `default.nix` for the service
|
||||
|
||||
## 1. Create the container directory
|
||||
|
||||
Add a `Dockerfile` (and any supporting files) under `containers/<name>/`:
|
||||
Add build files under `containers/<name>/`:
|
||||
|
||||
```
|
||||
containers/<name>/
|
||||
├── Dockerfile
|
||||
├── Dockerfile (built by Dagger on the k8s runner)
|
||||
├── default.nix (built by nix-build on the ringtail runner)
|
||||
└── (optional scripts, configs)
|
||||
```
|
||||
|
||||
The directory name becomes the image name: `registry.ops.eblu.me/blumeops/<name>`.
|
||||
A container can have one or both build files. The directory name becomes the image name: `registry.ops.eblu.me/blumeops/<name>`.
|
||||
|
||||
## 2. Build locally
|
||||
|
||||
Test your image with Dagger:
|
||||
**Dockerfile** — test with Dagger:
|
||||
|
||||
```bash
|
||||
dagger call build --src=. --container-name=<name>
|
||||
```
|
||||
|
||||
This builds `containers/<name>/Dockerfile` using the Dagger `docker_build()` function. Fix any build errors before proceeding.
|
||||
**Nix** — test with nix-build (requires nix, e.g. on [[ringtail]]):
|
||||
|
||||
```bash
|
||||
nix-build containers/<name>/default.nix -o result
|
||||
```
|
||||
|
||||
## 3. Release
|
||||
|
||||
|
|
@ -47,7 +52,14 @@ Once the image builds cleanly, create a tagged release:
|
|||
mise run container-tag-and-release <name> v1.0.0
|
||||
```
|
||||
|
||||
This creates a git tag `<name>-v1.0.0` and pushes it. The `build-container` Forgejo workflow triggers on the tag, builds the image via Dagger, and publishes it to the registry as `registry.ops.eblu.me/blumeops/<name>:v1.0.0`.
|
||||
Use `--dry-run` to preview without creating tags.
|
||||
|
||||
This creates a single git tag `<name>-v1.0.0` and pushes it. Both Forgejo workflows trigger on the tag — each checks for its build file and skips if not present:
|
||||
|
||||
| Build file | Workflow | Runner | Registry tag |
|
||||
|------------|----------|--------|--------------|
|
||||
| `Dockerfile` | `build-container.yaml` | `k8s` (indri) | `:v1.0.0` |
|
||||
| `default.nix` | `build-container-nix.yaml` | `nix-container-builder` ([[ringtail]]) | `:v1.0.0-nix` |
|
||||
|
||||
Check available images and tags with:
|
||||
|
||||
|
|
@ -76,6 +88,7 @@ Existing containers demonstrate several build approaches:
|
|||
| Multi-stage with Node + Go | [[#navidrome]] | Separate UI and backend build stages |
|
||||
| Multi-stage Elixir | [[#teslamate]] | Elixir release with Node assets |
|
||||
| Runtime tarball download | [[#kiwix-serve]] | Download pre-built binary with arch detection |
|
||||
| Nix `dockerTools` | [[#nettest-nix]] | `buildLayeredImage` with nixpkgs tools |
|
||||
|
||||
### transmission
|
||||
|
||||
|
|
@ -97,6 +110,10 @@ Existing containers demonstrate several build approaches:
|
|||
|
||||
`containers/kiwix-serve/Dockerfile` — Downloads a pre-built binary from upstream, with architecture detection for cross-platform support.
|
||||
|
||||
### nettest (nix)
|
||||
|
||||
`containers/nettest/default.nix` — Uses `dockerTools.buildLayeredImage` with `buildEnv` to merge nixpkgs tools (curl, jq, dnsutils, bash). Runs alongside the existing Dockerfile; the nix variant is tagged `:version-nix` in the registry.
|
||||
|
||||
## Related
|
||||
|
||||
- [[deploy-k8s-service]] — Deploying the service that uses the image
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: Ringtail
|
||||
modified: 2026-02-18
|
||||
modified: 2026-02-19
|
||||
tags:
|
||||
- infrastructure
|
||||
- host
|
||||
|
|
@ -81,7 +81,7 @@ argocd cluster add default --name k3s-ringtail
|
|||
|
||||
### Forgejo Actions Runner
|
||||
|
||||
A native Forgejo Actions runner (`ringtail-nix-builder`) runs as a systemd service via the NixOS `services.gitea-actions-runner` module. It builds containers using `nix build` and pushes them to Zot via `skopeo`.
|
||||
A native Forgejo Actions runner (`ringtail-nix-builder`) runs as a systemd service via the NixOS `services.gitea-actions-runner` module. It builds containers using `nix-build` and pushes them to Zot via `skopeo`.
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
|
|
@ -89,6 +89,9 @@ A native Forgejo Actions runner (`ringtail-nix-builder`) runs as a systemd servi
|
|||
| **Execution** | Host (no containers) |
|
||||
| **Token** | `/etc/forgejo-runner/token.env` (provisioned by Ansible) |
|
||||
| **Service unit** | `gitea-runner-nix_container_builder.service` |
|
||||
| **Host packages** | bash, coreutils, curl, gawk, git, gnused, jq, nodejs, wget, nix, skopeo |
|
||||
|
||||
The runner resolves `<nixpkgs>` from the flake registry at build time. Container trust policy (`/etc/containers/policy.json`) and registry search order (`/etc/containers/registries.conf`) are configured minimally in `configuration.nix` for skopeo — no full `virtualisation.containers` module needed.
|
||||
|
||||
## Maintenance Notes
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: Forgejo
|
||||
modified: 2026-02-08
|
||||
modified: 2026-02-19
|
||||
tags:
|
||||
- service
|
||||
- git
|
||||
|
|
@ -31,15 +31,20 @@ Git forge and CI/CD platform. **Primary source of truth for blumeops** (mirrored
|
|||
|
||||
## CI/CD (Forgejo Actions)
|
||||
|
||||
**Runner:** Kubernetes pod with Docker-in-Docker sidecar
|
||||
- Namespace: `forgejo-runner`
|
||||
- Labels: `k8s`
|
||||
- ArgoCD app: `forgejo-runner`
|
||||
**Runners:**
|
||||
|
||||
| Runner | Host | Labels | Purpose |
|
||||
|--------|------|--------|---------|
|
||||
| k8s DinD pod | [[indri]] (minikube) | `k8s` | Dockerfile builds via Dagger |
|
||||
| ringtail-nix-builder | [[ringtail]] (native) | `nix-container-builder` | Nix builds via `nix-build` + `skopeo` |
|
||||
|
||||
**Workflows:** `.forgejo/workflows/`
|
||||
- `build-container.yaml` - Container image builds on tag
|
||||
- `build-container.yaml` - Dockerfile builds on tag (runs on `k8s`)
|
||||
- `build-container-nix.yaml` - Nix builds on tag (runs on `nix-container-builder`)
|
||||
- `build-blumeops.yaml` - Documentation builds and releases
|
||||
|
||||
Both container workflows trigger on the same tag pattern (`*-v[0-9]*`). Each checks for its build file (`Dockerfile` or `default.nix`) and skips if not present. See [[build-container-image]].
|
||||
|
||||
## Secrets (Forgejo Config)
|
||||
|
||||
Server configuration secrets managed via 1Password → Ansible:
|
||||
|
|
|
|||
|
|
@ -14,20 +14,26 @@ echo ""
|
|||
for dir in "$CONTAINER_DIR"/*/; do
|
||||
[[ -d "$dir" ]] || continue
|
||||
|
||||
# Determine build type
|
||||
if [[ -f "$dir/default.nix" ]]; then
|
||||
build_type="nix"
|
||||
elif [[ -f "$dir/Dockerfile" ]]; then
|
||||
build_type="dockerfile"
|
||||
else
|
||||
continue
|
||||
fi
|
||||
# Determine available build types
|
||||
has_dockerfile=false
|
||||
has_nix=false
|
||||
[[ -f "$dir/Dockerfile" ]] && has_dockerfile=true
|
||||
[[ -f "$dir/default.nix" ]] && has_nix=true
|
||||
|
||||
# Skip directories with no build files
|
||||
$has_dockerfile || $has_nix || continue
|
||||
|
||||
# Build type label
|
||||
types=()
|
||||
$has_dockerfile && types+=("dockerfile")
|
||||
$has_nix && types+=("nix")
|
||||
label=$(IFS=+; echo "${types[*]}")
|
||||
|
||||
# Extract container name from directory
|
||||
container=$(basename "$dir")
|
||||
image="blumeops/$container"
|
||||
|
||||
echo "[$build_type] $container"
|
||||
echo "[$label] $container"
|
||||
echo " Image: $REGISTRY/$image"
|
||||
echo " Path: $dir"
|
||||
|
||||
|
|
@ -49,5 +55,7 @@ echo "---"
|
|||
echo "To release a new version:"
|
||||
echo " mise run container-tag-and-release <container> <version>"
|
||||
echo ""
|
||||
echo "One tag triggers all applicable workflows (dockerfile and/or nix)."
|
||||
echo ""
|
||||
echo "Example:"
|
||||
echo " mise run container-tag-and-release nettest v1.0.0"
|
||||
|
|
|
|||
|
|
@ -1,77 +1,114 @@
|
|||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env -S uv run --script
|
||||
# /// script
|
||||
# requires-python = ">=3.12"
|
||||
# dependencies = ["typer>=0.15.0"]
|
||||
# ///
|
||||
#MISE description="Release a container image by creating a git tag"
|
||||
#USAGE arg "<container>" help="Container name (directory under containers/)"
|
||||
#USAGE arg "<version>" help="Version in vX.Y.Z format"
|
||||
#USAGE flag "--dry-run" help="Show what would be done without creating tags"
|
||||
"""Release a container image by creating a git tag that triggers CI builds.
|
||||
|
||||
set -euo pipefail
|
||||
One tag triggers all applicable workflows:
|
||||
- Dockerfile present -> Build Container workflow -> :v<version>
|
||||
- default.nix present -> Build Container (Nix) workflow -> :v<version>-nix
|
||||
"""
|
||||
|
||||
CONTAINER="${1:-}"
|
||||
VERSION="${2:-}"
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
if [[ -z "$CONTAINER" || -z "$VERSION" ]]; then
|
||||
echo "Usage: mise run container-tag-and-release <container> <version>"
|
||||
echo ""
|
||||
echo "Run 'mise run container-list' to see available containers and recent tags."
|
||||
exit 1
|
||||
fi
|
||||
import typer
|
||||
|
||||
# Validate version format
|
||||
if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "Error: Version must be in format vX.Y.Z (e.g. v1.0.0)"
|
||||
exit 1
|
||||
fi
|
||||
REGISTRY = "registry.ops.eblu.me"
|
||||
FORGE_ACTIONS = "https://forge.ops.eblu.me/eblume/blumeops/actions"
|
||||
|
||||
# Determine build type: Nix or Dockerfile
|
||||
CONTAINER_DIR="containers/${CONTAINER}"
|
||||
if [[ -f "$CONTAINER_DIR/default.nix" ]]; then
|
||||
BUILD_TYPE="nix"
|
||||
TAG="${CONTAINER}-nix-${VERSION}"
|
||||
elif [[ -f "$CONTAINER_DIR/Dockerfile" ]]; then
|
||||
BUILD_TYPE="dockerfile"
|
||||
TAG="${CONTAINER}-${VERSION}"
|
||||
else
|
||||
echo "Error: No Dockerfile or default.nix found in '$CONTAINER_DIR'"
|
||||
echo ""
|
||||
echo "Available containers:"
|
||||
for dir in containers/*/; do
|
||||
[[ -d "$dir" ]] || continue
|
||||
name=$(basename "$dir")
|
||||
if [[ -f "$dir/default.nix" ]]; then
|
||||
echo " - $name (nix)"
|
||||
elif [[ -f "$dir/Dockerfile" ]]; then
|
||||
echo " - $name (dockerfile)"
|
||||
fi
|
||||
done
|
||||
exit 1
|
||||
fi
|
||||
app = typer.Typer(add_completion=False)
|
||||
|
||||
echo "Creating release tag: $TAG"
|
||||
echo "Build type: $BUILD_TYPE"
|
||||
echo ""
|
||||
|
||||
# Check if tag already exists
|
||||
if git rev-parse "$TAG" >/dev/null 2>&1; then
|
||||
echo "Error: Tag '$TAG' already exists"
|
||||
echo "Existing tags for $CONTAINER:"
|
||||
git tag -l "${CONTAINER}-*v*" | sort -V | tail -5
|
||||
exit 1
|
||||
fi
|
||||
def git(*args: str) -> str:
|
||||
result = subprocess.run(
|
||||
["git", *args], capture_output=True, text=True, check=True
|
||||
)
|
||||
return result.stdout.strip()
|
||||
|
||||
# Image name follows convention: blumeops/<container>
|
||||
IMAGE="blumeops/${CONTAINER}"
|
||||
|
||||
echo "Container: $CONTAINER"
|
||||
echo "Directory: $CONTAINER_DIR"
|
||||
echo "Image: registry.ops.eblu.me/$IMAGE:$VERSION"
|
||||
echo ""
|
||||
def git_tag_exists(tag: str) -> bool:
|
||||
result = subprocess.run(
|
||||
["git", "rev-parse", tag], capture_output=True, text=True
|
||||
)
|
||||
return result.returncode == 0
|
||||
|
||||
# Create and push tag
|
||||
git tag "$TAG"
|
||||
git push origin "$TAG"
|
||||
|
||||
echo ""
|
||||
echo "Tag '$TAG' created and pushed"
|
||||
echo ""
|
||||
echo "The workflow will now build and push:"
|
||||
echo " registry.ops.eblu.me/$IMAGE:$VERSION"
|
||||
echo ""
|
||||
echo "Monitor the build at:"
|
||||
echo " https://forge.ops.eblu.me/eblume/blumeops/actions"
|
||||
def list_containers() -> None:
|
||||
typer.echo("Available containers:")
|
||||
for d in sorted(Path("containers").iterdir()):
|
||||
if not d.is_dir():
|
||||
continue
|
||||
types = []
|
||||
if (d / "Dockerfile").exists():
|
||||
types.append("dockerfile")
|
||||
if (d / "default.nix").exists():
|
||||
types.append("nix")
|
||||
if types:
|
||||
typer.echo(f" - {d.name} ({', '.join(types)})")
|
||||
|
||||
|
||||
@app.command()
|
||||
def main(
|
||||
container: str = typer.Argument(help="Container name (directory under containers/)"),
|
||||
version: str = typer.Argument(help="Version in vX.Y.Z format"),
|
||||
dry_run: bool = typer.Option(False, "--dry-run", help="Show what would be done without creating tags"),
|
||||
) -> None:
|
||||
"""Release a container image by creating a git tag that triggers CI builds."""
|
||||
if not re.match(r"^v\d+\.\d+\.\d+$", version):
|
||||
typer.echo("Error: Version must be in format vX.Y.Z (e.g. v1.0.0)")
|
||||
raise typer.Exit(1)
|
||||
|
||||
container_dir = Path("containers") / container
|
||||
has_dockerfile = (container_dir / "Dockerfile").exists()
|
||||
has_nix = (container_dir / "default.nix").exists()
|
||||
|
||||
if not has_dockerfile and not has_nix:
|
||||
typer.echo(f"Error: No Dockerfile or default.nix found in '{container_dir}'")
|
||||
typer.echo()
|
||||
list_containers()
|
||||
raise typer.Exit(1)
|
||||
|
||||
image = f"blumeops/{container}"
|
||||
tag = f"{container}-{version}"
|
||||
|
||||
# Show what workflows will trigger
|
||||
builds = []
|
||||
if has_dockerfile:
|
||||
builds.append(f" dockerfile -> {REGISTRY}/{image}:{version}")
|
||||
if has_nix:
|
||||
builds.append(f" nix -> {REGISTRY}/{image}:{version}-nix")
|
||||
|
||||
if dry_run:
|
||||
typer.echo("[dry-run mode]")
|
||||
typer.echo(f"Container: {container}")
|
||||
typer.echo(f"Tag: {tag}")
|
||||
typer.echo(f"Builds:")
|
||||
for b in builds:
|
||||
typer.echo(b)
|
||||
typer.echo()
|
||||
|
||||
if git_tag_exists(tag):
|
||||
typer.echo(f"Error: Tag '{tag}' already exists")
|
||||
raise typer.Exit(1)
|
||||
|
||||
if dry_run:
|
||||
typer.echo(f"[dry-run] Would create and push tag: {tag}")
|
||||
else:
|
||||
git("tag", tag)
|
||||
git("push", "origin", tag)
|
||||
typer.echo(f"Tag '{tag}' created and pushed")
|
||||
|
||||
typer.echo()
|
||||
typer.echo(f"Monitor builds at: {FORGE_ACTIONS}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app()
|
||||
|
|
|
|||
|
|
@ -446,6 +446,15 @@ in
|
|||
"d /mnt/storage2 0755 eblume users -"
|
||||
];
|
||||
|
||||
# Container config for skopeo (used by the forgejo runner to push images)
|
||||
# and for unqualified image pulls via Zot pull-through cache
|
||||
environment.etc."containers/policy.json".text = builtins.toJSON {
|
||||
default = [{ type = "insecureAcceptAnything"; }];
|
||||
};
|
||||
environment.etc."containers/registries.conf".text = ''
|
||||
unqualified-search-registries = ["registry.ops.eblu.me", "docker.io", "ghcr.io", "quay.io"]
|
||||
'';
|
||||
|
||||
# Forgejo Actions runner (nix container builder)
|
||||
services.gitea-actions-runner = {
|
||||
package = pkgs.forgejo-runner;
|
||||
|
|
@ -456,7 +465,7 @@ in
|
|||
tokenFile = "/etc/forgejo-runner/token.env";
|
||||
labels = [ "nix-container-builder:host" ];
|
||||
hostPackages = with pkgs; [
|
||||
bash coreutils curl gawk gitMinimal gnused nodejs wget
|
||||
bash coreutils curl gawk gitMinimal gnused jq nodejs wget
|
||||
nix skopeo
|
||||
];
|
||||
settings = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue