docs: rebuild KB in OKF v0.1 with live-verified facts
Copy of the legacy ~/.pi/agent/docs tree rebuilt as the command-center knowledge base: concept files promoted to path identity, index listings stripped of frontmatter, all wikilinks/relative links resolved, every checkable claim verified against the live fleet (Dankserver = Ryzen 7 7700X + RTX 3090; Strix Halo is Dankclaw), unverifiable claims tagged. kb-lint exits 0.
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
---
|
||||
type: reference
|
||||
title: Cloud Providers - AWS, DigitalOcean, Hetzner
|
||||
description: Current best practices for AWS, DigitalOcean, and Hetzner - bootstrapping, IaC, cost, and lifecycle.
|
||||
tags:
|
||||
- aws
|
||||
- digitalocean
|
||||
- hetzner
|
||||
- cloud
|
||||
- infrastructure
|
||||
- engineering
|
||||
timestamp: 2026-08-11
|
||||
verified: 2026-08-28
|
||||
---
|
||||
# Cloud Providers
|
||||
|
||||
This page compares current (2025/2026) practices for AWS, DigitalOcean, and Hetzner.
|
||||
|
||||
## AWS
|
||||
|
||||
Use infrastructure as code with Terraform or OpenTofu. Build a landing zone with AWS Control Tower or a `aws-landing-zone` module.
|
||||
|
||||
Use these services as the baseline:
|
||||
|
||||
* EC2 for compute.
|
||||
* RDS for managed databases.
|
||||
* EKS for managed Kubernetes.
|
||||
* VPC for networking.
|
||||
* S3 for object storage.
|
||||
* IAM for access control.
|
||||
|
||||
Optimize cost with Savings Plans, Spot instances for stateless work, and Reserved instances for databases.
|
||||
|
||||
Set a security baseline with organization SCPs, GuardDuty, Security Hub, and KMS for encryption.
|
||||
|
||||
## DigitalOcean
|
||||
|
||||
Use Droplets for simple virtual servers. Use the App Platform as a PaaS for containerized applications. Use managed databases for PostgreSQL, MySQL, and Redis.
|
||||
|
||||
Use `doctl` as the command-line tool. Use the Terraform provider for infrastructure as code.
|
||||
|
||||
Droplets start around $4 per month. DigitalOcean costs more per compute unit than Hetzner but gives a better developer experience.
|
||||
|
||||
## Hetzner
|
||||
|
||||
Hetzner Cloud offers a strong cost advantage. Compute costs are roughly half or less than DigitalOcean and AWS.
|
||||
|
||||
Use the `hcloud` CLI or the official `hashicorp/hcloud` Terraform provider. Manage servers, networks, firewalls, load balancers, and volumes.
|
||||
|
||||
Hetzner has fewer regions. It has no managed Kubernetes service and no managed databases. Run k3s, k0s, or Talos for Kubernetes.
|
||||
|
||||
Hetzner suits cost-sensitive homelabs, European workloads, and k3s or k0s clusters.
|
||||
|
||||
## Provider Decision
|
||||
|
||||
| Factor | AWS | DigitalOcean | Hetzner |
|
||||
|--------|-----|--------------|---------|
|
||||
| Cost | High | Medium | Low |
|
||||
| Services | Enterprise | Managed databases | Limited |
|
||||
| Regions | Many | Several | Few |
|
||||
| Best for | Enterprise | Developer experience | Cost-sensitive clusters |
|
||||
|
||||
## Related Tools
|
||||
|
||||
* cloud-init for first-boot configuration.
|
||||
* Ansible for configuration management.
|
||||
* WireGuard or Tailscale for private networking.
|
||||
* Cloudflare Tunnels to expose services without open ports.
|
||||
|
||||
## Citations
|
||||
|
||||
* [AWS documentation](https://docs.aws.amazon.com/)
|
||||
* [DigitalOcean](https://www.digitalocean.com/)
|
||||
* [Hetzner Cloud](https://www.hetzner.com/cloud/)
|
||||
* [Terraform hcloud provider](https://registry.terraform.io/providers/hetznercloud/hcloud/latest/docs)
|
||||
|
||||
## See Also
|
||||
|
||||
* [Terraform and OpenTofu](terraform.md)
|
||||
* [Kubernetes](kubernetes.md)
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
type: reference
|
||||
title: Docker and Podman
|
||||
description: Current best practices for Docker and Podman - BuildKit, multi-stage builds, rootless operation, and pods.
|
||||
tags:
|
||||
- docker
|
||||
- podman
|
||||
- containers
|
||||
- infrastructure
|
||||
- engineering
|
||||
timestamp: 2026-08-16
|
||||
verified: 2026-08-28
|
||||
---
|
||||
# Docker and Podman
|
||||
|
||||
This page covers current (2025/2026) best practices for containers.
|
||||
|
||||
## Docker
|
||||
|
||||
Use BuildKit for builds. It enables incremental builds, cache mounts, and secret mounts.
|
||||
|
||||
Use multi-stage builds for production images. Build in a full stage with the toolchain. Copy only the artifacts to a minimal final stage. Name each stage with `AS`.
|
||||
|
||||
Harden images with these practices:
|
||||
|
||||
* Use distroless or alpine base images.
|
||||
* Set `USER` to a non-root user.
|
||||
* Use `ENTRYPOINT` in exec form.
|
||||
* Add a `HEALTHCHECK`.
|
||||
* Pin base image digests.
|
||||
* Use a `.dockerignore` file.
|
||||
|
||||
Use Docker Compose v2 for multi-container applications. Run `docker compose` without a hyphen.
|
||||
|
||||
## Podman
|
||||
|
||||
Podman runs without a daemon and rootless by default. Run it as a non-root user. An alias `alias docker=podman` works for most commands.
|
||||
|
||||
Use Podman pods to group containers that share network and IPC namespaces. Pods suit single-host service groups.
|
||||
|
||||
Use Quadlet for container lifecycle management under systemd. `podman generate systemd` is deprecated as of Podman 5.7; the deprecation notice points to Quadlet.
|
||||
|
||||
Podman is a good choice for Linux servers, homelabs, and CI runners.
|
||||
|
||||
### Quadlet (systemd-managed containers)
|
||||
|
||||
Quadlet files are systemd unit files with a podman section (`[Container]`, `[Network]`, etc.). Podman ships a systemd generator that turns them into `container` services.
|
||||
|
||||
Rootless search path: `~/.config/containers/systemd/`. System-wide: `/etc/containers/systemd/`.
|
||||
|
||||
| Fact | Value |
|
||||
|------|-------|
|
||||
| Unit naming (podman 5.x) | `foo.container` → `foo.service` (no `container-` prefix) |
|
||||
| Container naming | `ContainerName=foo` or default `systemd-foo` |
|
||||
| Boot start | `[Install] WantedBy=default.target` in the file; the generator applies it |
|
||||
| Rootless boot start | enable user-level linger: `loginctl enable-linger <user>` |
|
||||
| Start behavior | `podman run --name ... --replace --rm`; stop removes the container |
|
||||
| Cross-container deps | `[Unit] Wants=` / `After=` referencing other quadlet unit names |
|
||||
| Network | `Network=foo.network` uses a podman network created from `foo.network` |
|
||||
| Long pulls | add `[Service] TimeoutStartSec=900` |
|
||||
|
||||
Reference: `man podman-systemd.unit` (podman-systemd.unit(5)).
|
||||
|
||||
#### Gotchas found in the field (2026-08-16, Gitea migration on dankclaw)
|
||||
|
||||
- The automatic rootless default network (`podman`) has `dns_enabled: false`. Container names do not resolve on it. Create a quadlet `.network` file (DNS is enabled by default for quadlet networks) and point the containers at it.
|
||||
- `${VAR}` expansion in the generated `ExecStart` needs the variable in the *systemd unit environment*. Put `EnvironmentFile=/path/to/env` in the `[Service]` section of the quadlet file. An `EnvironmentFile=` in `[Container]` only lands in the ignored `[X-Container]` section and does not feed expansion.
|
||||
- A podman restart (or `systemctl --user daemon-reload`) re-runs the generator after quadlet file edits. Verify the parsed unit with `systemctl --user cat <unit>`.
|
||||
- Bind-mounted files created by the container are owned by the mapped host UID (container uid 1000 → first subuid + 1000). Edit them with `podman exec --user 1000 <container> ...`.
|
||||
|
||||
#### Gotchas found in the field (2026-08-19, SearXNG trio migration on dankclaw)
|
||||
|
||||
- The quadlet generator rejects several compose-familiar keys in `[Container]` and **silently skips the whole unit** (the error is only in `journalctl --user`, and the unit simply never appears in `systemctl list-unit-files`). Use the podman-flag names: `AddCapability=` (not `CapAdd=`), `AddDevice=HOST:CONTAINER` (not `Device=` — that is a `[Volume]` key). When a unit mysteriously does not generate, read the journal for `quadlet-generator: converting "...": unsupported key`.
|
||||
- Quadlet units are **generated** units (they live in `/run/user/UID/systemd/generator/`). `systemctl enable <unit>` fails on them with "transient or generated". You do not enable them: the `[Install] WantedBy=default.target` in the `.container` file *is* the enablement — `systemctl is-enabled` reports `generated`. With user linger on, they start at boot. Just `daemon-reload` then `start`.
|
||||
- A `.network` unit is also generated and cannot be enabled. It is pulled in automatically by any container that sets `Wants=`/`After=` on it (or `Network=<name>.network`).
|
||||
- To make one container reuse another's network namespace (the compose `network_mode: service:X` equivalent), set `Network=<name>.container` on the consumer. The generator adds the dependency on `<name>.service`. This is how SearXNG exits the Gluetun WireGuard tunnel: `Network=gluetun.container`.
|
||||
- Pin a quadlet network CIDR with `Subnet=<cidr>` in the `.network` file (maps to `podman network create --subnet`). Rootless podman otherwise reassigns the CIDR, which breaks any `trusted_proxies` entry that references it.
|
||||
- A working pattern for a boot-persistent trio: a `.network` (DNS on, `Subnet=` pinned) that the VPN client and the cache join, plus the consumer container on `Network=<vpn>.container`. Secrets live in a mode-0600 env file referenced by `EnvironmentFile=` in each unit's `[Service]`.
|
||||
|
||||
## Docker vs Podman
|
||||
|
||||
| Factor | Docker | Podman |
|
||||
|--------|--------|--------|
|
||||
| Platform | Mac and Windows | Linux focus |
|
||||
| Model | Daemon-based | Rootless and daemonless |
|
||||
| Default user | Root | Non-root |
|
||||
| Grouping | Compose services | Pods |
|
||||
|
||||
Use Docker for cross-platform development. Use Podman rootless for Linux servers and security-conscious deployments.
|
||||
|
||||
## Citations
|
||||
|
||||
* [Docker documentation](https://docs.docker.com/)
|
||||
* [Podman documentation](https://podman.io/docs)
|
||||
* [Container Specification](https://containers.dev/)
|
||||
|
||||
## See Also
|
||||
|
||||
* [Kubernetes](kubernetes.md)
|
||||
* [Go](../languages/go.md)
|
||||
@@ -0,0 +1,15 @@
|
||||
# Infrastructure and Cloud
|
||||
|
||||
Current (2025/2026) best practices for infrastructure as code, containers, orchestration, and cloud providers.
|
||||
|
||||
## Topics
|
||||
|
||||
* [Terraform and OpenTofu](terraform.md) - IaC modules, state, backends, and orchestration.
|
||||
* [Docker and Podman](containers.md) - BuildKit, multi-stage builds, rootless, and pods.
|
||||
* [Kubernetes](kubernetes.md) - Helm, k3s, k0s, and Talos.
|
||||
* [Cloud Providers](cloud.md) - AWS, DigitalOcean, and Hetzner.
|
||||
|
||||
## See Also
|
||||
|
||||
* [Engineering](../index.md) - The parent area.
|
||||
* [SDLC and Tooling](../sdlc.md)
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
type: reference
|
||||
title: Kubernetes
|
||||
description: Current best practices for Kubernetes - Helm charts, k3s, k0s, and Talos Linux.
|
||||
tags:
|
||||
- kubernetes
|
||||
- helm
|
||||
- k3s
|
||||
- k0s
|
||||
- talos
|
||||
- infrastructure
|
||||
- engineering
|
||||
timestamp: 2026-08-11
|
||||
verified: 2026-08-28
|
||||
---
|
||||
# Kubernetes
|
||||
|
||||
This page covers current (2025/2026) best practices for Kubernetes.
|
||||
|
||||
## Helm
|
||||
|
||||
Use Helm to manage charts. Follow the canonical chart layout:
|
||||
|
||||
```
|
||||
my-chart/
|
||||
├── Chart.yaml
|
||||
├── values.yaml
|
||||
├── values.schema.json
|
||||
├── charts/
|
||||
├── templates/
|
||||
│ ├── deployment.yaml
|
||||
│ ├── service.yaml
|
||||
│ └── _helpers.tpl
|
||||
├── .helmignore
|
||||
└── NOTES.txt
|
||||
```
|
||||
|
||||
Use `_helpers.tpl` for consistent labels, such as `app.kubernetes.io/*`. Separate `values.yaml` per environment. Pin chart versions in CI. Run `helm lint` before packaging.
|
||||
|
||||
Set `securityContext` to non-root and read-only root filesystem. Set resource requests and limits.
|
||||
|
||||
## Distribution Choices
|
||||
|
||||
| Tool | Best For | Notes |
|
||||
|------|----------|-------|
|
||||
| k3s | Fast bootstrap | Single binary, embedded addons, quick setup. |
|
||||
| k0s | Vanilla Kubernetes | No host dependencies, `k0sctl` lifecycle tool. |
|
||||
| Talos Linux | Secure immutable clusters | Small footprint, API-driven config. |
|
||||
|
||||
### k3s
|
||||
|
||||
Install with:
|
||||
|
||||
```bash
|
||||
curl -sfL https://get.k3s.io | sh -
|
||||
```
|
||||
|
||||
k3s is a single binary under 100 MB. It is ready in about 30 seconds. Use SQLite for single-node or embedded etcd for high availability.
|
||||
|
||||
### Talos Linux
|
||||
|
||||
Talos is an immutable Kubernetes OS. It has no SSH, no shell, and no package manager. Configure it with declarative YAML through the `talosctl` gRPC API. Use automatic A/B upgrades with rollback.
|
||||
|
||||
## Related Tools
|
||||
|
||||
* Cilium or Calico for networking.
|
||||
* ArgoCD or Flux for GitOps deployment.
|
||||
* k0sctl for cluster lifecycle.
|
||||
|
||||
## Citations
|
||||
|
||||
* [Helm](https://helm.sh/)
|
||||
* [k3s](https://k3s.io/)
|
||||
* [k0s](https://k0sproject.io/)
|
||||
* [Talos Linux](https://www.talos.dev/)
|
||||
|
||||
## See Also
|
||||
|
||||
* [Docker and Podman](containers.md)
|
||||
* [Cloud Providers](cloud.md)
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
type: reference
|
||||
title: Terraform and OpenTofu
|
||||
description: Current best practices for Terraform and OpenTofu - module structure, state management, backends, and orchestration.
|
||||
tags:
|
||||
- terraform
|
||||
- opentofu
|
||||
- iac
|
||||
- infrastructure
|
||||
- engineering
|
||||
timestamp: 2026-08-11
|
||||
verified: 2026-08-28
|
||||
---
|
||||
# Terraform and OpenTofu
|
||||
|
||||
This page covers current (2025/2026) best practices for Terraform and OpenTofu.
|
||||
|
||||
## OpenTofu vs Terraform
|
||||
|
||||
OpenTofu is the open-source fork of Terraform. It uses the MPL 2.0 license. Terraform moved to the Business Source License. Both remain compatible with the same configurations and most providers.
|
||||
|
||||
Use OpenTofu when license portability matters. Use Terraform when you need HashiCorp's commercial extensions.
|
||||
|
||||
## Module Structure
|
||||
|
||||
Separate infrastructure into layers:
|
||||
|
||||
```
|
||||
infrastructure/
|
||||
├── modules/ # Reusable building blocks
|
||||
└── environments/
|
||||
├── dev/
|
||||
├── stage/
|
||||
└── prod/
|
||||
```
|
||||
|
||||
Environment modules call the reusable modules. Root modules declare providers and the backend.
|
||||
|
||||
## State Management
|
||||
|
||||
Never commit `.tfstate` to version control. Use a remote backend only.
|
||||
|
||||
The AWS remote backend uses S3 and DynamoDB:
|
||||
|
||||
* `bucket` for the state bucket.
|
||||
* `key` for the state file path.
|
||||
* `dynamodb_table` for state locking.
|
||||
* `encrypt` for encryption at rest.
|
||||
|
||||
Enable versioning and server-side encryption on the state bucket.
|
||||
|
||||
Use separate state files per environment. Do not use workspaces for separate environments.
|
||||
|
||||
## Security and Lifecycle
|
||||
|
||||
* Mark sensitive values with `sensitive = true`.
|
||||
* Pin provider versions with `required_providers`.
|
||||
* Run `terraform import` to adopt existing infrastructure.
|
||||
* Run `terraform plan` periodically to detect drift.
|
||||
* Use lifecycle blocks for resource replacement policies.
|
||||
|
||||
## Related Tools
|
||||
|
||||
* Terragrunt for orchestration: DRY config, hooks, and run queues.
|
||||
* Pulumi for infrastructure as code in real programming languages.
|
||||
* Packer for building machine images.
|
||||
* Atlantis for pull request based Terraform CI/CD.
|
||||
|
||||
## Citations
|
||||
|
||||
* [Terraform documentation](https://developer.hashicorp.com/terraform)
|
||||
* [OpenTofu](https://opentofu.org/)
|
||||
* [Terragrunt](https://terragrunt.com/)
|
||||
* [AWS backend](https://developer.hashicorp.com/terraform/language/settings/backends/s3)
|
||||
|
||||
## See Also
|
||||
|
||||
* [Cloud Providers](cloud.md)
|
||||
* [Kubernetes](kubernetes.md)
|
||||
Reference in New Issue
Block a user