feature: port the entire project to k3s
This commit is contained in:
@@ -0,0 +1,10 @@
|
|||||||
|
.git
|
||||||
|
.devenv/
|
||||||
|
.direnv/
|
||||||
|
devenv.lock
|
||||||
|
devenv.local.nix
|
||||||
|
devenv.nix
|
||||||
|
devenv.yaml
|
||||||
|
Dockerfile
|
||||||
|
.dockerignore
|
||||||
|
README.md
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# devenv
|
||||||
|
.devenv/
|
||||||
|
.devenv.flake.nix
|
||||||
|
devenv.local.nix
|
||||||
|
.direnv/
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
# Static greeter. Stock nginx serves /usr/share/nginx/html with no extra config;
|
||||||
|
# index.html, robots.txt and favicon.ico are picked up by the defaults.
|
||||||
|
FROM nginx:1.29-alpine
|
||||||
|
|
||||||
|
# Content is baked into the image rather than bind-mounted (as the old
|
||||||
|
# docker-compose setup did), so a rollout is just a new tag.
|
||||||
|
COPY index.html robots.txt favicon.ico /usr/share/nginx/html/
|
||||||
|
COPY _css/ /usr/share/nginx/html/_css/
|
||||||
|
COPY _img/ /usr/share/nginx/html/_img/
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
@@ -1,3 +1,58 @@
|
|||||||
# website
|
# website
|
||||||
|
|
||||||
Simple greeter.
|
Simple greeter — the landing page at [0x29a.ch](https://0x29a.ch).
|
||||||
|
|
||||||
|
Previously a stock `nginx` container on the old Docker host, serving a bind-mounted
|
||||||
|
`/mnt/docker/website/html`. It now ships as a self-contained image (content baked in)
|
||||||
|
and runs on the k3s cluster behind the Hetzner Caddy.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
index.html the greeter
|
||||||
|
_css/styles.css styling
|
||||||
|
_img/ft.jpg background image
|
||||||
|
favicon.ico favicon
|
||||||
|
robots.txt disallow all
|
||||||
|
Dockerfile nginx:1.29-alpine + the static files
|
||||||
|
devenv.nix dev shell: podman
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build & push the image
|
||||||
|
|
||||||
|
Images live in the Gitea container registry under `git.0x29a.ch/aaron/website`.
|
||||||
|
`podman` reads the `Dockerfile` natively — a drop-in for `docker`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
podman build -t git.0x29a.ch/aaron/website:1.0.0 .
|
||||||
|
podman login git.0x29a.ch # Gitea user + a token with write:package
|
||||||
|
podman push git.0x29a.ch/aaron/website:1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
Run it locally to smoke-test:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
podman run --rm -p 8080:80 git.0x29a.ch/aaron/website:1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deploy to k3s
|
||||||
|
|
||||||
|
Deployed via the Helm chart in `helm-k3s-lab-gitops/apps/website`, synced by ArgoCD.
|
||||||
|
The package is private, so the namespace needs a pull secret referenced by the chart's
|
||||||
|
`image.pullSecret` (default `gitea-registry`):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl create secret docker-registry gitea-registry \
|
||||||
|
--docker-server=git.0x29a.ch \
|
||||||
|
--docker-username=<user> \
|
||||||
|
--docker-password=<gitea-token> \
|
||||||
|
-n website
|
||||||
|
```
|
||||||
|
|
||||||
|
Then bump `image.tag` in the chart's `values.yaml` and commit; ArgoCD rolls it out from
|
||||||
|
`main`. (Make the Gitea package public instead and set `image.pullSecret: ""` to drop the
|
||||||
|
secret entirely.)
|
||||||
|
|
||||||
|
Traefik holds Ingress rules for both `0x29a.ch` and `www.0x29a.ch`. TLS is terminated at
|
||||||
|
the edge by Caddy on the Hetzner box, which reverse-proxies to the three k3s nodes over
|
||||||
|
Tailscale — see `ansible-play-infra/inventory/host_vars/0x29a.ch.yml`.
|
||||||
|
|||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"devenv": {
|
||||||
|
"locked": {
|
||||||
|
"dir": "src/modules",
|
||||||
|
"lastModified": 1790415795,
|
||||||
|
"narHash": "sha256-nvpxhuC///gvHzRj9/8A+3+2frKEP8kaabBuQDRO4G4=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "devenv",
|
||||||
|
"rev": "6d76db3889deba50ba7d906ec710d59fcd86354a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"dir": "src/modules",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "devenv",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-src": "nixpkgs-src"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1789506231,
|
||||||
|
"narHash": "sha256-vNkJbtmqyBfFhn/HnzQo4ROuoyYWuy/allqTfJb4kMY=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "devenv-nixpkgs",
|
||||||
|
"rev": "c2f38fe7f9e04d9aadd354d380f2bd40531d9737",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"ref": "rolling",
|
||||||
|
"repo": "devenv-nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-src": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1789370336,
|
||||||
|
"narHash": "sha256-6RSEDHIWQtesQKWSu5qRai8L2h4KgCgMEfJHstW99G4=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "c7def046b9a883d46974757852106483d741586f",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"devenv": "devenv",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
# nixpkgs' rootless podman ships without /etc/containers config, so short
|
||||||
|
# names (nginx:1.29-alpine) and the signature policy can't resolve. These are
|
||||||
|
# the two files podman looks for under ~/.config/containers.
|
||||||
|
registriesConf = pkgs.writeText "registries.conf" ''
|
||||||
|
unqualified-search-registries = ["docker.io"]
|
||||||
|
'';
|
||||||
|
policyJson = pkgs.writeText "policy.json" ''
|
||||||
|
{ "default": [ { "type": "insecureAcceptAnything" } ] }
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Static site — no language toolchain needed, just the image build.
|
||||||
|
packages = [
|
||||||
|
# --- build & ship the image ---
|
||||||
|
pkgs.podman # `podman build -t git.0x29a.ch/aaron/website:1.0.0 .`
|
||||||
|
# # reads the Dockerfile natively; push with `podman push`.
|
||||||
|
];
|
||||||
|
|
||||||
|
enterShell = ''
|
||||||
|
# Seed rootless-podman config once, so `podman build` resolves short image
|
||||||
|
# names and finds a signature policy. Never clobbers existing user config.
|
||||||
|
conf="$HOME/.config/containers"
|
||||||
|
if [ ! -e "$conf/registries.conf" ] || [ ! -e "$conf/policy.json" ]; then
|
||||||
|
mkdir -p "$conf"
|
||||||
|
[ -e "$conf/registries.conf" ] || install -m644 ${registriesConf} "$conf/registries.conf"
|
||||||
|
[ -e "$conf/policy.json" ] || install -m644 ${policyJson} "$conf/policy.json"
|
||||||
|
echo "seeded rootless-podman config in $conf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Persist registry logins. Rootless podman defaults to the volatile
|
||||||
|
# $XDG_RUNTIME_DIR (wiped on reboot); point it at ~/.config so a single
|
||||||
|
# `podman login git.0x29a.ch` survives reboots. The token lives in
|
||||||
|
# auth.json (base64, outside the repo) — never committed.
|
||||||
|
export REGISTRY_AUTH_FILE="$HOME/.config/containers/auth.json"
|
||||||
|
|
||||||
|
echo "website devenv ready — build: podman build -t git.0x29a.ch/aaron/website:1.0.0 ."
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# devenv inputs. Commit this and devenv.lock; .devenv/ stays gitignored.
|
||||||
|
inputs:
|
||||||
|
nixpkgs:
|
||||||
|
url: github:cachix/devenv-nixpkgs/rolling
|
||||||
Reference in New Issue
Block a user