- Nix 98%
- Just 2%
|
All checks were successful
ci/woodpecker/cron/flake-check Pipeline was successful
|
||
|---|---|---|
| .woodpecker | ||
| _crds | ||
| env | ||
| lib | ||
| manifests | ||
| .gitignore | ||
| .sops.yaml | ||
| AGENTS.md | ||
| common.nix | ||
| flake.lock | ||
| flake.nix | ||
| justfile | ||
| README.md | ||
| renovate.json | ||
| templates.nix | ||
| TODO.md | ||
| treefmt.nix | ||
Kubernetes Cluster - Nixidy + ArgoCD
GitOps-managed Kubernetes cluster using Nixidy for type-safe manifest generation and ArgoCD for continuous deployment.
Overview
This repository implements the "Rendered Manifests Pattern":
- Nix configuration (
env/dev/*.nix,env/prod/*.nix) defines all Kubernetes resources in a type-safe way - Nixidy generates plain YAML manifests and commits them to
manifests/dev/andmanifests/prod/ - ArgoCD watches the manifest directories and automatically syncs changes to the cluster
- App-of-apps pattern: ArgoCD manages itself and all other applications
Key Benefits: Type safety, reproducible builds, Git-based audit trail, declarative infrastructure.
Repository Structure
cluster/
├── flake.nix # Nix flake with dependencies and env configuration
├── flake.lock # Locked dependency versions
├── justfile # Common operations (run `just` to see all)
├── common.nix # Shared configuration (networking, domains, etc.)
├── templates.nix # Reusable application templates
├── treefmt.nix # Formatter configuration
├── _crds/ # Generated CRD Nix files (regenerate with just regen-crds)
├── env/
│ ├── dev/ # Dev application definitions (auto-discovered by import-tree)
│ │ ├── *.nix # Application configs (argocd, traefik, etc.)
│ │ └── *.sops.yaml # Encrypted secrets
│ └── prod/ # Prod application definitions
│ └── *.nix
└── manifests/
├── dev/ # Generated YAML manifests for dev (committed, do not edit)
│ ├── apps/ # ArgoCD Application definitions
│ ├── argocd/ # ArgoCD manifests
│ └── */ # Other application manifests
└── prod/ # Generated YAML manifests for prod (committed, do not edit)
Prerequisites
- Nix with flakes enabled
- Kubernetes cluster (k3s recommended)
- SOPS with age keys for secrets management (optional)
Ingress & Routing
The cluster uses Traefik as the ingress controller, deployed via Helm chart.
Configuration
- LoadBalancer IP:
192.168.10.228(configured incommon.nix) - Domain (dev):
*.dev.martials.no/ Domain (prod):*.martials.no(configured incommon.nix) - Entry Points:
web: HTTP (port 80)websecure: HTTPS (port 443)
Routing Methods
Traefik IngressRoute (type-safe Nix resources preferred; YAML also supported):
resources.ingressRoutes.myapp-route.spec = {
entryPoints = [ "web" ];
routes = [
{
match = "Host(`myapp.dev.martials.no`)";
kind = "Rule";
services = [ { name = "myapp-svc"; port = 80; } ];
}
];
};
See toolbox.nix for a complete example.
Customizing Networking
Edit common.nix to configure:
networking.localIp: LoadBalancer IP addressnetworking.domain.root: Base domainnetworking.domain.k8s: Kubernetes subdomain
Quick Start
# Enter development shell (provides nixidy, kubectl, sops)
nix develop
# View available commands
just
# Build manifests (preview, doesn't modify files)
just build dev
# Generate manifests to manifests/dev/
just switch dev
# Review changes and commit
git diff manifests/
git add env/ manifests/
git commit -m "Update configuration"
git push
Note: ArgoCD automatically deploys changes pushed to the repository.
Common Operations
Run just or just --list to see all available commands. Most common:
just build dev # Preview generated manifests
just switch dev # Generate and write manifests
just diff dev # Compare current vs generated
just argocd-status # Check ArgoCD application status
just pods # View all pods
just sops-edit # Edit encrypted secrets
just regen-crds # Regenerate CRD type modules from generators
See the justfile for the complete list of operations.
Development Workflow
Making Changes
- Edit configuration in
env/dev/*.nix(orenv/prod/*.nix) - Build and validate:
just build dev - Generate manifests:
echo y | just switch dev - Review:
git diff manifests/ - Commit and push
- ArgoCD auto-syncs within minutes
Adding a New Application
- Create
env/dev/myapp.nix(orenv/prod/myapp.nix) — it is automatically discovered by import-tree, no registration needed:
{ lib, ... }:
{
applications.myapp = {
namespace = "myapp";
createNamespace = true;
resources = let
labels = { "app.kubernetes.io/name" = "myapp"; };
in {
deployments.myapp.spec = {
replicas = 2;
selector.matchLabels = labels;
template = {
metadata.labels = labels;
spec.containers.myapp = {
image = "registry.example.com/myapp:v1.0.0";
ports.http.containerPort = 8080;
};
};
};
services.myapp.spec = {
selector = labels;
ports.http = { port = 80; targetPort = 8080; };
};
};
};
}
- Build, switch, and commit:
just build dev→echo y | just switch dev→ commitenv/+manifests/
See DEPLOYMENT_GUIDE.md for detailed examples including ingress, secrets, databases, and CI/CD setup.
Using Helm Charts
helm.releases.myapp = {
chart = lib.helm.downloadHelmChart {
repo = "https://charts.example.com";
chart = "app";
version = "1.0.0";
chartHash = ""; # Leave empty; build error provides correct hash
};
values = {
replicaCount = 2;
# ... other values
};
};
Managing Secrets with SOPS
# Edit encrypted secrets (requires age key configured)
just sops-edit
# Secrets are automatically decrypted by SOPS operator in cluster
Documentation
- AGENTS.md: Guidelines for AI agents and contributors
- justfile: All available commands with descriptions
Architecture
- Type Safety: Nixidy validates resources against Kubernetes schemas
- Reproducibility:
flake.lockpins all dependencies - GitOps: Single source of truth in Git, ArgoCD handles deployment
- Declarative: Entire cluster state defined in Nix configuration
- Secrets: SOPS encrypts secrets at rest in Git, decrypted in-cluster
Resources
- Nixidy Documentation - Official docs and options reference
- ArgoCD Documentation - GitOps deployment
- k3s Documentation - Lightweight Kubernetes
- SOPS - Secrets management
License
Personal cluster configuration. Use as reference for your own setup.