From a55f3823ef389e6d33f0b5c7a8fe4f34a77ea9c0 Mon Sep 17 00:00:00 2001 From: Oleks Date: Sat, 9 May 2026 22:18:57 +0300 Subject: [PATCH] Initial: Angie 1.11.3 OCI image build for aarch64 Builds via dockerTools.streamLayeredImage from nixpkgs unstable's pkgs.angie. Woodpecker pipeline pushes to git.oleks.space/oleks/angie with both -arm64 and latest-arm64 tags. Used by the kotkanagrilli.fi staging Helm chart on the kotkan node (arm64) to replace the upstream amd64-only runalsh/angie image. --- .gitignore | 1 + .woodpecker.yaml | 66 ++++++++++++++++++++++++++++++++++++++++++++ README.md | 28 +++++++++++++++++++ flake.lock | 27 ++++++++++++++++++ flake.nix | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 194 insertions(+) create mode 100644 .gitignore create mode 100644 .woodpecker.yaml create mode 100644 README.md create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b2be92b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +result diff --git a/.woodpecker.yaml b/.woodpecker.yaml new file mode 100644 index 0000000..bce7209 --- /dev/null +++ b/.woodpecker.yaml @@ -0,0 +1,66 @@ +labels: + arch: arm64 + +clone: + - name: clone + image: woodpeckerci/plugin-git + environment: + CI_NETRC_MACHINE: git.oleks.space + CI_NETRC_USERNAME: oleks + CI_NETRC_PASSWORD: + from_secret: gitea_clone_token + PLUGIN_TAGS: "false" + PLUGIN_DEPTH: "1" + +when: + - event: push + branch: [main, master] + - event: tag + ref: "refs/tags/v*" + +steps: + - name: build-and-push + image: git.oleks.space/oleks/nix-ci:latest + environment: + GITEA_CLONE_TOKEN: + from_secret: gitea_clone_token + CI_REGISTRY_TOKEN: + from_secret: registry_token + backend_options: + kubernetes: + resources: + requests: + memory: 4Gi + commands: + # Bootstrap nix substituters and netrc — same as siblings in this repo. + - echo "79.76.48.244 git.oleks.space nix-cache-upload.oleks.space" >>/etc/hosts + - | + cat >>/etc/nix/nix.conf <<'EOF' + experimental-features = nix-command flakes + trusted-substituters = https://nix-cache-mirror.oleks.space https://nix-cache-custom.oleks.space/attic-infra-cache-k3s-1 + substituters = https://nix-cache-mirror.oleks.space https://nix-cache-custom.oleks.space/attic-infra-cache-k3s-1 + trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= attic-infra-cache-k3s-1:qYSNK3DmttQXCFqn1t50qoWGtQNPRFWq9mgQjD05DeU= + EOF + - if [ -n "$GITEA_CLONE_TOKEN" ]; then echo "machine git.oleks.space login oleks password $GITEA_CLONE_TOKEN" >~/.netrc && chmod 600 ~/.netrc; fi + + # Build the image (a script that streams the OCI tar to stdout). + - nix build .#default --print-out-paths --no-link + - VERSION="$(nix eval --raw .#version | xargs cat)" + - echo "Built angie $VERSION" + + # Push to Gitea OCI registry under both the version tag and `latest-arm64`. + - mkdir -p ~/.config/containers + - | + printf '{"auths":{"git.oleks.space":{"auth":"%s"}}}\n' \ + "$(printf 'oleks:%s' "$CI_REGISTRY_TOKEN" | base64 -w0)" \ + > ~/.config/containers/auth.json + - | + nix run nixpkgs#skopeo -- copy --insecure-policy \ + --authfile ~/.config/containers/auth.json \ + docker-archive:<($(nix build .#default --print-out-paths --no-link)) \ + docker://git.oleks.space/oleks/angie:$VERSION-arm64 + - | + nix run nixpkgs#skopeo -- copy --insecure-policy \ + --authfile ~/.config/containers/auth.json \ + docker://git.oleks.space/oleks/angie:$VERSION-arm64 \ + docker://git.oleks.space/oleks/angie:latest-arm64 diff --git a/README.md b/README.md new file mode 100644 index 0000000..c9c9e20 --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# angie-arm64 + +OCI image for [Angie](https://angie.software/) (an nginx fork) on aarch64. +Upstream `runalsh/angie` only publishes amd64 images, so we rebuild from the +`pkgs.angie` package in nixpkgs and push the result to the private Gitea +registry. + +## Output + +| Tag | Pushed when | +|---|---| +| `git.oleks.space/oleks/angie:-arm64` | every successful CI run | +| `git.oleks.space/oleks/angie:latest-arm64` | every successful CI run | + +The version string comes from `pkgs.angie.version` in nixpkgs unstable; bump +the flake input to roll it forward. + +## Build locally + +```bash +nix build .#default +./result | skopeo copy docker-archive:/dev/stdin oci-archive:angie.tar +``` + +## Trigger CI + +Push to `main`/`master` or push a `v*` tag in the corresponding Gitea repo +(`oleks/angie-arm64` — match the directory name when seeding it). diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..4fe7997 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1777954456, + "narHash": "sha256-hGdgeU2Nk87RAuZyYjyDjFL6LK7dAZN5RE9+hrDTkDU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "549bd84d6279f9852cae6225e372cc67fb91a4c1", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..326a37d --- /dev/null +++ b/flake.nix @@ -0,0 +1,72 @@ +{ + description = "Angie web server (aarch64) — OCI image for Gitea registry"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + outputs = + { self, nixpkgs }: + let + system = "aarch64-linux"; + pkgs = import nixpkgs { inherit system; }; + + # nixpkgs ships angie compiled against `--prefix=/etc/angie` and + # `--http-log-path=/var/log/angie/access.log`; the package's `bin/angie` + # already knows where to look for its main config (/etc/angie/angie.conf). + angie = pkgs.angie; + + # Stock main config: turns on http and includes whatever drop-ins the + # chart mounts at /etc/angie/http.d/*.conf — same idiom as the alpine + # nginx image's /etc/nginx/conf.d/. + mainConf = pkgs.writeText "angie.conf" '' + worker_processes auto; + error_log /var/log/angie/error.log notice; + pid /run/angie.pid; + + events { worker_connections 1024; } + + http { + include ${angie}/conf/mime.types; + default_type application/octet-stream; + + sendfile on; + keepalive_timeout 65; + + access_log /var/log/angie/access.log; + + include /etc/angie/http.d/*.conf; + } + ''; + + image = pkgs.dockerTools.streamLayeredImage { + name = "angie"; + tag = angie.version; + contents = with pkgs; [ + angie + cacert + dockerTools.fakeNss + coreutils + bash + ]; + # Writable runtime dirs — image filesystem is otherwise read-only. + extraCommands = '' + mkdir -p var/log/angie var/cache/angie var/lib/angie run tmp etc/angie/http.d + chmod 1777 tmp + cp ${mainConf} etc/angie/angie.conf + ''; + config = { + Entrypoint = [ "${angie}/bin/angie" ]; + Cmd = [ "-g" "daemon off;" ]; + ExposedPorts = { "80/tcp" = { }; }; + WorkingDir = "/etc/angie"; + }; + }; + in + { + packages.${system} = { + default = image; + # Plain text file containing just the version string — read by CI to + # produce the registry tag without re-evaluating the flake. + version = pkgs.writeText "angie-version" angie.version; + }; + }; +}