mirror of
https://github.com/srid/nixos-config.git
synced 2026-07-16 22:01:33 +08:00
incus-pet: hello-web example flake — minimal contract demonstration
Self-contained reference under
modules/nixos/linux/incus/incus-pet/example/hello-web/ that satisfies
the incus-pet contract in the smallest possible form:
- packages.<sys>.default a darkhttpd wrapper that serves a
one-page index.html, reading HOST/PORT
from the environment
- nixosModules.default services.hello-web.{enable, package,
host, port} + a DynamicUser=true systemd
unit
- nixosModules.incus the deploy contract: services.hello-web
bound to 8080, hostname "hello-web"
Useful as a copy-paste template for new apps. Less moving parts than
the anywhen reference (no bun, no SQLite, no state dir, no e2e tests
to keep green) — just three flake outputs and a static HTML response.
Live-deployed end-to-end on pureintent during this PR's bring-up:
$ incus-pet deploy path:./.../example/hello-web hello-web \
--port 8081 --listen 100.122.32.106
$ curl http://100.122.32.106:8081/
<!doctype html>
<h1>Hello from incus-pet</h1>
Idempotent re-deploy verified (no flags needed — host-port + listen
read back from container metadata; container name auto-detected from
incus.container.hostname).
This commit is contained in:
parent
caea54f185
commit
293e53071c
3 changed files with 182 additions and 0 deletions
|
|
@ -0,0 +1,40 @@
|
|||
# hello-web — incus-pet reference example
|
||||
|
||||
Smallest possible flake that satisfies the [incus-pet contract](../../SKILL.md).
|
||||
A static HTTP server (`darkhttpd` wrapping a one-page `index.html`) packaged
|
||||
through the full stack:
|
||||
|
||||
- `packages.<sys>.default` — the binary
|
||||
- `nixosModules.default` — `services.hello-web.{enable, package, host, port}` + a systemd unit
|
||||
- `nixosModules.incus` — the deploy contract (binds 8080 inside a `hello-web` container)
|
||||
|
||||
## Build it standalone
|
||||
|
||||
```sh
|
||||
nix build path:./modules/nixos/linux/incus/incus-pet/example/hello-web
|
||||
|
||||
# Then run it locally — listens on 0.0.0.0:8080.
|
||||
./result/bin/hello-web &
|
||||
curl http://127.0.0.1:8080
|
||||
```
|
||||
|
||||
## Deploy it as an incus-pet container
|
||||
|
||||
From a host that has the incus daemon and the `incus-pet` CLI on PATH:
|
||||
|
||||
```sh
|
||||
nix run path:.#incus-pet -- deploy \
|
||||
path:./modules/nixos/linux/incus/incus-pet/example/hello-web \
|
||||
hello-web --port 8081 --listen 100.122.32.106
|
||||
|
||||
curl http://100.122.32.106:8081
|
||||
```
|
||||
|
||||
`incus-pet list` will show the running container; `incus-pet rm hello-web`
|
||||
tears it down.
|
||||
|
||||
## What to read next
|
||||
|
||||
The flake here is meant to be a working template. Compare the three
|
||||
outputs (`packages.default`, `nixosModules.default`, `nixosModules.incus`)
|
||||
side-by-side with what srid/anywhen ships — same shape, scaled down.
|
||||
27
modules/nixos/linux/incus/incus-pet/example/hello-web/flake.lock
generated
Normal file
27
modules/nixos/linux/incus/incus-pet/example/hello-web/flake.lock
generated
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1779357205,
|
||||
"narHash": "sha256-cCO8aTqss5x9Ky8GWkpY0Hy5fyTZEbtifSUV8QjSzic=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f83fc3c307e74bc5fd5adb7eb6b8b13ffd2a36e1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
115
modules/nixos/linux/incus/incus-pet/example/hello-web/flake.nix
Normal file
115
modules/nixos/linux/incus/incus-pet/example/hello-web/flake.nix
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
# hello-web — minimal incus-pet example.
|
||||
#
|
||||
# Self-contained reference flake that ships the three outputs incus-pet
|
||||
# consumes:
|
||||
#
|
||||
# - packages.<sys>.default a tiny static-file server (darkhttpd
|
||||
# wrapped to read HOST/PORT from env)
|
||||
# - nixosModules.default services.hello-web.{enable, package,
|
||||
# host, port} + a systemd unit
|
||||
# - nixosModules.incus the deploy contract — wires the
|
||||
# service to bind 8080 inside an incus
|
||||
# container at hostname "hello-web"
|
||||
#
|
||||
# Deploy with (from a host that has the incus daemon + incus-pet CLI):
|
||||
#
|
||||
# nix run github:srid/nixos-config#incus-pet -- \
|
||||
# deploy <path-to-this-flake> --port 8081 --listen <ip>
|
||||
{
|
||||
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
|
||||
outputs = { self, nixpkgs, ... }:
|
||||
let
|
||||
systems = [ "x86_64-linux" "aarch64-linux" ];
|
||||
eachSystem = f: nixpkgs.lib.genAttrs systems
|
||||
(system: f nixpkgs.legacyPackages.${system});
|
||||
in
|
||||
{
|
||||
packages = eachSystem (pkgs:
|
||||
let
|
||||
www = pkgs.writeTextDir "index.html" ''
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>hello-web</title>
|
||||
<h1>Hello from incus-pet</h1>
|
||||
<p>Served by darkhttpd inside an incus container.</p>
|
||||
'';
|
||||
hello-web = pkgs.writeShellApplication {
|
||||
name = "hello-web";
|
||||
runtimeInputs = [ pkgs.darkhttpd ];
|
||||
text = ''
|
||||
HOST="''${HOST:-0.0.0.0}"
|
||||
PORT="''${PORT:-8080}"
|
||||
exec darkhttpd ${www} --addr "$HOST" --port "$PORT"
|
||||
'';
|
||||
meta.mainProgram = "hello-web";
|
||||
};
|
||||
in
|
||||
{
|
||||
default = hello-web;
|
||||
hello-web = hello-web;
|
||||
});
|
||||
|
||||
nixosModules.default = { config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.hello-web;
|
||||
in
|
||||
{
|
||||
options.services.hello-web = {
|
||||
enable = lib.mkEnableOption "hello-web example server";
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
description = "The hello-web package to run (must expose bin/hello-web via meta.mainProgram).";
|
||||
};
|
||||
host = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "0.0.0.0";
|
||||
description = "Address the HTTP server binds to.";
|
||||
};
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8080;
|
||||
description = "Port the HTTP server listens on.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.hello-web = {
|
||||
description = "hello-web example HTTP server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
environment = {
|
||||
HOST = cfg.host;
|
||||
PORT = toString cfg.port;
|
||||
};
|
||||
serviceConfig = {
|
||||
ExecStart = lib.getExe cfg.package;
|
||||
Restart = "on-failure";
|
||||
RestartSec = 2;
|
||||
DynamicUser = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# incus-pet contract — see SKILL.md in the incus-pet tree.
|
||||
nixosModules.incus = { config, lib, pkgs, ... }: {
|
||||
imports = [ self.nixosModules.default ];
|
||||
|
||||
incus.container = {
|
||||
enable = true;
|
||||
hostname = lib.mkDefault "hello-web";
|
||||
};
|
||||
system.stateVersion = "25.05";
|
||||
|
||||
services.hello-web = {
|
||||
enable = true;
|
||||
package = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.default;
|
||||
host = lib.mkDefault "0.0.0.0";
|
||||
port = 8080; # fixed by the incus-pet contract
|
||||
};
|
||||
};
|
||||
|
||||
formatter = eachSystem (pkgs: pkgs.nixpkgs-fmt);
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue