diff --git a/services/docs/content/en/_index.md b/services/docs/content/en/_index.md index 0243972..63f6831 100644 --- a/services/docs/content/en/_index.md +++ b/services/docs/content/en/_index.md @@ -7,7 +7,7 @@ title: "Ermnvldmr's Documentation" Welcome to the unified documentation for my own projects {{< cards >}} +{{< card link="ermnvldmr" title="ermnvldmr.com Platform" icon="cloud" subtitle="Cloud-native infrastructure, Packer golden image, K3s cluster, and GitOps platform" >}} {{< card link="apex" title="apex.ermnvldmr.com" icon="server" subtitle="Fleet operations framework: a stdlib-python engine and a shared compose core" >}} {{< card link="quetza" title="Quetza Bot" icon="terminal" subtitle="Modular Discord bot framework documentation" >}} -{{< card link="root" title="ermnvldmr.com-root-commons (deprecated)" icon="archive" subtitle="Deprecated — superseded by the apex framework" >}} {{< /cards >}} diff --git a/services/docs/content/en/ermnvldmr/_index.md b/services/docs/content/en/ermnvldmr/_index.md new file mode 100644 index 0000000..45918da --- /dev/null +++ b/services/docs/content/en/ermnvldmr/_index.md @@ -0,0 +1,32 @@ +--- +title: "ermnvldmr.com Platform" +weight: 1 +type: docs +cascade: + type: docs +--- + +**ermnvldmr.com Platform** is the complete cloud-native infrastructure, automation pipeline, and GitOps delivery system powering all `ermnvldmr.com` production services. + +The platform is designed around strict infrastructure-as-code principles, immutable golden OS images, secret encryption at rest, automated continuous reconciliation, and zero-downtime rolling updates. + +--- + +## Documentation Sections + +{{% cards %}} +{{< card link="architecture" title="Architecture & Flow" icon="server" subtitle="End-to-end architectural design: Packer, Cloud-Init, K3s, Flux GitOps, and Cloudflare." >}} +{{< card link="golden-image" title="Golden Image Automation" icon="cube" subtitle="Automated QEMU Packer build pipeline, kernel & OS bake-in, S3 artifact storage, and quota management." >}} +{{< card link="deployment-gitops" title="GitOps & Release Engine" icon="refresh" subtitle="Continuous deployment, semantic releases, fast-track deploys, and automated /version.json rollout checks." >}} +{{< card link="operations" title="Operations & Runbook" icon="shield-check" subtitle="SSH access, SOPS age encryption, persistent storage management, database backups, and disaster recovery." >}} +{{% /cards %}} + +--- + +## Key Platform Characteristics + +* **Immutable Golden Images**: Standardized Debian 12 + K3s base built via Packer and QEMU, isolated and stored in S3. +* **Autonomous First-Boot Initialization**: Cloud-Init automatically provisions storage, network hardening, firewall, age encryption secrets, and bootstraps Flux GitOps without requiring manual console access. +* **Declarative GitOps Engine**: Flux v2 continuously reconciles Kubernetes cluster state against the `next` branch in GitHub. +* **End-to-End Encryption**: SOPS + Age encrypts all sensitive secrets in Git; Let's Encrypt and Cloudflare Full (Strict) secure all public traffic. +* **Automated Production Rollout Verification**: Release pipelines query public `/version.json` probes to verify that rolling updates actively serve user traffic before finishing. diff --git a/services/docs/content/en/ermnvldmr/architecture.md b/services/docs/content/en/ermnvldmr/architecture.md new file mode 100644 index 0000000..42fb8b0 --- /dev/null +++ b/services/docs/content/en/ermnvldmr/architecture.md @@ -0,0 +1,116 @@ +--- +title: "Architecture & Flow" +weight: 2 +type: docs +--- + +The `ermnvldmr.com` infrastructure architecture combines immutable OS image baking, autonomous cloud-init bootstrapping, and declarative Flux GitOps reconciliation into a single unified deployment model. + +--- + +## 1. High-Level System Architecture + +```mermaid +flowchart TD + subgraph GitHub ["GitHub Infrastructure"] + Repo["Git Repository (next branch)"] + Workflows["GitHub Actions Pipelines"] + GHCR["GitHub Container Registry (GHCR)"] + end + + subgraph S3 ["S3-Compatible Object Storage"] + GoldenImage["Packer Golden Image (.qcow2)"] + Backups["Daily PostgreSQL Backups"] + end + + subgraph Cloud ["Cloud Infrastructure / Compute Platform"] + subgraph VM ["Compute Virtual Machine"] + subgraph OS ["Debian 12 Bookworm"] + CloudInit["Cloud-Init First-Boot"] + UFW["UFW Firewall (80, 443, 22)"] + SSD["Secondary SSD (/dev/vdb /var/lib/rancher/k3s/storage)"] + end + + subgraph K3s ["K3s Single-Node Cluster"] + Flux["Flux v2 Operator"] + Traefik["Traefik Ingress (HostPort 80/443)"] + CertManager["Cert-Manager (Let's Encrypt Prod)"] + + subgraph Apps ["Namespaced Workloads (com-ermnvldmr)"] + WWW["www (React 19 SSG + Nginx)"] + Docs["docs (Hugo + Hextra + Nginx)"] + Postgres["PostgreSQL 16 StatefulSet"] + Umami["Umami Analytics Server"] + BackupCron["Postgres S3 Backup CronJob"] + end + end + end + end + + subgraph Edge ["Cloudflare Edge"] + CF["Cloudflare Proxy (Full Strict)"] + end + + Users["Internet Visitors"] --> CF + CF --> Traefik + Traefik --> WWW + Traefik --> Docs + Traefik --> Umami + Umami --> Postgres + BackupCron --> Backups + Workflows --> GHCR + Workflows --> GoldenImage + Repo --> Flux + Flux --> Apps +``` + +--- + +## 2. Platform Lifecycle Stages + +The lifecycle of the platform operates in three distinct phases: + +### Phase 1: Golden Image Build (Packer) +1. **Automated Trigger**: GitHub Actions runs `.github/workflows/ci-next-build-golden-image.yml`. +2. **QEMU Virtualization**: Packer launches a headless QEMU Debian 12 installation with preseed automation (`preseed.cfg`). +3. **Provisioning**: + * Installs base system packages (`curl`, `git`, `htop`, `fail2ban`, `ufw`, `qemu-guest-agent`, `isc-dhcp-client`). + * Configures `ds-identify` with `policy: enabled` so cloud-init is guaranteed to run. + * Pre-installs K3s binary (`INSTALL_K3S_SKIP_ENABLE=true`, `INSTALL_K3S_SKIP_START=true`). + * Strips machine identity (`/etc/machine-id`, DBus ID, SSH host keys, network MAC caches) for clean first-boot isolation. +4. **S3 Upload & Quota Management**: Converts image to compressed `qcow2` format, prunes older images in `dev/images/` to prevent bucket exhaustion, and uploads the verified golden image to S3-compatible object storage. + +--- + +### Phase 2: Autonomous First-Boot (Cloud-Init) +When a VM is created from the golden image with `ci/cloud-init/user-data.template.yaml`: +1. **User & Network Setup**: + * Creates administrative user `adam` with public SSH key. + * Disables password authentication and root direct SSH access. + * Configures reliable fallback DNS nameservers (`1.1.1.1`, `8.8.8.8`, `77.88.8.8`). +2. **Security & Kernel Hardening**: + * Applies sysctl rules: SYN flood protection, disabling ICMP redirects, source routing protection, and strict reverse path filtering. + * Configures UFW firewall rules allowing only SSH (22), Traefik HTTP (80), and Traefik HTTPS (443), while routing pod CIDR (`10.42.0.0/16`) and service CIDR (`10.43.0.0/16`). + * Enables Fail2ban. +3. **Persistent Secondary Storage**: + * Detects secondary virtual disk `/dev/vdb`. + * Formats with `ext4` and filesystem label `k3s-storage` if not yet formatted. + * Mounts to `/var/lib/rancher/k3s/storage` and persists mount configuration in `/etc/fstab`. +4. **K3s & GitOps Engine Startup**: + * Starts `k3s.service` with built-in ServiceLB enabled. + * Injects the SOPS age decryption key into Kubernetes secret `flux-system/sops-age`. + * Installs Flux v2 custom resource definitions and controllers. + * Applies the root GitOps sync (`GitRepository` + `Kustomization`) pointing directly to `https://github.com/deytenit/ermnvldmr.com.git` on branch `next`. + +--- + +### Phase 3: Continuous Reconciliation & Delivery (GitOps) +1. **Flux Controller**: + * Polls the `next` branch every 1 minute for repository changes. + * Evaluates Kustomize overlays in `ci/k8s/clusters/production`. + * Automatically decrypts `*.sops.yaml` secrets in-cluster using the injected `sops-age` key. + * Enforces zero-downtime rolling update strategies (`maxUnavailable: 0`, `maxSurge: 1`). +2. **Ingress & TLS Automation**: + * Traefik binds HostPorts 80 and 443. + * Cert-Manager solves Let's Encrypt HTTP-01 challenges via Ingress routes. + * Cloudflare Edge operates in **Full (strict)** SSL mode, proxying traffic securely to Traefik. diff --git a/services/docs/content/en/ermnvldmr/deployment-gitops.md b/services/docs/content/en/ermnvldmr/deployment-gitops.md new file mode 100644 index 0000000..05b32ea --- /dev/null +++ b/services/docs/content/en/ermnvldmr/deployment-gitops.md @@ -0,0 +1,74 @@ +--- +title: "GitOps & Release Engine" +weight: 4 +type: docs +--- + +The platform uses a declarative GitOps model powered by **Flux v2** and **Kustomize**, with automated post-deployment rollout validation across all production workloads. + +--- + +## 1. Monorepo GitOps Layout + +All Kubernetes manifests are located in [`ci/k8s/`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/k8s/): + +```text +ci/k8s/ +├── apps/ # Application workloads +│ ├── docs/ # Hugo documentation service +│ ├── postgres/ # PostgreSQL 16 StatefulSet & S3 backup CronJob +│ ├── umami/ # Umami web analytics +│ └── www/ # React 19 primary website +├── base/ # Base cluster resources +│ └── namespaces/ # `com-ermnvldmr` namespace definition +├── clusters/ # Flux cluster root definitions +│ └── production/ # Root Kustomization point for production +└── infrastructure/ # Shared cluster infrastructure + ├── cert-manager/ # Cert-Manager v1.17.0 & Let's Encrypt ClusterIssuer + └── networking/ # Traefik Ingress routing rules +``` + +--- + +## 2. Release Workflows & Continuous Deployment + +### Service Deployment Modes: + +1. **`services/docs` (Continuous Deployment)**: + * **Trigger**: Push to `next` modifying `services/docs/**`. + * **Workflow**: `.github/workflows/services-docs-next-required.yml`. + * **Action**: Builds Docker image, updates `ci/k8s/apps/docs/kustomization.yaml`, commits to `next`, and runs automated `verify-rollout`. + +2. **`services/www` (Semantic Release Dispatch)**: + * **Trigger**: Dispatched via `.github/workflows/services-www-releases-dispatch-release.yml`. + * **Standard Mode**: Runs full verification suite (Vitest, Storybook Playwright, Lint, Typecheck, Build) ➔ Tags git release ➔ Pushes image to GHCR ➔ Updates GitOps tag ➔ Runs `verify-rollout`. + * **Fast-Track Mode (`skip_ci: true`)**: Bypasses test suites for emergency deploys and rollbacks, immediately building the image, updating GitOps, and verifying the production rollout. + +--- + +## 3. Automated Post-Deployment Verification (`/version.json`) + +To guarantee that a deployment has actually completed and is serving user traffic: +1. Every container image includes a generated `/usr/share/nginx/html/version.json` with `COMMIT_SHA` and `VERSION` build metadata. +2. Nginx serves `/version.json` with `Cache-Control: no-store, no-cache, must-revalidate`. +3. The `verify-rollout` GitHub Actions job polls the public endpoint (`https://www.ermnvldmr.com/version.json` or `https://docs.ermnvldmr.com/version.json`) every 10 seconds (up to 5 minutes) until the live production commit matches the deployed commit. + +```bash +TARGET_COMMIT="sha-26f0c23" +for i in {1..30}; do + LIVE_COMMIT=$(curl -sf https://www.ermnvldmr.com/version.json | jq -r '.commit') + if [ "$LIVE_COMMIT" = "$TARGET_COMMIT" ]; then + echo "✅ Production rollout verified!" + exit 0 + fi + sleep 10 +done +``` + +--- + +## 4. Rollback Strategy + +* **Git Revert (Standard)**: Revert the deployment commit in Git and push to `next`. +* **GitOps Script**: Run `bash ci/scripts/deploy-gitops.sh `. +* **Emergency Kubernetes Rollback**: Run `kubectl rollout undo deployment/ -n com-ermnvldmr` on the cluster for instant 2-second rollback. diff --git a/services/docs/content/en/ermnvldmr/golden-image.md b/services/docs/content/en/ermnvldmr/golden-image.md new file mode 100644 index 0000000..ddc7bed --- /dev/null +++ b/services/docs/content/en/ermnvldmr/golden-image.md @@ -0,0 +1,61 @@ +--- +title: "Golden Image Automation" +weight: 3 +type: docs +--- + +The `ermnvldmr.com` golden image pipeline automates the generation of standardized, hardened Debian 12 virtual machine images pre-configured for single-node K3s clustering. + +--- + +## 1. Packer Configuration & Provisioning Pipeline + +Golden images are defined in [`ci/packer/`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/packer/) and built using the `qemu` Packer builder. + +### Key Files: +* **[`debian-12-k3s.pkr.hcl`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/packer/debian-12-k3s.pkr.hcl)**: Main Packer template specifying CPU, RAM, disk size (10GB qcow2), Debian 12 Netinst ISO, boot commands, and provisioner sequence. +* **[`http/preseed.cfg`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/packer/http/preseed.cfg)**: Debian automated preseed installation rules (minimal system, non-interactive partitioning, APT mirrors). +* **[`scripts/01-base-system.sh`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/packer/scripts/01-base-system.sh)**: Base system package installation, cloud-init forced policy enablement (`/etc/cloud/ds-identify.cfg`), kernel optimization, and fail2ban setup. +* **[`scripts/02-install-k3s.sh`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/packer/scripts/02-install-k3s.sh)**: Downloads and installs the K3s binary (`INSTALL_K3S_SKIP_ENABLE=true`, `INSTALL_K3S_SKIP_START=true`) so the binary is baked into `/usr/local/bin/k3s` without creating a cluster during image build. +* **[`scripts/03-cleanup.sh`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/packer/scripts/03-cleanup.sh)**: Machine identity reset (`/etc/machine-id`, `/var/lib/dbus/machine-id`, `/etc/ssh/ssh_host_*`), cache purging, and zeroing free space for maximum image compression. + +--- + +## 2. GitHub Actions Automation + +The image build is executed via `.github/workflows/ci-next-build-golden-image.yml`. + +### Workflow Stages: +1. **Validate Provisioner Scripts**: Verifies bash syntax (`bash -n ci/packer/scripts/*.sh`) and Packer template formatting (`packer fmt -check`). +2. **Build Golden Image**: + * Initializes Packer plugins (`packer init`). + * Runs headless QEMU virtual machine build (`packer build`). + * Compresses the output artifact to `qcow2`. +3. **S3 Storage Upload & Quota Management**: + * Configures AWS S3 CLI with S3-compatible Object Storage credentials. + * **Automatic Quota Pruning**: Removes older images matching `dev/images/com-ermnvldmr-debian-12-k3s-amd64-*.qcow2` before uploading to prevent exceeding bucket limits. + * **Uploads**: The newly baked image is pushed to: + ```text + s3:///dev/images/com-ermnvldmr-debian-12-k3s-amd64-.qcow2 + ``` + +--- + +## 3. Naming Convention + +Images follow a deterministic naming structure based on the git commit: + +```text +com-ermnvldmr-debian-12-k3s-amd64-.qcow2 +``` + +Example: `com-ermnvldmr-debian-12-k3s-amd64-f4ba6d1.qcow2` + +--- + +## 4. First-Boot Cloud-Init Integration + +When launching a compute instance from the uploaded golden image in your cloud infrastructure: +1. Pass the instantiated [`user-data.template.yaml`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/cloud-init/user-data.template.yaml) in the instance metadata under `user-data`. +2. Cloud-init executes `/usr/local/bin/bootstrap-cluster.sh` autonomously on first boot. +3. The instance initializes the network, formats persistent SSDs, starts K3s, installs Flux, and syncs production workloads within ~90 seconds. diff --git a/services/docs/content/en/ermnvldmr/operations.md b/services/docs/content/en/ermnvldmr/operations.md new file mode 100644 index 0000000..832940b --- /dev/null +++ b/services/docs/content/en/ermnvldmr/operations.md @@ -0,0 +1,100 @@ +--- +title: "Operations & Runbook" +weight: 5 +type: docs +--- + +Practical runbook and operational guidelines for managing, debugging, and maintaining the `ermnvldmr.com` production cluster. + +--- + +## 1. Remote SSH Access + +Connect to the virtual machine using the administrative `adam` account: + +```bash +ssh -i ~/.ssh/id_ed25519 adam@ +``` + +The `adam` user has passwordless `sudo` privileges and automatically configured `kubectl` credentials in `~/.kube/config`. + +--- + +## 2. Cluster Health Inspection + +### Check Pod Status +```bash +kubectl get pods -n com-ermnvldmr -o wide +``` + +### Check Ingress & TLS Certificates +```bash +kubectl get certificates -n com-ermnvldmr +kubectl get ingress -n com-ermnvldmr +``` + +### Check Flux GitOps Sync Status +```bash +kubectl get gitrepositories -n flux-system +kubectl get kustomizations -n flux-system +``` + +### Force Immediate GitOps Reconciliation +```bash +kubectl annotate --overwrite kustomization -n flux-system cluster-sync reconcile.fluxcd.io/requestedAt="$(date +%s)" +``` + +--- + +## 3. Secret Management with SOPS + Age + +All sensitive files (`*.sops.yaml`) are committed directly to Git using SOPS with Age asymmetric encryption. + +### SOPS Configuration (`.sops.yaml`): +```yaml +creation_rules: + - path_regex: 'ci/k8s/.*secret.*\.yaml$' + encrypted_regex: '^(data|stringData)$' + age: 'age1' +``` + +> **Important**: The `encrypted_regex` rule preserves `apiVersion`, `kind`, and `metadata.name` in plaintext so Kustomize and Flux can inspect and route resources without pre-parsing errors. + +### Encrypting a Secret +```bash +sops --encrypt --in-place ci/k8s/apps/postgres/secret.sops.yaml +``` + +### Editing an Encrypted Secret +```bash +sops ci/k8s/apps/postgres/secret.sops.yaml +``` + +--- + +## 4. PostgreSQL Storage & S3 Backups + +### Storage Architecture +* PostgreSQL data resides on a persistent 5Gi PVC backed by `/dev/vdb` (mounted at `/var/lib/rancher/k3s/storage`). +* Storage survives VM restarts and node maintenance. + +### Automated Daily S3 Backup CronJob +* Manifest: [`ci/k8s/apps/postgres/backup-cronjob.yaml`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/k8s/apps/postgres/backup-cronjob.yaml). +* Runs daily at 03:00 UTC (`0 3 * * *`). +* Executes `pg_dump` with gzip compression and uploads directly to `s3:///backups/postgres/`. + +### Manual Backup Trigger +```bash +kubectl create job --from=cronjob/postgres-backup manual-backup-$(date +%s) -n com-ermnvldmr +``` + +--- + +## 5. Cloudflare SSL/TLS Configuration + +* **SSL Mode**: **Full (strict)** +* **HTTPS Redirect Bypass Rule**: Ensure an exception rule exists for ACME HTTP-01 challenges: + ```text + http.request.scheme eq "http" and not starts_with(http.request.uri.path, "/.well-known/acme-challenge/") + ``` + This allows cert-manager to renew Let's Encrypt certificates over port 80 without being redirected or blocked. diff --git a/services/docs/content/en/root/_index.md b/services/docs/content/en/root/_index.md deleted file mode 100644 index ed963cf..0000000 --- a/services/docs/content/en/root/_index.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Documentation of ermnvldmr.com root deployment commons -description: Documentation for the ermnvldmr.com root deployment commons framework. -weight: 2 -type: docs -cascade: - type: docs ---- - -> [!WARNING] -> **Deprecated.** The root framework has been superseded by the -> [apex fleet operations framework](/apex) — a python-stdlib rewrite of the engine with a -> shared compose core. This section is retained for reference only and no longer receives -> updates. - -The `ermnvldmr.com-root-commons` framework provides a minimal-dependency deployment environment for independent, self-hosted projects. - -The generic logic, scripts, and deployment patterns used across multiple unrelated self-hosted applications are stored in the [GitHub: ermnvldmr.com-root-commons](https://github.com/deytenit/ermnvldmr.com-root-commons) repository. - -## Core features - -- **Smart Dispatcher**: A single entrypoint (`root`) for all orchestration tasks. -- **Tiered Storage**: Standardized classification for configuration, data, and logs. -- **Privilege Isolation**: Project-specific non-root users for enhanced security. -- **Namespaced Libraries**: Explicit, modular Bash utilities for consistent automation. - -## Sections - -{{% cards %}} -{{< card link="concepts" title="Concepts" icon="book-open" subtitle="Theoretical foundations, architecture, and security models." >}} -{{< card link="guides" title="Guides" icon="map" subtitle="Step-by-step guides for installation and action development." >}} -{{< card link="reference" title="Reference" icon="code" subtitle="API and technical references for developers." >}} -{{% /cards %}} - ---- - -**See also:** - -- [GitHub: ermnvldmr.com-root-commons](https://github.com/deytenit/ermnvldmr.com-root-commons) diff --git a/services/docs/content/en/root/concepts/_index.md b/services/docs/content/en/root/concepts/_index.md deleted file mode 100644 index 7ba7751..0000000 --- a/services/docs/content/en/root/concepts/_index.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Concepts -description: Theoretical foundations, architecture, and security models. -weight: 10 ---- - -Theoretical foundations, architecture, and security models for the ermnvldmr.com root deployment commons framework. - -{{% cards %}} -{{< card link="principles" title="Infrastructure principles" icon="book-open" subtitle="Predictability, minimal dependencies, and decentralization." >}} -{{< card link="architecture" title="Infrastructure architecture" icon="share" subtitle="Decentralized orchestration and deployment models." >}} -{{< card link="security-model" title="Security & privilege isolation" icon="shield-check" subtitle="Privilege isolation and network hardening." >}} -{{< card link="tiered-storage" title="Tiered storage model" icon="database" subtitle="Standardized storage classification for service data." >}} -{{% /cards %}} diff --git a/services/docs/content/en/root/concepts/architecture.md b/services/docs/content/en/root/concepts/architecture.md deleted file mode 100644 index ca8fde7..0000000 --- a/services/docs/content/en/root/concepts/architecture.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: Infrastructure architecture -description: The decentralized orchestration model and deployment structure. -weight: 10 ---- - -The Root framework operates on a decentralized orchestration model designed for independent, self-contained projects. It enforces a strict separation between the orchestrator (the "brain") and the automation tasks (the "muscle"). - -## Core philosophy {#philosophy} - -The framework is built on the **Smart Root, Stupid Actions** principle. This design ensures that individual automation scripts remain declarative and unaware of the global system state, while the central dispatcher handles environment resolution and library initialization. - -### Smart Root (The Dispatcher) - -The `root` entrypoint is the sole interface for users. It is responsible for: - -- **Environment resolution** → Locating the `commons` and `configs` repositories. -- **Library warming** → Sourcing namespaced modules exactly once. -- **Context establishment** → Defining the target [Node](/root/glossary#node) and its associated paths. - -### Stupid Actions (The Tasks) - -[Actions](/root/glossary#action) are declarative scripts located in `scripts/actions/`. They are "stupid" because: - -- They do not calculate paths or detect repositories. -- They depend entirely on the `ROOT_` environment variables. -- They focus exclusively on a single atomic task (e.g., `compose`, `ufw`). - -## Deployment model {#deployment} - -The framework is typically deployed as a shared [Commons](/root/glossary#commons) repository mounted as a Git submodule within a configuration repository. The engine powering this shared infrastructure is hosted at [GitHub: ermnvldmr.com-root-commons](https://github.com/deytenit/ermnvldmr.com-root-commons). - -{{< filetree/container >}} -{{< filetree/folder name="configs-repo" state="open" >}} - {{< filetree/folder name=".operator" state="open" >}} - {{< filetree/folder name="shared (submodule)" state="open" >}} - {{< filetree/folder name="scripts" >}} - {{< filetree/folder name="run" >}} - {{< filetree/file name="root (dispatcher)" >}} - {{< /filetree/folder >}} - {{< filetree/folder name="lib" >}} - {{< filetree/file name="shared libraries" >}} - {{< /filetree/folder >}} - {{< filetree/folder name="actions" >}} - {{< filetree/file name="shared actions" >}} - {{< /filetree/folder >}} - {{< /filetree/folder >}} - {{< /filetree/folder >}} - {{< filetree/folder name="local" state="open" >}} - {{< filetree/folder name="scripts" >}} - {{< filetree/folder name="actions" >}} - {{< filetree/file name="node-specific overrides" >}} - {{< /filetree/folder >}} - {{< /filetree/folder >}} - {{< /filetree/folder >}} - {{< /filetree/folder >}} - {{< filetree/folder name="daedalus (node)" >}} - {{< filetree/file name="docker-compose.yml" >}} - {{< /filetree/folder >}} - {{< filetree/file name="init.sh (bootstrap)" >}} -{{< /filetree/folder >}} -{{< /filetree/container >}} - ---- - -**See also:** - -- [Concept: The ROOT_ API](/root/reference/root-api) -- [Guide: Installation](/root/guides/installation) -- [GitHub: ermnvldmr.com-root-commons](https://github.com/deytenit/ermnvldmr.com-root-commons) diff --git a/services/docs/content/en/root/concepts/principles.md b/services/docs/content/en/root/concepts/principles.md deleted file mode 100644 index cf45429..0000000 --- a/services/docs/content/en/root/concepts/principles.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Infrastructure principles -description: Core principles providing a secure, predictable, and minimal-dependency environment. -weight: 5 ---- - -The Root framework is built on core principles designed to provide a secure, predictable, and minimal-dependency environment for independent self-hosted projects. - -## Predictability through structure {#predictability} - -Manual server configuration is prone to "configuration drift," where hosts intended to be identical slowly diverge. Root solves this by: - -- **Git-centric truth**: Every configuration, from UFW rules to crontabs, is stored in the repository. -- **Idempotent automation**: [Actions](/root/glossary#action) are designed to be run multiple times without causing side effects, ensuring the host always matches the intended state. - -## Minimal dependency footprint {#minimalism} - -To ensure long-term maintainability, the framework avoids complex configuration management tools (like Ansible or Salt). Instead, it relies on: - -- **Bash**: The universal language of Unix systems. -- **Docker**: For application isolation and environment consistency. -- **Standard Linux tools**: Leveraging `systemd`, `ufw`, and `cron` directly. - -## Decentralization {#decentralization} - -Each [Node](/root/glossary#node) is an island. While they share the [Commons](/root/glossary#commons) library, they do not depend on a central "master" server. This architecture ensures that a failure in one host does not impact unrelated services. - ---- - -**See also:** - -- [Concept: Security model](/root/concepts/security-model) -- [Concept: Tiered storage](/root/concepts/tiered-storage) diff --git a/services/docs/content/en/root/concepts/security-model.md b/services/docs/content/en/root/concepts/security-model.md deleted file mode 100644 index 3e83e41..0000000 --- a/services/docs/content/en/root/concepts/security-model.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: Security & privilege isolation -description: Security measures, privilege isolation, and project-level sandboxing. -weight: 20 ---- - -Security in Root is achieved through strict privilege isolation and project-level "sandboxing" to mitigate the impact of service compromises. - -## The "No-Root" Principle {#noroot} - -Running applications as `root` inside containers is a significant security risk. The framework enforces isolation via the `tiers/useradd` and `tiers/chown` actions. - -### Project-specific users - -Every project located at `{repository root}/{node}/{project}` is assigned a dedicated system user on the host. - -- **Isolation**: If a container is compromised, the attacker only gains the privileges of that specific low-privileged user. -- **Filesystem safety**: Projects can only read/write to their own directories within the [Tiers](/root/glossary#tier). - -## Docker socket protection {#socket-protection} - -Direct access to `/var/run/docker.sock` is equivalent to root access on the host. As a best practice, it is highly recommended to protect the Docker socket. One way to achieve this is by utilizing a **Socket Proxy** (e.g., based on `tecnativa/docker-socket-proxy`) to filter and restrict access to the Docker API. - -```yaml filename="docker-socket-proxy-example.yml" -services: - socket-proxy: - image: tecnativa/docker-socket-proxy:0 - container_name: root-socket-proxy - user: "0:0" - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - environment: - CONTAINERS: 1 - SERVICES: 1 - TASKS: 1 - networks: - socket: {} - restart: unless-stopped - - traefik: - # ... - depends_on: - - socket-proxy - command: - # Use the proxy instead of the local socket - - "--providers.docker.endpoint=tcp://root-socket-proxy:2375" - networks: - socket: {} -``` - -## Security Monitoring (CrowdSec) {#crowdsec} - -The framework integrates **CrowdSec** for behavioral detection and automated response. - -- **Intrusion detection**: CrowdSec monitors logs from [Traefik](https://traefik.io/) and SSH for suspicious patterns (e.g., brute-force attacks, port scanning). -- **Automated blocking**: When a threat is detected, the **CrowdSec Firewall Bouncer** automatically updates [UFW](https://help.ubuntu.com/community/UFW) rules to block the malicious IP at the host level. -- **Shared threat intelligence**: CrowdSec shares anonymized threat data with its community, providing preemptive protection against known bad actors. - -## Network hardening {#networking} - -Root uses `configure/ufw` to implement a "Default Deny" policy. - -- **Internal routing**: Services communicate over a dedicated `root-proxy` bridge network, which is often configured as `internal: true`. -- **Enclave isolation**: Outgoing traffic can be routed through a dedicated egress node for granular control. - ---- - -**See also:** - -- [Concept: Tiered storage](/root/concepts/tiered-storage) -- [Guide: Action development](/root/guides/action-development) diff --git a/services/docs/content/en/root/concepts/tiered-storage.md b/services/docs/content/en/root/concepts/tiered-storage.md deleted file mode 100644 index 0f419e0..0000000 --- a/services/docs/content/en/root/concepts/tiered-storage.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: Tiered storage model -description: Standardized storage taxonomy for service data. -weight: 15 ---- - -The framework enforces a standardized storage taxonomy. This ensures that every service has a predictable location for its data, which simplifies backup strategies and hardware allocation. - -## The storage taxonomy {#taxonomy} - -Data is divided into three logical [Tiers](/root/glossary#tier) based on its performance requirements, lifecycle, and importance. - -### Tier 1: Configuration & Cache - -**Path:** `${ROOT_NODE_DIR}/@tier1` - -- **Contents**: Config files, small SQLite databases, SSL certificates, application cache. -- **Characteristics**: Extremely high value, low to medium volume, requires low latency. -- **Hardware**: High-speed SSD storage, typically shared with the Operating System. - -### Tier 2: Application Data - -**Path:** `${ROOT_NODE_DIR}/@tier2` - -- **Contents**: User uploads, large databases, persistent application state. -- **Characteristics**: High value, medium to high volume, requires high reliability. -- **Hardware**: Reliable HDD clusters, RAID arrays, or dedicated storage compute. - -### Tier 3: Transients & Bulk Media - -**Path:** `${ROOT_NODE_DIR}/@tier3` - -- **Contents**: Logs, temporary files, bulk media (movies, music), and other non-critical large data. -- **Characteristics**: Low value, very high volume. -- **Hardware**: High-capacity HDDs optimized for continuous sequential write/read (e.g., WD Purple). Note that Tier 3 is **too slow for cache**. - -## Backup strategy {#backup} - -The framework does not enforce a specific backup strategy or provide a default implementation, allowing for complete node-specific flexibility. Operators are expected to implement their own backup logic. - -### Example: Restic backup - -A common best practice is to use **Restic** for backups. For example, you might create an operator compose file to run Restic: - -```yaml filename="operator-compose.yml" -services: - restic: - image: restic/restic:0.18.1 - container_name: operator-restic - volumes: - - ./@tier2/{project}/{service}/{data}:/data/@tier2/{project}/{service}/{data}:ro - - ./@tier1/{project}/{service}/{data}:/data/@tier1/{project}/{service}/{data}:ro - - ./@tier1/.operator/restic/cache:/var/restic-cache - environment: - RESTIC_REPOSITORY: "s3:example.com/bucket" - RESTIC_PASSWORD: ${RESTIC_PASSWORD} - # ... AWS/S3 credentials - network_mode: "host" - entrypoint: [ "restic" ] - user: "0:0" -``` - -### Implementing the strategy - -Operators can implement this strategy by defining a local action in `.operator/local/scripts/actions/sync/tiers`. The `root` dispatcher can then execute this script to trigger the backup, allowing for granular control over how data is persisted. - -## Justification {#justification} - -1. **Hardware optimization**: By mapping tiers to specific hardware (SSDs for Tier 1, RAID for Tier 2, Purples for Tier 3), we optimize for both performance and cost. -2. **Selective backup**: Separating transient logs and bulk media (Tier 3) from critical configs (Tier 1) prevents wasting expensive backup storage. -3. **Architectural clarity**: Any operator can inspect a [Node](/root/glossary#node) directory and immediately understand the storage requirements and priority of its contents. - ---- - -**See also:** - -- [Concept: Infrastructure architecture](/root/concepts/architecture) -- [Reference: ROOT_ API](/root/reference/root-api) diff --git a/services/docs/content/en/root/glossary.md b/services/docs/content/en/root/glossary.md deleted file mode 100644 index 24a7a77..0000000 --- a/services/docs/content/en/root/glossary.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: Glossary -description: Terminology used within the Root infrastructure framework. -weight: 100 ---- - -Terminology used within the Root infrastructure framework. - -## Action {#action} - -**Action** - An atomic automation task located in `scripts/actions/`. Actions follow the "Stupid Action" philosophy, remaining declarative and relying on the `root` dispatcher for environment setup. - -## Commons {#commons} - -**Commons** - The shared repository containing generic logic, namespaced libraries, and standardized automation actions used across all nodes. Referenced at [GitHub: ermnvldmr.com-root-commons](https://github.com/deytenit/ermnvldmr.com-root-commons). - -## Dispatcher {#dispatcher} - -**Dispatcher** - The `root` script that serves as the entrypoint. It resolves paths, warms the environment, and executes the requested [Action](/root/glossary#action). - -## Node {#node} - -**Node** - A physical or virtual host managed by the framework. Each node has a dedicated directory in the configuration repository containing its services and local settings. - -## Root {#root} - -**Root** - Both the name of the command-line utility and the top-level orchestration service within a [Node](/root/glossary#node) (typically handling Traefik and Adguard). - -## Tier {#tier} - -**Tier** - A standardized storage classification for service data. -- **Tier 1**: Configuration and critical state. -- **Tier 2**: Application data and databases. -- **Tier 3**: Logs, caches, and bulk media. - ---- - -**See also:** - -- [Concept: Infrastructure architecture](/root/concepts/architecture) -- [Concept: Tiered storage model](/root/concepts/tiered-storage) diff --git a/services/docs/content/en/root/guides/_index.md b/services/docs/content/en/root/guides/_index.md deleted file mode 100644 index 591c615..0000000 --- a/services/docs/content/en/root/guides/_index.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Guides -description: Step-by-step guides for installation and action development. -weight: 20 ---- - -Step-by-step guides for installing and developing within the ermnvldmr.com root deployment commons framework. - -{{% cards %}} -{{< card link="first-node" title="Setting Up Your First Node" icon="map" subtitle="Practical guide to creating your own config repository." >}} -{{< card link="installation" title="Installation" icon="arrow-down" subtitle="Initial setup of the framework on a new host." >}} -{{< card link="action-development" title="Action development" icon="code" subtitle="Creating and managing atomic automation tasks." >}} -{{% /cards %}} diff --git a/services/docs/content/en/root/guides/action-development.md b/services/docs/content/en/root/guides/action-development.md deleted file mode 100644 index 246f18c..0000000 --- a/services/docs/content/en/root/guides/action-development.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: Action development -description: Developing atomic automation tasks in the Root framework. -weight: 30 ---- - -[Actions](/root/glossary#action) are atomic automation tasks. Following the "Stupid Action" philosophy, they must remain declarative and rely on the library for complex operations. - -## Creating a new action {#create} - -{{% steps %}} - -### Step 1: Create the script file - -Place your script in `scripts/actions/{group}/{name}`. Do not use file extensions. - -### Step 2: Implement metadata - -Every action must provide a description and argument list for the help system. - -```bash filename="scripts/actions/utils/my-action" -action_metadata() { - cat <> ~/.bashrc -log_info "Done. Please run 'source ~/.bashrc' or re-login to your shell." -``` - -Make it executable: -```bash -chmod +x init.sh -``` - -{{% /steps %}} - -## 2. Defining Your First Node - -A Node is a folder at the repository root that represents one physical or virtual server. - -### Node Structure - -Let's create a node named `daedalus`. Inside, we'll define an operator configuration (e.g., for backups) and a core service. - -```bash -mkdir -p daedalus/.operator/configs/{cron,crowdsec,systemd,ufw/docker,ufw/host} -mkdir -p daedalus/root -``` - -### Base Configurations (Optional) - -You can place configuration files (like UFW rules or a crontab) inside the `daedalus/.operator/configs/` directory. For example, a basic crontab: - -```bash filename="daedalus/.operator/configs/cron/crontab.template" -# Run backups every night at 3:00 AM -0 3 * * * root sync tiers daedalus -``` - -## 3. Configuring Services (Docker Compose) - -The framework relies on `docker-compose.yml` to orchestrate services. - -### Node-Level Infrastructure (Operator) - -The `daedalus/docker-compose.yml` file runs infrastructure utilities, such as `restic` for backups or VPN agents. This compose file has direct access to the filesystem via `@tierX` mounts. - -```yaml filename="daedalus/docker-compose.yml" -name: 'operator' - -services: - restic: - image: restic/restic:0.18.1 - container_name: operator-restic - volumes: - # Example: mounting project data for backups (Read-Only) - - ./@tier2/my-app/data:/data/@tier2/my-app/data:ro - - ./@tier3/.operator/restic/cache:/var/restic-cache - environment: - RESTIC_REPOSITORY: "s3:example.com/my-bucket/daedalus" - RESTIC_PASSWORD: "${RESTIC_PASSWORD?error}" - # AWS credentials... - network_mode: "host" - entrypoint: [ "restic" ] -``` - -### The Root Project - -The `root` project typically contains your reverse proxies (Traefik) and core services that other projects will route through. - -```yaml filename="daedalus/root/docker-compose.yml" -name: root - -services: - socket-proxy: - image: tecnativa/docker-socket-proxy:0 - container_name: root-socket-proxy - user: "0:0" - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - environment: - CONTAINERS: 1 - SERVICES: 1 - TASKS: 1 - networks: - socket: {} - restart: unless-stopped - - traefik: - image: traefik:3.6 - container_name: root-traefik - # UID and GID are automatically populated by the framework after running 'root tiers useradd' - user: "${UID?error}:${GID?error}" - group_add: - - "${SHARED_GID?error}" - depends_on: - - socket-proxy - volumes: - - ./@tier1/shared/root/traefik/letsencrypt:/letsencrypt - - ./@tier3/traefik/logs:/logs - - ./@tier1/traefik/dynamic:/etc/traefik/dynamic:ro - ports: - - '0.0.0.0:80:80' - - '0.0.0.0:443:443' - networks: - proxy: {} - socket: {} - command: - - "--api.dashboard=true" - - "--providers.docker=true" - - "--providers.docker.network=root-proxy" - - "--providers.docker.endpoint=tcp://root-socket-proxy:2375" - restart: unless-stopped - -networks: - proxy: - name: root-proxy - internal: true - driver: bridge - socket: - name: root-socket - internal: true - driver: bridge -``` - -## 4. Deployment - -Now that your structure is ready: - -1. Commit and push this repository to your Git server (e.g., GitHub). -2. SSH into your VPS. -3. Follow the [Installation](/root/guides/installation) guide, using your new repository URL instead of the example ones. - ---- - -**See also:** - -- [Guide: Installation on a new host](/root/guides/installation) -- [Concept: Infrastructure Architecture](/root/concepts/architecture) diff --git a/services/docs/content/en/root/guides/installation.md b/services/docs/content/en/root/guides/installation.md deleted file mode 100644 index 18df0e7..0000000 --- a/services/docs/content/en/root/guides/installation.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -title: Initial Host Setup -description: Setting up a fresh Debian host from scratch. -weight: 1 ---- - -Hardened setup for a fresh Debian host from zero to deployment. - -## Setup Procedure - -{{% steps %}} - -### Essential Packages - -Install `sudo` and `docker-ce` first. This is necessary because the subsequent user setup relies on the `docker` group and `sudo` configuration. - -**Install Sudo** - -```bash -# As root: -apt update && apt install sudo -y -``` - -**Install Docker** - -Follow the [Official Docker Installation Guide for Debian](https://docs.docker.com/engine/install/debian/) to install the latest Docker Engine. - -### System User & Privileges - -The `adam` user handles all administrative tasks. SSH-key authentication and passwordless `sudo` via the `wheel` group minimize friction while maintaining security. - -**Create the Admin User** - -```bash -# As root: -# Create the user with a bash shell -useradd -m -s /bin/bash adam - -# Create the wheel group (common for cross-distro consistency) -groupadd wheel - -# Create a modular sudoers file -# This allows members of 'wheel' to run sudo without a password -echo "%wheel ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/99-custom-sudoers - -# Validate syntax -visudo -c -f /etc/sudoers.d/99-custom-sudoers - -# Add adam to the necessary groups -usermod -aG wheel,docker adam -``` - -### Swap Setup - -Configure a swap file to ensure system stability during memory-intensive operations. - -```bash -# As root: -# Create a 2GB swap file (adjust size as needed) -fallocate -l 2G /swap -chmod 600 /swap -mkswap /swap -swapon /swap - -# Make it permanent -echo '/swap none swap sw 0 0' >> /etc/fstab -``` - -### SSH Access & Hardening - -Passwords are disabled. Access is strictly via SSH keys. - -**Authorize Operator Key** - -Import your local public key to the `adam` user. - -```bash -# As root: -# Setup directories -mkdir -p /home/adam/.ssh -chmod 700 /home/adam/.ssh - -# Add your public key (Replace [PASTE_PUB_KEY_HERE]) -echo "[PASTE_PUB_KEY_HERE]" > /home/adam/.ssh/authorized_keys -chmod 600 /home/adam/.ssh/authorized_keys -chown -R adam:adam /home/adam/.ssh -``` - -**Operator Side Access** - -Configure your local machine for easy access to the host. - -```bash -# ~/.ssh/config on operator side -Host daedalus.example.com - Port 2222 - User adam - IdentityFile ~/.ssh/adam_example_com_ed25519 -``` - -**Harden SSH Daemon** - -Modify the SSH configuration to change the default port and disable password entry. - -```bash -# As root: -# Create a dedicated override config -cat < /etc/ssh/sshd_config.d/99-custom-ssh.conf -Port 2222 -PasswordAuthentication no -PermitEmptyPasswords no -AllowUsers adam -EOF - -# Validate syntax before restarting to avoid lockout -sshd -t && systemctl restart ssh -``` - -### GitHub Access (Deploy Key) - -The host requires its own identity to pull updates from the GitHub repository. - -```bash -# As root: -# Generate a host-specific SSH key (no passphrase for automation) -sudo -u adam ssh-keygen -t ed25519 -f /home/adam/.ssh/github_ed25519 -N "" - -# Configure SSH to use this key for GitHub -cat < Deploy Keys) -cat /home/adam/.ssh/github_ed25519.pub -``` - -> [!TIP] -> Add the output above to the Deploy Keys settings of your infrastructure repository (e.g., `https://github.com/your-username/your-repo/settings/keys`) with **read access**. - -### Repository Deployment - -Clone your infrastructure repository and initialize the node. - -```bash -# As root: -# Setup the service directory -export REPO_DIR="/srv/your-infrastructure-repo" -mkdir -p $REPO_DIR -chown adam:adam $REPO_DIR - -# Clone as the adam user -sudo -u adam git clone git@github.com:your-username/your-repo.git $REPO_DIR - -# Initialize node (Set your node name, e.g., daedalus) -export NODE="daedalus" -cd $REPO_DIR -sudo -u adam ./init.sh -``` - -**Node-Specific Configuration** - -Run the staged initialization scripts using the `root` dispatcher: - -```bash -# Run the sequence for your specific node (as the 'adam' user) -# Ensure you have sourced ~/.bashrc or re-logged in if 'root' is not found -root configure base $NODE -root configure ufw $NODE -root configure crowdsec $NODE -root configure cron $NODE -``` - -### Storage & Hardening - -Define the data tiers and secure the environment by creating non-root users for containerized services. - -```bash -# Create (or mount) storage directories -sudo mkdir -p /srv/my-infrastructure-root-$NODE-{tier1,tier2,tier3} - -# Setup tiers and non-root users -root tiers link $NODE \ - /srv/my-infrastructure-root-$NODE-tier1 \ - /srv/my-infrastructure-root-$NODE-tier2 \ - /srv/my-infrastructure-root-$NODE-tier3 - -root tiers useradd $NODE -root tiers chown $NODE -``` - -{{% /steps %}} - ---- - -**See also:** - -- [Doc: Docker - Install on Debian](https://docs.docker.com/engine/install/debian/) diff --git a/services/docs/content/en/root/reference/_index.md b/services/docs/content/en/root/reference/_index.md deleted file mode 100644 index 5a49bad..0000000 --- a/services/docs/content/en/root/reference/_index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Reference -description: API and technical references for developers. -weight: 30 ---- - -Technical reference materials and APIs for the ermnvldmr.com root deployment commons framework. - -{{% cards %}} -{{< card link="compose" title="Compose actions reference" icon="play" subtitle="High-level entrypoint for orchestrating docker-compose." >}} -{{< card link="configure" title="Configure actions reference" icon="arrow-down" subtitle="Host provisioning and system-level configuration." >}} -{{< card link="initialization" title="Initialization actions reference" icon="play" subtitle="Actions for initial node setup." >}} -{{< card link="root-api" title="ROOT_ API reference" icon="code" subtitle="Standardized environment variables and logging helpers." >}} -{{< card link="source" title="Source services reference" icon="book-open" subtitle="Shared services built from source." >}} -{{< card link="sync" title="Sync actions reference" icon="check" subtitle="Actions for keeping nodes up-to-date." >}} -{{< card link="tiers" title="Tiers actions reference" icon="archive" subtitle="Storage tiers management." >}} -{{< card link="utils" title="Utility actions reference" icon="check" subtitle="Helper scripts and utilities." >}} -{{% /cards %}} diff --git a/services/docs/content/en/root/reference/compose.md b/services/docs/content/en/root/reference/compose.md deleted file mode 100644 index 21e88ea..0000000 --- a/services/docs/content/en/root/reference/compose.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Compose Actions -description: Standardized high-level entrypoint for orchestrating docker-compose across a node. -weight: 54 ---- - -The `compose` action provides a standardized, high-level entrypoint for orchestrating Docker Compose files across all projects within a specific node. - -## Core Compose Action {#actions} - -| Action | Description | -| :--- | :--- | -| `compose ` | Executes a given Docker Compose command (e.g., `up`, `down`, `restart`) across the node's infrastructure. | - -## Orchestration Order {#order} - -To maintain correct dependencies (especially when shutting down or starting up infrastructure-level proxies and networks), the `compose` action intelligently orders the execution: - -### Starting Up (`up`, `restart`) -When starting or restarting services, the action follows a **Forward Order**: -1. **Node Infrastructure**: First, it processes the node-level `docker-compose.yml` (located at the root of the node directory). -2. **Root Infrastructure**: Next, it processes the `root/docker-compose.yml` project, if it exists (usually contains Traefik, Socket Proxy, etc.). -3. **Projects**: Finally, it processes all other project directories in alphabetical order. - -### Shutting Down (`down`) -When stopping services, the action uses a **Reverse Order** to ensure projects disconnect gracefully before the network or proxy goes down: -1. **Projects**: All standard projects are stopped in reverse alphabetical order. -2. **Root Infrastructure**: The `root/docker-compose.yml` project is stopped. -3. **Node Infrastructure**: Finally, the node-level `docker-compose.yml` is brought down. - -## Options {#options} - -You can pass standard Docker Compose arguments to the end of the command. -Additionally, the action supports a dry-run mode: - -- `--dry-run`: Prints the commands that would be executed without actually running them. - -**Example usage:** -```bash -root compose daedalus up -d --remove-orphans -root compose daedalus restart --dry-run -root compose daedalus down -``` - ---- - -**See also:** - -- [Concept: Infrastructure Architecture](/root/concepts/architecture) -- [Reference: ROOT_ API Reference](/root/reference/root-api) diff --git a/services/docs/content/en/root/reference/configure.md b/services/docs/content/en/root/reference/configure.md deleted file mode 100644 index f75c200..0000000 --- a/services/docs/content/en/root/reference/configure.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: Configuration Actions -description: Host provisioning, template engine, and system-level configuration. -weight: 53 ---- - -Configuration actions are used to provision the host and maintain system-level services. They rely heavily on the built-in template engine to generate declarative configuration files. - -## The Template Engine {#template-engine} - -The Root framework uses `envsubst` (from `gettext-base`) to render templates. This allows you to use standard Bash environment variables directly within your configuration files. - -### Template Conventions - -- **File Extension**: Templates typically use the `.template` extension (e.g., `crontab.template`). -- **Variable Syntax**: Use `${VARIABLE_NAME}` or `$VARIABLE_NAME` to inject values. -- **Auto-Discovery**: Many actions automatically look for templates in specific directories within the [Configs](/root/glossary#configs) repository. - -### Rendering Helpers - -The `root_template.sh` library provides several helpers: - -- `root_template_render `: Renders a single file. -- `root_template_render_directory `: Recursively renders an entire directory structure. -- `root_template_crontab