{ description = "Angie web server (aarch64) — OCI image for Gitea registry"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; nix2container.url = "github:nlewo/nix2container"; nix2container.inputs.nixpkgs.follows = "nixpkgs"; parity.url = "git+https://git.oleks.space/oleks/parity-lib"; }; outputs = { nixpkgs, nix2container, parity, ... }: let system = "aarch64-linux"; pkgs = import nixpkgs { inherit system; }; n2c = nix2container.packages.${system}.nix2container; # 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). inherit (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" '' # Run as root in the container — fakeNss doesn't ship a "nogroup" # group, which is the compiled-in default group for this angie build, # and the worker would refuse to start otherwise. user root; worker_processes auto; error_log /var/log/nginx/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/nginx/access.log; include /etc/angie/http.d/*.conf; } ''; # The image root extra: /etc/angie (the bundled conf-dir + our main config) # plus the runtime dirs angie expects to exist. angie runs as root and the # container gets a writable upper layer, so the dirs only need to EXIST — # no sticky/1777 perms needed (this replaces streamLayeredImage's # extraCommands, which did the same mkdir + cp of the angie conf-dir). rootExtra = pkgs.runCommand "angie-root" { } '' mkdir -p $out/var/log/nginx $out/var/cache/angie $out/var/lib/angie \ $out/run $out/tmp $out/etc/angie/http.d cp ${angie}/conf/* $out/etc/angie/ chmod -R u+w $out/etc/angie cp -f ${mainConf} $out/etc/angie/angie.conf ''; # OCI image via nix2container (cluster #201): yields `.copyTo` (skopeo) so # it consumes the shared parity-lib mkNix2ContainerPublish — no buildkit, # no inline skopeo/token/guard. Replaces dockerTools.streamLayeredImage. image = n2c.buildImage { name = "git.oleks.space/oleks/angie"; tag = angie.version; arch = "arm64"; layers = [ (n2c.buildLayer { copyToRoot = [ rootExtra angie pkgs.cacert pkgs.dockerTools.fakeNss pkgs.coreutils pkgs.bash ]; maxLayers = 25; # reproducible = false materializes the layer tar so the image streams # verbatim from any host (remote-builder + binary-cache safe); parity # is asserted at the OCI manifest DIGEST (nix run .#verify-digest, #195). reproducible = false; }) ]; config = { Entrypoint = [ "${angie}/bin/angie" ]; Cmd = [ "-c" "/etc/angie/angie.conf" "-g" "daemon off;" ]; ExposedPorts = { "80/tcp" = { }; }; WorkingDir = "/etc/angie"; }; }; # Publish apps: shared parity-lib nix2container builder (cluster #201). # Single-arch (arm64): yields stage-arm64 / publish-arm64 / publish-index / # publish / push-staged / verify-digest. copy-to (skopeo) pushes the arch # tag, regctl assembles the index; dry-run by default (--publish to push); # token $REGISTRY_TOKEN -> pass fallback, never echoed. builders = parity.lib.mkParityBuilders pkgs; publishApps = builders.mkNix2ContainerPublish { imageName = "git.oleks.space/oleks/angie"; inherit (angie) version; images = { arm64.copyTo = image.copyTo; }; }; in { packages.${system} = { default = image; }; # stage-arm64 / publish-arm64 / publish-index / publish / push-staged / # verify-digest come from parity-lib. apps.${system} = publishApps; # Plain string — read by CI via `nix eval --raw .#angieVersion`. angieVersion = angie.version; }; }