docs: add ermnvldmr platform architecture and operations guide (en/ru), remove deprecated root section (#43)

### Summary of Changes

- **Added `ermnvldmr` Platform Documentation (English & Russian)**:
  - `_index.md`: Overview and navigation cards
- `architecture.md`: End-to-end architecture (Packer, Cloud-Init, K3s,
Flux v2, Cloudflare) with Mermaid diagram
- `golden-image.md`: Packer QEMU build pipeline, S3 storage & quota
pruning
- `deployment-gitops.md`: Declarative Flux GitOps, release pipelines,
fast-track deploys, and automated `/version.json` rollout validation
- `operations.md`: SSH access, SOPS + Age secret encryption, PostgreSQL
storage, S3 backups, and Cloudflare configuration
- **Deprecated Section Cleanup**:
- Deleted obsolete `services/docs/content/en/root/` and
`services/docs/content/ru/root/`
This commit is contained in:
deytenit authored and GitHub committed 2026-08-23 18:12:25 +03:00
1 parent 9e129ccfb8
commit 7e0969ebbb
52 files changed
+766 -2415

No files matched your search

+1 -1
View File
@@ -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 >}}
@@ -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.
@@ -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.
@@ -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 <service> <previous_tag>`.
* **Emergency Kubernetes Rollback**: Run `kubectl rollout undo deployment/<service> -n com-ermnvldmr` on the cluster for instant 2-second rollback.
@@ -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://<bucket>/dev/images/com-ermnvldmr-debian-12-k3s-amd64-<git_short_sha>.qcow2
```
---
## 3. Naming Convention
Images follow a deterministic naming structure based on the git commit:
```text
com-ermnvldmr-debian-12-k3s-amd64-<short_sha>.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.
@@ -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@<SERVER_IP>
```
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<YOUR_PUBLIC_AGE_KEY>'
```
> **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://<bucket>/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.
-39
View File
@@ -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)
@@ -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 %}}
@@ -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** &rarr; Locating the `commons` and `configs` repositories.
- **Library warming** &rarr; Sourcing namespaced modules exactly once.
- **Context establishment** &rarr; 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)
@@ -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)
@@ -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)
@@ -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)
-41
View File
@@ -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)
@@ -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 %}}
@@ -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 <<EOF
description: "Brief summary of the task."
args:
- NODE: "The node name"
- PARAM: "A custom parameter"
EOF
}
```
### Step 3: Initialize context
Use the `root_require_node` helper to establish the environment. This must be the first functional step in your script.
```bash filename="scripts/actions/utils/my-action"
root_require_node "${1:-}"
shift
```
### Step 4: Use namespaced helpers
Perform operations using the `root_*` library functions. Rely on `ROOT_` environment variables for all pathing.
```bash filename="scripts/actions/utils/my-action"
root_log_info "Processing node $ROOT_NODE"
root_sys_restart_service "my-service"
```
{{% /steps %}}
## Library namespaces {#libraries}
Actions have access to the following modules:
- `root_core_*`: Logging and Telegram notifications.
- `root_init_*`: Declarative service initialization and package management.
- `root_sys_*`: Systemd and unit file management.
- `root_template_*`: Envsubst-based rendering and configuration injection.
- `root_validate_*`: Input, file, and OS validation.
---
**See also:**
- [Reference: ROOT_ API reference](/root/reference/root-api)
- [Concept: Infrastructure architecture](/root/concepts/architecture)
@@ -1,190 +0,0 @@
---
title: "Setting Up Your First Node"
description: A practical guide on creating your first node and hooking up the deployment commons.
weight: 25
---
**Goal:** Create a configuration repository for your infrastructure, add the root deployment commons as a submodule, and define your first basic node.
## 1. Creating the Configuration Repository
Your infrastructure should be managed from a single Git repository. This repository will hold the configuration for all your servers (nodes).
{{% steps %}}
### Step 1: Initialize the repository
Create a new directory and initialize Git.
```bash
mkdir my-infrastructure
cd my-infrastructure
git init
```
### Step 2: Add the commons submodule
The `ermnvldmr.com-root-commons` must be placed at `.operator/shared`.
```bash
mkdir -p .operator
git submodule add https://github.com/deytenit/ermnvldmr.com-root-commons.git .operator/shared
```
### Step 3: Create the Bootstrap Script
Create an `init.sh` file at the root of your repository. This script links the commons framework into your local environment.
```bash filename="init.sh"
#!/usr/bin/env bash
# init.sh
# Source common utilities from the submodule
source "$(git -C "$(dirname "$0")" rev-parse --show-toplevel)/.operator/shared/scripts/lib/common.sh"
SCRIPT_NAME="init"
navigate_to_repo_root
log_info "Setting up Git hooks..."
git config core.hooksPath .operator/shared/githooks
git config --global --add safe.directory "${REPO_ROOT}"
log_info "Setting up PATH for the root dispatcher..."
ABSOLUTE_RUN_DIR="$(realpath "${REPO_ROOT}/.operator/shared/scripts/run")"
BASHRC_ENTRY="export PATH=\"${ABSOLUTE_RUN_DIR}:\$PATH\""
sed -i '/\.operator\/shared\/scripts\/run/d' ~/.bashrc
echo "$BASHRC_ENTRY" >> ~/.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)
@@ -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 <<EOF > /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 <<EOF | sudo -u adam tee /home/adam/.ssh/config
Host github.com
AddKeysToAgent yes
IdentityFile ~/.ssh/github_ed25519
EOF
# Display the public key to be added to GitHub (Settings > 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/)
@@ -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 %}}
@@ -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 <node> <action>` | 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)
@@ -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 <input> <output>`: Renders a single file.
- `root_template_render_directory <src> <dest>`: Recursively renders an entire directory structure.
- `root_template_crontab <template>`: Renders and installs a crontab for the current user.
## Core Configuration Actions {#actions}
| Action | Description |
| :--- | :--- |
| `configure/base` | Installs essential packages (`sudo`, `ufw`, `docker`) and sets up basic system users. |
| `configure/cron` | Renders and installs node-specific crontabs. |
| `configure/crowdsec` | Sets up the CrowdSec agent and bouncers. |
| `configure/routing` | Configures system-level routing and bridge networks. |
| `configure/systemd` | Installs and enables systemd service units. |
| `configure/ufw` | Renders and applies firewall rules using UFW and `ufw-docker`. |
## Example: Nginx Template {#example}
```nginx filename="nginx.conf.template"
# This template uses ROOT_NODE environment variable
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Injected from environment
server_name ${ROOT_NODE}.example.com;
}
```
---
**See also:**
- [Concept: Infrastructure Architecture](/root/concepts/architecture)
- [Reference: ROOT_ API Reference](/root/reference/root-api)
@@ -1,40 +0,0 @@
---
title: System Initialization
description: Repository setup, Git hooks, and PATH configuration.
weight: 51
---
The Root framework requires a one-time initialization on each host to establish path linkages and repository-level configurations.
## The `init.sh` Script {#init-script}
The `init.sh` script located at the repository root is the primary bootstrap mechanism. It performs the following critical tasks:
1. **Submodule Initialization**: Ensures the [Commons](/root/glossary#commons) repository is present and up to date.
2. **Git Hook Configuration**: Points `core.hooksPath` to `.operator/shared/githooks` to enable standardized pre-commit checks.
3. **Safe Directory Registration**: Adds the repository to Git's `safe.directory` list, which is required for operations performed by different users (e.g., `root`, `adam`).
4. **Vim Configuration**: Links a standardized `.vimrc` to both the current user and the `root` user for a consistent editing experience.
5. **PATH Persistence**: Adds the `.operator/shared/scripts/run` directory to the user's `~/.bashrc`, making the `root` command available globally.
## Git Hooks {#githooks}
Root enforces standards through Git hooks stored in `.operator/shared/githooks/`.
- **Pre-commit**: Validates that all scripts follow the namespacing and structure conventions.
- **Commit-msg**: (Optional) Enforces conventional commit messages if configured.
## PATH Configuration {#path}
The `root` command is a wrapper located in `.operator/shared/scripts/run/root`. By adding this directory to the `PATH`, the dispatcher can be invoked from any directory within the system, automatically resolving the repository root based on the current working directory or environment variables.
```bash
# Example of manual PATH addition (performed automatically by init.sh)
export PATH="$HOME/repo/.operator/shared/scripts/run:$PATH"
```
---
**See also:**
- [Guide: Initial Host Setup](/root/guides/installation)
- [Reference: ROOT_ API Reference](/root/reference/root-api)
@@ -1,69 +0,0 @@
---
title: ROOT_ API reference
description: Standardized environment variables for path resolution and node context.
weight: 50
---
Every [Action](/root/glossary#action) script executed via the `root` dispatcher has access to a standardized set of environment variables and Bash libraries. This provides a consistent "API" for interacting with the infrastructure.
## The `root` Dispatcher {#dispatcher}
The `root` command (located in `.operator/shared/scripts/run/root`) is the main entrypoint for all orchestration. Its primary responsibilities include:
1. **Context Resolution**: Locating the target [Node](/root/glossary#node) and its associated storage [Tiers](/root/glossary#tier).
2. **Library Loading**: Sourcing the core namespaced libraries (e.g., `root_core`, `root_sys`).
3. **Action Execution**: Discovering and running the requested action, prioritizing local overrides.
## Path resolution variables {#paths}
These variables are established by the dispatcher and are available to all actions.
| Variable | Description |
| :--- | :--- |
| `ROOT_SHARED` | Absolute path to the [Commons](/root/glossary#commons) repository. |
| `ROOT_CONFIGS` | Absolute path to the main configuration repository. |
| `ROOT_LOCAL` | Absolute path to the local operator directory (`.operator/local`). |
| `ROOT_ACTIONS_SHARED` | Path to the global shared actions. |
| `ROOT_ACTIONS_LOCAL` | Path to node-specific local actions. |
## Node context variables {#node-context}
When an action targets a specific node, the following variables are established by the `root_require_node` helper.
| Variable | Description |
| :--- | :--- |
| `ROOT_NODE` | The identifier of the target node (e.g., `daedalus`). |
| `ROOT_NODE_DIR` | Absolute path to the node configuration directory. |
| `ROOT_TIER1` | Absolute path to the [Tier 1](/root/glossary#tier) storage directory. |
| `ROOT_TIER2` | Absolute path to the Tier 2 storage directory. |
| `ROOT_TIER3` | Absolute path to the Tier 3 storage directory. |
## Core Logging Helpers {#logging}
Standardized logging ensure consistent output across all actions.
- `root_log_info`: Standard informational output.
- `root_log_warn`: Warnings requiring attention.
- `root_log_error`: Critical errors sent to `stderr`.
- `root_log_success`: Confirmation of successful task completion.
## The Help System {#help}
The dispatcher provides a built-in help system by parsing an `action_metadata` block at the top of each script. This allows scripts to remain "stupid" and declarative without implementing their own CLI argument parsing.
```bash filename="example-action-metadata"
action_metadata() {
cat <<EOF
description: "Brief summary of the action."
args:
- NODE: "The name of the target node."
EOF
}
```
---
**See also:**
- [Concept: Infrastructure principles](/root/concepts/principles)
- [Guide: Action development](/root/guides/action-development)
@@ -1,42 +0,0 @@
---
title: The `source/` Directory
description: Conceptual overview of the self-contained source directory structure.
weight: 52
---
The `source/` directory at the repository root contains the core components and projects that the Root framework orchestrates. It is designed for maximum isolation and self-containment.
## Core Philosophy {#philosophy}
The `source/` directory is not just a place to store code; it is a collection of independent [Projects](/root/glossary#project). Each project within this directory should follow these principles:
1. **Isolation**: Each project lives in its own subdirectory (e.g., `source/my-app/`).
2. **Self-Documentation**: Each project directory **MUST** contain its own `README.md` file describing its purpose, dependencies, and configuration.
3. **Internal Logic**: Projects handle their own build processes, Dockerfiles, and internal configurations. The Root framework's [Actions](/root/glossary#action) simply orchestrate these existing components.
## Directory Structure {#structure}
A typical project within the `source/` directory might look like this:
{{< filetree/container >}}
{{< filetree/folder name="source" state="open" >}}
{{< filetree/folder name="happ-subscription-generator" state="open" >}}
{{< filetree/file name="Dockerfile" >}}
{{< filetree/file name="generator.py" >}}
{{< filetree/file name="README.md" >}}
{{< /filetree/folder >}}
{{< /filetree/folder >}}
{{< /filetree/container >}}
## Relationship with Actions {#actions}
Root actions (like `compose` or `sync`) interact with the `source/` directory by referencing paths within it. For example, the `compose` action might use a `docker-compose.yml` file that points to a `Dockerfile` located in `source/app/`.
This separation of concerns ensures that the orchestration logic (Actions) remains decoupled from the implementation details (Source).
---
**See also:**
- [Concept: Infrastructure Architecture](/root/concepts/architecture)
- [Reference: ROOT_ API Reference](/root/reference/root-api)
@@ -1,36 +0,0 @@
---
title: Synchronization Actions
description: Repository updates, package synchronization, and data backups.
weight: 54
---
Synchronization actions ensure that the host's state remains consistent with the defined configurations in the remote repositories.
## Core Synchronization Actions {#actions}
| Action | Description |
| :--- | :--- |
| `sync/packages` | Synchronizes node packages and their configurations across the system. |
| `sync/repository` | Updates the main configuration repository to its latest state from GitHub. |
| `sync/tiers` | Triggers the node-specific backup strategy for the configured [Tiers](/root/glossary#tier). |
## Repository Synchronization (`sync/repository`) {#repository}
The `sync/repository` action is responsible for keeping the host's configuration repository up-to-date with its remote source. It typically performs a `git pull` on the main configuration repository and may optionally trigger sub-module updates for the [Commons](/root/glossary#commons) repository.
This ensures that any changes to the node configurations, actions, or source files are correctly pulled down to the target host.
## Backup Synchronization (`sync/tiers`) {#tiers}
The `sync/tiers` action is the primary entry point for a node's backup strategy.
- **No Default Implementation**: The framework itself does not provide a default backup mechanism, allowing operators to design a custom strategy suitable for their needs.
- **Custom Overrides**: As a "Smart Dispatcher" action, you can define your backup logic by placing a custom script in `.operator/local/scripts/actions/sync/tiers`.
- **Example Implementation**: A common practice is to use a tool like [Restic](https://restic.net/) within this custom script to perform off-site backups of critical data (Tiers 1 and 2) to an S3-compatible storage backend.
---
**See also:**
- [Concept: Tiered Storage Model](/root/concepts/tiered-storage)
- [Reference: ROOT_ API Reference](/root/reference/root-api)
@@ -1,44 +0,0 @@
---
title: Tier Management Actions
description: Storage classification, symbolic linking, and privilege isolation.
weight: 55
---
Tier management actions are responsible for enforcing the framework's [Tiered Storage Model](/root/concepts/tiered-storage) and ensuring correct filesystem ownership and isolation.
## Core Tier Actions {#actions}
| Action | Description |
| :--- | :--- |
| `tiers/chown` | Sets correct filesystem ownership for project-specific [Non-Root Users](#useradd). |
| `tiers/link` | Manages symbolic links between the project directories and their corresponding [Tiers](/root/glossary#tier). |
| `tiers/useradd` | Provisions a unique system user for each project to achieve [Privilege Isolation](/root/concepts/security-model). |
## User Management (`tiers/useradd`) {#useradd}
The `tiers/useradd` action creates a dedicated, low-privileged system user for each project within a node. This user is then used to run the project's containers, ensuring that a compromise of one project does not grant the attacker access to the entire host.
- **Naming Convention**: Users are typically named after the project.
- **Group Membership**: Users can optionally be added to the `docker` group or interact with Docker via other securely configured methods, depending on the operator's preference.
## Storage Linking (`tiers/link`) {#link}
The `tiers/link` action creates the symbolic link structure required for the tiered storage model. It ensures that directories like `config`, `data`, and `logs` within a project folder point to their physical locations in `@tier1`, `@tier2`, and `@tier3` respectively.
```bash
# Example link structure created by tiers/link
/srv/root/icarus/synapse/config -> /srv/storage/@tier1/synapse
/srv/root/icarus/synapse/data -> /srv/storage/@tier2/synapse
/srv/root/icarus/synapse/logs -> /srv/storage/@tier3/synapse
```
## Ownership Management (`tiers/chown`) {#chown}
Once tiers and links are established, the `tiers/chown` action ensures that the physical directories in each tier are owned by the correct project user. This is critical for preventing permission-denied errors and ensuring that projects can only access their own data.
---
**See also:**
- [Concept: Tiered Storage Model](/root/concepts/tiered-storage)
- [Concept: Security & Privilege Isolation](/root/concepts/security-model)
@@ -1,37 +0,0 @@
---
title: Utility Actions
description: Common helper scripts for maintenance, validation, and certificate management.
weight: 56
---
Utility actions provide common helper functions for node maintenance, validation, and project-specific tasks.
## Core Utility Actions {#actions}
| Action | Description |
| :--- | :--- |
| `utils/extract-traefik-certs` | Extracts SSL/TLS certificates and private keys from Traefik's `acme.json` storage. |
| `utils/generate-happ-subscriptions` | Automatically generates HApp subscription files based on current project metadata. |
| `utils/lint-docker-compose` | Performs a static analysis of all `docker-compose.yml` files to ensure they meet the framework's standards. |
## Certificate Management (`utils/extract-traefik-certs`) {#certificates}
Traefik stores its ACME-issued certificates (like those from Let's Encrypt) in a single `acme.json` file. The `utils/extract-traefik-certs` action parses this file and extracts individual `fullchain.pem` and `privkey.pem` files.
This is particularly useful when other services (e.g., mail servers, non-Dockerized applications) require the same SSL certificates.
## Quality Assurance (`utils/lint-docker-compose`) {#linting}
To maintain consistency and security, the `utils/lint-docker-compose` action validates all compose files across the infrastructure. It checks for:
- **Naming Standards**: Ensures project names and container names follow the `{node}-{project}` convention.
- **Security Context**: Flags containers running as `root` without a justified override.
- **Resource Constraints**: Identifies services lacking CPU or memory limits.
- **Label Standards**: Validates required labels for routing (e.g., [Traefik](https://traefik.io/)) and [CrowdSec](/root/concepts/security-model#crowdsec).
---
**See also:**
- [Concept: Infrastructure Principles](/root/concepts/principles)
- [Concept: Security & Privilege Isolation](/root/concepts/security-model)
+1 -1
View File
@@ -7,7 +7,7 @@ title: 'Документация ermnvldmr.com'
Добро пожаловать в единую документацию для моих собственных проектов
{{< cards >}}
{{< card link="ermnvldmr" title="Платформа ermnvldmr.com" icon="cloud" subtitle="Cloud-native инфраструктура, golden image на Packer, K3s кластер и GitOps" >}}
{{< card link="/en/apex" title="apex.ermnvldmr.com" icon="server" subtitle="Fleet operations framework (English only)" >}}
{{< card link="quetza" title="Quetza Bot" icon="terminal" subtitle="Документация модульного фреймворка Discord-бота" >}}
{{< card link="root" title="ermnvldmr.com-root-commons (deprecated)" icon="archive" subtitle="Устарело — заменено фреймворком apex" >}}
{{< /cards >}}
@@ -0,0 +1,32 @@
---
title: "Платформа ermnvldmr.com"
weight: 1
type: docs
cascade:
type: docs
---
**Платформа ermnvldmr.com** — это облачная инфраструктура, автоматизированный сборочный пайплайн и GitOps-система доставки, обеспечивающая работу всех сервисов `ermnvldmr.com`.
Платформа построена на принципах Infrastructure as Code, неизменяемых golden-образах ОС, сквозном шифровании секретов в Git, непрерывной автоматической синхронизации и бесшовных (zero-downtime) обновлениях.
---
## Разделы документации
{{% cards %}}
{{< card link="architecture" title="Архитектура и потоки данных" icon="server" subtitle="Сквозная архитектура: Packer, Cloud-Init, K3s, Flux GitOps и Cloudflare." >}}
{{< card link="golden-image" title="Автоматизация Golden Image" icon="cube" subtitle="Сборочный пайплайн Packer на базе QEMU, запекание ядра и K3s, хранение в S3 и управление квотами." >}}
{{< card link="deployment-gitops" title="GitOps и пайплайн релизов" icon="refresh" subtitle="Непрерывный деплой, семантические релизы, fast-track деплои и проверка готовности через /version.json." >}}
{{< card link="operations" title="Эксплуатация и регламенты" icon="shield-check" subtitle="SSH-доступ, шифрование SOPS Age, постоянное хранилище SSD, резервное копирование и восстановление." >}}
{{% /cards %}}
---
## Ключевые характеристики платформы
* **Неизменяемые Golden Images**: Стандартизированная база Debian 12 + K3s, собираемая через Packer и QEMU, изолированная от machine-id и хранимая в S3.
* **Автономная инициализация первого запуска**: Cloud-Init автоматически настраивает диск, безопасность ядра, файрвол, ключи Age и запускает Flux GitOps без необходимости подключения к серийной консоли.
* **Декларативный GitOps-движок**: Flux v2 непрерывно синхронизирует состояние Kubernetes-кластера с веткой `next` в GitHub.
* **Сквозное шифрование**: SOPS + Age шифрует все секреты в репозитории; Let's Encrypt и Cloudflare Full (Strict) защищают внешний трафик.
* **Автоматическая верификация раскатки**: Релизные пайплайны опрашивают публичный эндпоинт `/version.json`, подтверждая успешную доставку коммита реальным пользователям.
@@ -0,0 +1,114 @@
---
title: "Архитектура и потоки данных"
weight: 2
type: docs
---
Архитектура инфраструктуры `ermnvldmr.com` объединяет запекание неизменяемых образов ОС, автономную bootstrap-инициализацию через cloud-init и декларативную GitOps-синхронизацию Flux в единую надежную модель развертывания.
---
## 1. Общая схема системы
```mermaid
flowchart TD
subgraph GitHub ["Инфраструктура GitHub"]
Repo["Git-репозиторий (ветка next)"]
Workflows["GitHub Actions пайплайны"]
GHCR["GitHub Container Registry (GHCR)"]
end
subgraph S3 ["Объектное S3-хранилище"]
GoldenImage["Packer Golden Image (.qcow2)"]
Backups["Ежедневные бэкапы PostgreSQL"]
end
subgraph Cloud ["Облачная инфраструктура / Платформа Compute"]
subgraph VM ["Виртуальная машина Compute"]
subgraph OS ["Debian 12 Bookworm"]
CloudInit["Cloud-Init First-Boot"]
UFW["Файрвол UFW (80, 443, 22)"]
SSD["Постоянный SSD (/dev/vdb /var/lib/rancher/k3s/storage)"]
end
subgraph K3s ["Кластер K3s (Single-Node)"]
Flux["Оператор Flux v2"]
Traefik["Traefik Ingress (HostPort 80/443)"]
CertManager["Cert-Manager (Let's Encrypt Prod)"]
subgraph Apps ["Сервисы кластера (com-ermnvldmr)"]
WWW["www (React 19 SSG + Nginx)"]
Docs["docs (Hugo + Hextra + Nginx)"]
Postgres["PostgreSQL 16 StatefulSet"]
Umami["Сервер аналитики Umami"]
BackupCron["CronJob бэкапа Postgres в S3"]
end
end
end
end
subgraph Edge ["Cloudflare Edge"]
CF["Прокси Cloudflare (Full Strict)"]
end
Users["Пользователи"] --> CF
CF --> Traefik
Traefik --> WWW
Traefik --> Docs
Traefik --> Umami
Umami --> Postgres
BackupCron --> Backups
Workflows --> GHCR
Workflows --> GoldenImage
Repo --> Flux
Flux --> Apps
```
---
## 2. Фазы жизненного цикла платформы
### Фаза 1: Сборка Golden Image (Packer)
1. **Автоматический запуск**: GitHub Actions выполняет `.github/workflows/ci-next-build-golden-image.yml`.
2. **QEMU-виртуализация**: Packer запускает виртуальную установку Debian 12 с автоматизацией preseed (`preseed.cfg`).
3. **Инициализация**:
* Установка системных утилит (`curl`, `git`, `htop`, `fail2ban`, `ufw`, `qemu-guest-agent`, `isc-dhcp-client`).
* Настройка `/etc/cloud/ds-identify.cfg` с `policy: enabled` для гарантированного старта cloud-init.
* Предустановка бинарного файла K3s (`INSTALL_K3S_SKIP_ENABLE=true`, `INSTALL_K3S_SKIP_START=true`) в `/usr/local/bin/k3s`.
* Сброс идентичности хоста (`/etc/machine-id`, DBus ID, ключи SSH, сетевые кэши).
4. **Сжатие и загрузка в S3**: Образ конвертируется в `qcow2`, старые образы в `dev/images/` автоматически удаляются для соблюдения квот хранилища, и готовый образ загружается в объектное S3-хранилище.
---
### Фаза 2: Автономный первый запуск (Cloud-Init)
При создании виртуальной машины с метаданными `ci/cloud-init/user-data.template.yaml`:
1. **Настройка пользователей и сети**:
* Создание пользователя `adam` с публичным SSH-ключом и правами sudo без пароля.
* Отключение парольной аутентификации и прямого доступа root по SSH.
* Конфигурация fallback DNS-серверов (`1.1.1.1`, `8.8.8.8`, `77.88.8.8`).
2. **Харденинг ядра и безопасность**:
* Применение правил sysctl (защита от SYN Flood, запрет ICMP redirects, фильтрация обратного пути rp_filter).
* Настройка UFW: открыты только порты 22 (SSH), 80 (HTTP Traefik) и 443 (HTTPS Traefik), настроена внутренняя маршрутизация подсетей K3s Pods (`10.42.0.0/16`) и Services (`10.43.0.0/16`).
* Включение службы Fail2ban.
3. **Подключение постоянного SSD**:
* Определение вторичного диска `/dev/vdb`.
* Автоматическое форматирование в `ext4` с меткой `k3s-storage`, если диск не был отформатирован.
* Монтирование в `/var/lib/rancher/k3s/storage` и добавление записи в `/etc/fstab`.
4. **Запуск K3s и GitOps-движка**:
* Старт службы `k3s.service` с активным ServiceLB.
* Создание секрета `flux-system/sops-age` с ключом дешифрования.
* Установка CRD и контроллеров Flux v2.
* Применение корневого манифеста синхронизации (`GitRepository` + `Kustomization`), привязанного к ветке `next`.
---
### Фаза 3: Непрерывная доставка и синхронизация (GitOps)
1. **Контроллер Flux**:
* Опрашивает ветку `next` каждую 1 минуту.
* Применяет Kustomize-оверлеи из `ci/k8s/clusters/production`.
* Дешифрует секреты `*.sops.yaml` прямо внутри кластера с помощью ключа Age.
* Гарантирует бесшовный rollout подов (`maxUnavailable: 0`, `maxSurge: 1`).
2. **Сетевой уровень и TLS**:
* Traefik слушает порты 80 и 443.
* Cert-Manager валидирует HTTP-01 ACME challenge от Let's Encrypt через правила Ingress.
* Прокси Cloudflare работает в режиме **Full (strict)**, обеспечивая максимальный уровень безопасности.
@@ -0,0 +1,74 @@
---
title: "GitOps и пайплайн релизов"
weight: 4
type: docs
---
Платформа использует декларативную модель GitOps на базе **Flux v2** и **Kustomize** со встроенной автоматической проверкой раскатки сервисов в продакшене.
---
## 1. Структура GitOps-манифестов
Все манифесты Kubernetes расположены в каталоге [`ci/k8s/`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/k8s/):
```text
ci/k8s/
├── apps/ # Сервисы и приложения
│ ├── docs/ # Документация на Hugo
│ ├── postgres/ # PostgreSQL 16 StatefulSet и бэкап-CronJob
│ ├── umami/ # Аналитика Umami
│ └── www/ # Основной сайт на React 19
├── base/ # Базовые ресурсы
│ └── namespaces/ # Определение неймспейса `com-ermnvldmr`
├── clusters/ # Точки входа для Flux
│ └── production/ # Корневая Kustomization продакшена
└── infrastructure/ # Кластерная инфраструктура
├── cert-manager/ # Cert-Manager v1.17.0 и ClusterIssuer Let's Encrypt
└── networking/ # Правила маршрутизации Traefik Ingress
```
---
## 2. Пайплайны развертывания и релизов
### Режимы деплоя сервисов:
1. **`services/docs` (Непрерывный деплой)**:
* **Триггер**: Push в ветку `next` с изменениями в `services/docs/**`.
* **Workflow**: `.github/workflows/services-docs-next-required.yml`.
* **Действие**: Сборка Docker-образа, обновление `ci/k8s/apps/docs/kustomization.yaml`, коммит в `next` и запуск задачи `verify-rollout`.
2. **`services/www` (Семантический релиз через Dispatch)**:
* **Триггер**: Запуск вручную через `.github/workflows/services-www-releases-dispatch-release.yml`.
* **Стандартный режим**: Полный цикл тестов (Vitest, Storybook Playwright, Lint, Typecheck, Build) ➔ Git-тег релиза ➔ Пуш в GHCR ➔ Обновление тега в GitOps ➔ Проверка через `verify-rollout`.
* **Быстрый режим (`skip_ci: true`)**: Пропуск тестов для экстренных деплоев и откатов с мгновенной сборкой образа, пушем в GitOps и верификацией.
---
## 3. Автоматическая проверка раскатки (`/version.json`)
Для 100% уверенности в том, что релиз дошел до пользователей:
1. Каждый Docker-образ содержит файл `/usr/share/nginx/html/version.json` со значениями `COMMIT_SHA` и `VERSION`.
2. Nginx отдает `/version.json` с заголовками `Cache-Control: no-store, no-cache, must-revalidate`.
3. Шаг `verify-rollout` в GitHub Actions опрашивает публичный адрес (`https://www.ermnvldmr.com/version.json` или `https://docs.ermnvldmr.com/version.json`) каждые 10 секунд (до 5 минут), пока коммит в продакшене не совпадет с задеплоенным.
```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 "✅ Раскатка в продакшене подтверждена!"
exit 0
fi
sleep 10
done
```
---
## 4. Стратегия отката (Rollback)
* **Git Revert (Стандартный)**: Создание revert-коммита для деплой-коммита и пуш в `next`.
* **GitOps-скрипт**: Запуск `bash ci/scripts/deploy-gitops.sh <service> <previous_tag>`.
* **Экстренный откат в кластере**: Команда `kubectl rollout undo deployment/<service> -n com-ermnvldmr` для мгновенного переключения трафика.
@@ -0,0 +1,61 @@
---
title: "Автоматизация Golden Image"
weight: 3
type: docs
---
Сборочный пайплайн Golden Image автоматизирует создание стандартизированных и защищенных образов виртуальных машин Debian 12 с предустановленным кластером K3s.
---
## 1. Конфигурация Packer и скрипты провижининга
Конфигурация сборок расположена в каталоге [`ci/packer/`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/packer/) и использует builder `qemu`.
### Основные компоненты:
* **[`debian-12-k3s.pkr.hcl`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/packer/debian-12-k3s.pkr.hcl)**: HCL-шаблон Packer, задающий параметры виртуальной машины (CPU, RAM, диск 10GB qcow2, образ Debian 12 Netinst, параметры загрузки и скрипты).
* **[`http/preseed.cfg`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/packer/http/preseed.cfg)**: Правила автоматической неинтерактивной установки Debian через Preseed.
* **[`scripts/01-base-system.sh`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/packer/scripts/01-base-system.sh)**: Установка базовых утилит, принудительное включение cloud-init (`/etc/cloud/ds-identify.cfg`), оптимизация сетевого стека и настройка fail2ban.
* **[`scripts/02-install-k3s.sh`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/packer/scripts/02-install-k3s.sh)**: Скачивание и установка бинарного файла K3s (`INSTALL_K3S_SKIP_ENABLE=true`, `INSTALL_K3S_SKIP_START=true`) в `/usr/local/bin/k3s` без запуска сервиса во время сборки.
* **[`scripts/03-cleanup.sh`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/packer/scripts/03-cleanup.sh)**: Сброс идентификаторов машины (`/etc/machine-id`, `/var/lib/dbus/machine-id`, хостовые ключи SSH), очистка кэшей apt и зануление свободного места на диске.
---
## 2. Автоматизация в GitHub Actions
Сборка образов запускается пайплайном `.github/workflows/ci-next-build-golden-image.yml`.
### Этапы workflow:
1. **Валидация скриптов**: Проверка синтаксиса bash (`bash -n ci/packer/scripts/*.sh`) и форматирования Packer (`packer fmt -check`).
2. **Сборка образа**:
* Инициализация плагинов (`packer init`).
* Сборка в headless QEMU (`packer build`).
* Сжатие артефакта в формат `qcow2`.
3. **Загрузка в S3 и контроль квот**:
* Настройка AWS S3 CLI для работы с S3-совместимым объектным хранилищем.
* **Автоматическая очистка**: Удаление устаревших образов в префиксе `dev/images/com-ermnvldmr-debian-12-k3s-amd64-*.qcow2` для предотвращения переполнения квоты бакета.
* **Загрузка**: Сохранение нового образа:
```text
s3://<bucket>/dev/images/com-ermnvldmr-debian-12-k3s-amd64-<git_short_sha>.qcow2
```
---
## 3. Схема именования образов
Имя образа жестко связано с коммитом Git:
```text
com-ermnvldmr-debian-12-k3s-amd64-<short_sha>.qcow2
```
Пример: `com-ermnvldmr-debian-12-k3s-amd64-f4ba6d1.qcow2`
---
## 4. Развертывание через Cloud-Init
Для запуска виртуальной машины в облачной инфраструктуре из готового образа:
1. Передайте заполненный шаблон [`user-data.template.yaml`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/cloud-init/user-data.template.yaml) в метаданные инстанса в поле `user-data`.
2. Cloud-init автоматически выполнит `/usr/local/bin/bootstrap-cluster.sh` при первом старте.
3. Инстанс настроит сеть, смонтирует постоянный SSD, запустит K3s, установит Flux и поднимет все сервисы примерно за 90 секунд.
@@ -0,0 +1,100 @@
---
title: "Эксплуатация и регламенты"
weight: 5
type: docs
---
Практическое руководство и регламенты для администрирования, отладки и обслуживания продакшен-кластера `ermnvldmr.com`.
---
## 1. Удаленный SSH-доступ
Подключение к виртуальной машине осуществляется под учетной записью `adam`:
```bash
ssh -i ~/.ssh/id_ed25519 adam@<SERVER_IP>
```
Пользователь `adam` имеет права `sudo` без пароля и преднастроенный доступ к `kubectl` через `~/.kube/config`.
---
## 2. Диагностика состояния кластера
### Проверка статуса подов
```bash
kubectl get pods -n com-ermnvldmr -o wide
```
### Проверка Ingress и TLS-сертификатов
```bash
kubectl get certificates -n com-ermnvldmr
kubectl get ingress -n com-ermnvldmr
```
### Проверка синхронизации Flux GitOps
```bash
kubectl get gitrepositories -n flux-system
kubectl get kustomizations -n flux-system
```
### Принудительный запуск синхронизации GitOps
```bash
kubectl annotate --overwrite kustomization -n flux-system cluster-sync reconcile.fluxcd.io/requestedAt="$(date +%s)"
```
---
## 3. Управление секретами через SOPS + Age
Все файлы секретов (`*.sops.yaml`) хранятся в репозитории Git в зашифрованном виде с использованием асимметричных ключей Age.
### Конфигурация SOPS (`.sops.yaml`):
```yaml
creation_rules:
- path_regex: 'ci/k8s/.*secret.*\.yaml$'
encrypted_regex: '^(data|stringData)$'
age: 'age1<YOUR_PUBLIC_AGE_KEY>'
```
> **Важно**: Параметр `encrypted_regex` оставляет `apiVersion`, `kind` и `metadata.name` открытыми, что предотвращает ошибки синтаксического разбора в Kustomize и Flux.
### Шифрование секрета
```bash
sops --encrypt --in-place ci/k8s/apps/postgres/secret.sops.yaml
```
### Редактирование зашифрованного секрета
```bash
sops ci/k8s/apps/postgres/secret.sops.yaml
```
---
## 4. Хранилище PostgreSQL и резервное копирование в S3
### Архитектура постоянного хранения
* Данные PostgreSQL размещены на постоянном томе PVC (5Gi) на диске `/dev/vdb` (смонтированном в `/var/lib/rancher/k3s/storage`).
* Данные сохраняются при перезагрузках виртуальной машины и перезапусках подов.
### Автоматический бэкап в S3 (CronJob)
* Манифест: [`ci/k8s/apps/postgres/backup-cronjob.yaml`](file:///home/deytenit/Source/repos/deytenit/ermnvldmr.com/ci/k8s/apps/postgres/backup-cronjob.yaml).
* Расписание: ежедневно в 03:00 UTC (`0 3 * * *`).
* Делает дамп `pg_dump` со сжатием gzip и отправляет его в `s3://<bucket>/backups/postgres/`.
### Ручной запуск бэкапа
```bash
kubectl create job --from=cronjob/postgres-backup manual-backup-$(date +%s) -n com-ermnvldmr
```
---
## 5. Настройки SSL/TLS в Cloudflare
* **Режим SSL**: **Full (strict)**
* **Правило исключения для HTTPS Redirect**: Обязательно наличие правила для исключения ACME HTTP-01 challenge:
```text
http.request.scheme eq "http" and not starts_with(http.request.uri.path, "/.well-known/acme-challenge/")
```
Это позволяет cert-manager продлевать сертификаты Let's Encrypt по порту 80 без блокировок и редиректов.
-38
View File
@@ -1,38 +0,0 @@
---
title: Documentation of ermnvldmr.com root deployment commons
description: Документация общих модулей корневой инфраструктуры ermnvldmr.com.
weight: 2
type: docs
cascade:
type: docs
---
> [!WARNING]
> **Deprecated.** The root framework has been superseded by the
> [apex fleet operations framework](/en/apex) (documentation in English only). This
> section is retained for reference only and no longer receives updates.
Фреймворк `ermnvldmr.com-root-commons` предоставляет среду развертывания с минимальными зависимостями для независимых self-hosted проектов.
Общая логика, скрипты и шаблоны развертывания, используемые в различных приложениях, хранятся в репозитории [GitHub: ermnvldmr.com-root-commons](https://github.com/deytenit/ermnvldmr.com-root-commons).
## Основные возможности
- **Smart Dispatcher**: Единая точка входа (`root`) для всех задач оркестрации.
- **Tiered Storage**: Стандартизированная классификация для конфигураций, данных и логов.
- **Privilege Isolation**: Изоляция привилегий через выделенных non-root пользователей для каждого проекта.
- **Namespaced Libraries**: Явные модульные Bash-утилиты для обеспечения согласованной автоматизации.
## Разделы
{{% cards %}}
{{< card link="concepts" title="Концепции" icon="book-open" subtitle="Теоретические основы, архитектура и модели безопасности." >}}
{{< card link="guides" title="Руководства" icon="map" subtitle="Пошаговые инструкции по установке и разработке Action-скриптов." >}}
{{< card link="reference" title="Справочник" icon="code" subtitle="API и технические справочники для разработчиков." >}}
{{% /cards %}}
---
**See also:**
- [GitHub: ermnvldmr.com-root-commons](https://github.com/deytenit/ermnvldmr.com-root-commons)
@@ -1,14 +0,0 @@
---
title: Концепции
description: Теоретические основы, архитектура и модели безопасности.
weight: 10
---
Теоретические основы, архитектура и модели безопасности общих модулей корневой инфраструктуры ermnvldmr.com.
{{% cards %}}
{{< card link="principles" title="Принципы инфраструктуры" icon="book-open" subtitle="Предсказуемость, минимум зависимостей и децентрализация." >}}
{{< card link="architecture" title="Архитектура инфраструктуры" icon="share" subtitle="Децентрализованная оркестрация и модели развертывания." >}}
{{< card link="security-model" title="Модель безопасности и изоляция" icon="shield-check" subtitle="Изоляция привилегий и защита сети." >}}
{{< card link="tiered-storage" title="Модель многоуровневого хранения" icon="database" subtitle="Стандартизированная классификация хранения данных сервисов." >}}
{{% /cards %}}
@@ -1,71 +0,0 @@
---
title: Архитектура инфраструктуры
description: Децентрализованная модель оркестрации и структура развертывания.
weight: 10
---
Фреймворк Root работает на децентрализованной модели оркестрации, разработанной для независимых, самодостаточных проектов. Он обеспечивает строгое разделение между оркестратором («мозгом») и задачами автоматизации («мышцами»).
## Основная философия {#philosophy}
Фреймворк построен на принципе **Smart Root, Stupid Actions** («Умный Root, глупые Action-скрипты»). Такой дизайн гарантирует, что отдельные скрипты автоматизации остаются декларативными и не знают о глобальном состоянии системы, в то время как центральный диспетчер берет на себя разрешение окружения и инициализацию библиотек.
### Smart Root (Диспетчер)
Точка входа `root` является единственным интерфейсом для пользователей. Она отвечает за:
- **Разрешение окружения** &rarr; Поиск репозиториев `commons` и `configs`.
- **Подготовка библиотек** &rarr; Разовая загрузка пространств имен (modules) библиотек.
- **Установление контекста** &rarr; Определение целевого [Узла (Node)](/root/glossary#node) и связанных с ним путей.
### Stupid Actions (Задачи)
[Action-скрипты (Actions)](/root/glossary#action) — это декларативные скрипты, расположенные в `scripts/actions/`. Они называются «глупыми», потому что:
- Они не вычисляют пути и не ищут репозитории.
- Они полностью зависят от переменных окружения `ROOT_`.
- Они фокусируются исключительно на одной атомарной задаче (например, `compose`, `ufw`).
## Модель развертывания {#deployment}
Они обычно развертываются как общий репозиторий [Commons](/root/glossary#commons), подключенный как Git-субмодуль внутри репозитория конфигураций. Движок, на котором построена эта общая инфраструктура, размещен по адресу [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)
-commons)
@@ -1,33 +0,0 @@
---
title: Принципы инфраструктуры
description: Основные принципы, обеспечивающие безопасную, предсказуемую среду с минимальными зависимостями.
weight: 5
---
Общие модули построены на ключевых принципах, предназначенных для обеспечения безопасной, предсказуемой среды с минимальными зависимостями для независимых self-hosted проектов.
## Предсказуемость через структуру {#predictability}
Ручная настройка сервера подвержена «дрейфу конфигурации» (configuration drift), когда хосты, которые должны быть идентичными, со временем начинают различаться. Общие модули решают эту проблему следующим образом:
- **Git как источник истины**: Каждая конфигурация, от правил UFW до crontab, хранится в репозитории.
- **Идемпотентная автоматизация**: [Action-скрипты](/root/glossary#action) разработаны так, чтобы их можно было запускать многократно без побочных эффектов, гарантируя, что хост всегда соответствует заданному состоянию.
## Минимальное количество зависимостей {#minimalism}
Для обеспечения долгосрочной поддерживаемости общие модули избегают сложных инструментов управления конфигурацией (таких как Ansible или Salt). Вместо этого они полагаются на:
- **Bash**: Универсальный язык Unix-систем.
- **Docker**: Для изоляции приложений и согласованности окружения.
- **Стандартные инструменты Linux**: Прямое использование `systemd`, `ufw` и `cron`.
## Децентрализация {#decentralization}
Каждый [Узел (Node)](/root/glossary#node) является независимым. Хотя они используют библиотеку общих модулей ([Commons](/root/glossary#commons)), они не зависят от центрального «мастер»-сервера. Такая архитектура гарантирует, что сбой на одном хосте не повлияет на несвязанные сервисы.
---
**См. также:**
- [Концепция: Модель безопасности и изоляция](/root/concepts/security-model)
- [Концепция: Модель многоуровневого хранения](/root/concepts/tiered-storage)
@@ -1,64 +0,0 @@
---
title: Безопасность и изоляция привилегий
description: Меры безопасности, изоляция привилегий и песочница на уровне проектов.
weight: 20
---
Безопасность в Root достигается за счет строгой изоляции привилегий и создания «песочниц» на уровне проектов для минимизации последствий в случае взлома отдельных сервисов.
## Принцип «No-Root» {#noroot}
Запуск приложений под пользователем `root` внутри контейнеров является значительным риском безопасности. Общие модули обеспечивают изоляцию с помощью действий `tiers/useradd` и `tiers/chown`.
### Пользователи для конкретных проектов
Каждому проекту, расположенному по пути `{repository root}/{node}/{project}`, назначается выделенный системный пользователь на хосте.
- **Изоляция**: Если контейнер будет взломан, злоумышленник получит только привилегии этого конкретного низкопривилегированного пользователя.
- **Безопасность файловой системы**: Проекты могут читать и записывать данные только в свои собственные директории в рамках [Уровней (Tiers)](/root/glossary#tier).
## Защита сокета Docker {#socket-protection}
Прямой доступ к `/var/run/docker.sock` эквивалентен правам root на хосте. В качестве лучшей практики настоятельно рекомендуется защищать сокет Docker. Один из способов достижения этого — использование **Socket Proxy** (например, на базе `tecnativa/docker-socket-proxy`) для фильтрации и ограничения доступа к 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:
# Использовать прокси вместо локального сокета
- "--providers.docker.endpoint=tcp://root-socket-proxy:2375"
networks:
socket: {}
```
## Мониторинг безопасности (CrowdSec) {#crowdsec}
Фреймворк интегрирует **CrowdSec** для поведенческого анализа и автоматического реагирования.
- **Обнаружение вторжений**: CrowdSec отслеживает логи [Traefik](https://traefik.io/) и SSH на предмет подозрительных паттернов (например, брутфорс-атаки, сканирование портов).
- **Автоматическая блокировка**: При обнаружении угрозы **CrowdSec Firewall Bouncer** автоматически обновляет правила [UFW](https://help.ubuntu.com/community/UFW), блокируя вредоносный IP на уровне хоста.
- **Обмен данными об угрозах**: CrowdSec делится анонимизированными данными об угрозах со своим сообществом, обеспечивая превентивную защиту от известных злоумышленников.
## Сетевое ужесточение {#networking}
Root использует `configure/ufw` для реализации политики «Запрещено по умолчанию» (Default Deny).
- **Внутренняя маршрутизация**: Сервисы взаимодействуют через выделенную сеть-мост `root-proxy`, которая часто настраивается как `internal: true`.
- **Изоляция анклавов**: Исходящий трафик может быть направлен через выделенный узел выхода (egress node) для детального контроля.
@@ -1,71 +0,0 @@
---
title: Модель многоуровневого хранения
description: Стандартизированная таксономия хранения данных сервисов.
weight: 15
---
Фреймворк навязывает стандартизированную таксономию хранения. Это гарантирует, что каждый сервис имеет предсказуемое местоположение для своих данных, что упрощает стратегии резервного копирования и распределение оборудования.
## Таксономия хранения {#taxonomy}
Данные разделены на три логических [Уровня (Tiers)](/root/glossary#tier) на основе их требований к производительности, жизненного цикла и важности.
### Уровень 1 (Tier 1): Конфигурации и Кэш
**Путь:** `${ROOT_NODE_DIR}/@tier1`
- **Содержимое**: Конфигурационные файлы, небольшие базы данных SQLite, SSL-сертификаты, кэш приложений.
- **Характеристики**: Чрезвычайно высокая ценность, объем от низкого до среднего, требует минимальных задержек (latency).
- **Оборудование**: Высокоскоростные SSD-накопители, обычно общие с операционной системой.
### Уровень 2 (Tier 2): Данные приложений
**Путь:** `${ROOT_NODE_DIR}/@tier2`
- **Содержимое**: Пользовательские загрузки, большие базы данных, постоянное состояние приложений.
- **Характеристики**: Высокая ценность, объем от среднего до высокого, требует высокой надежности.
- **Оборудование**: Надежные HDD-кластеры, RAID-массивы или выделенные хранилища.
### Уровень 3 (Tier 3): Временные файлы и объемные медиа
**Путь:** `${ROOT_NODE_DIR}/@tier3`
- **Содержимое**: Логи, временные файлы, объемные медиа (фильмы, музыка) и другие некритичные большие данные.
- **Характеристики**: Низкая ценность, очень высокий объем.
- **Оборудование**: HDD большой емкости, оптимизированные для непрерывной последовательной записи/чтения (например, WD Purple). Обратите внимание, что Tier 3 **слишком медленный для кэша**.
## Стратегия резервного копирования {#backup}
Общие модули не навязывают конкретную стратегию резервного копирования и не предоставляют реализацию по умолчанию, обеспечивая полную гибкость на уровне узла. Ожидается, что операторы сами реализуют логику резервного копирования.
### Пример: Резервное копирование с помощью Restic
Распространенной лучшей практикой является использование **Restic** для резервного копирования. Например, вы можете создать файл compose узла оператора для запуска 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
network_mode: "host"
entrypoint: [ "restic" ]
user: "0:0"
```
### Реализация стратегии
Операторы могут реализовать свою стратегию, определив локальный Action в `.operator/local/scripts/actions/sync/tiers`. Диспетчер `root` затем сможет выполнить этот скрипт для запуска резервного копирования, позволяя детально контролировать способ сохранения данных.
## Обоснование {#justification}
1. **Оптимизация оборудования**: Сопоставляя уровни с конкретным оборудованием (SSD для Tier 1, RAID для Tier 2, Purples для Tier 3), мы оптимизируем как производительность, так и стоимость.
2. **Выборочное резервное копирование**: Отделение временных логов и объемных медиа (Tier 3) от критических конфигураций (Tier 1) предотвращает трату дорогостоящего места в хранилище резервных копий.
3. **Архитектурная ясность**: Любой оператор может проинспектировать директорию [Узла (Node)](/root/glossary#node) и сразу понять требования к хранению и приоритет его содержимого.
-41
View File
@@ -1,41 +0,0 @@
---
title: Глоссарий
description: Терминология, используемая в рамках общих модулей корневой инфраструктуры.
weight: 100
---
Терминология, используемая в рамках общих модулей корневой инфраструктуры ermnvldmr.com.
## Action {#action}
**Action (Действие)** - Атомарная задача автоматизации, расположенная в `scripts/actions/`. Action-скрипты следуют философии "Stupid Action" («Глупое действие»), оставаясь декларативными и полагаясь на диспетчер `root` для настройки окружения.
## Commons {#commons}
**Commons (Общие модули)** - Общий репозиторий, содержащий общую логику, модульные библиотеки и стандартизированные действия автоматизации, используемые на всех узлах. Ссылка на [GitHub: ermnvldmr.com-root-commons](https://github.com/deytenit/ermnvldmr.com-root-commons).
## Dispatcher {#dispatcher}
**Dispatcher (Диспетчер)** - Скрипт `root`, который служит точкой входа. Он разрешает пути, подготавливает окружение и выполняет запрошенный [Action](/root/glossary#action).
## Node {#node}
**Node (Узел)** - Физический или виртуальный хост, управляемый общими модулями. Каждый узел имеет выделенную директорию в репозитории конфигураций, содержащую его сервисы и локальные настройки.
## Root {#root}
**Root** - Имя утилиты командной строки, а также сервис оркестрации верхнего уровня внутри [Узла (Node)](/root/glossary#node) (обычно обрабатывающий Traefik и AdGuard).
## Tier {#tier}
**Tier (Уровень)** - Стандартизированная классификация хранения данных сервисов.
- **Tier 1 (Уровень 1)**: Конфигурация и критическое состояние.
- **Tier 2 (Уровень 2)**: Данные приложений и базы данных.
- **Tier 3 (Уровень 3)**: Логи, кэши и объемные медиафайлы.
---
**См. также:**
- [Концепция: Архитектура инфраструктуры](/root/concepts/architecture)
- [Концепция: Модель многоуровневого хранения](/root/concepts/tiered-storage)
@@ -1,13 +0,0 @@
---
title: Руководства
description: Пошаговые инструкции по установке и разработке Action-скриптов.
weight: 20
---
Пошаговые инструкции по установке и разработке в рамках общих модулей корневой инфраструктуры ermnvldmr.com.
{{% cards %}}
{{< card link="first-node" title="Создание вашего первого узла" icon="map" subtitle="Практическое руководство по созданию репозитория конфигураций." >}}
{{< card link="installation" title="Установка" icon="arrow-down" subtitle="Первоначальная настройка общих модулей на новом хосте." >}}
{{< card link="action-development" title="Разработка Action-скриптов" icon="code" subtitle="Создание и управление атомарными задачами автоматизации." >}}
{{% /cards %}}
@@ -1,67 +0,0 @@
---
title: Разработка Action-скриптов
description: Разработка атомарных задач автоматизации в рамках общих модулей.
weight: 30
---
[Action-скрипты](/root/glossary#action) — это атомарные задачи автоматизации. Следуя философии "Stupid Action" («Глупое действие»), они должны оставаться декларативными и полагаться на библиотеку для выполнения сложных операций.
## Создание нового Action-скрипта {#create}
{{% steps %}}
### Шаг 1: Создание файла скрипта
Поместите ваш скрипт в `scripts/actions/{group}/{name}`. Не используйте расширения файлов.
### Шаг 2: Реализация метаданных
Каждый Action-скрипт должен предоставлять описание и список аргументов для системы справки (help system).
```bash filename="scripts/actions/utils/my-action"
action_metadata() {
cat <<EOF
description: "Краткое описание задачи."
args:
- NODE: "Имя узла"
- PARAM: "Пользовательский параметр"
EOF
}
```
### Шаг 3: Инициализация контекста
Используйте вспомогательную функцию `root_require_node` для настройки окружения. Это должно быть первым функциональным шагом в вашем скрипте.
```bash filename="scripts/actions/utils/my-action"
root_require_node "${1:-}"
shift
```
### Шаг 4: Использование модульных функций
Выполняйте операции, используя библиотечные функции `root_*`. Полагайтесь на переменные окружения `ROOT_` для всех путей.
```bash filename="scripts/actions/utils/my-action"
root_log_info "Обработка узла $ROOT_NODE"
root_sys_restart_service "my-service"
```
{{% /steps %}}
## Пространства имен библиотек {#libraries}
Action-скрипты имеют доступ к следующим модулям:
- `root_core_*`: Логирование и уведомления в Telegram.
- `root_init_*`: Декларативная инициализация сервисов и управление пакетами.
- `root_sys_*`: Управление systemd и файлами юнитов.
- `root_template_*`: Рендеринг на основе envsubst и внедрение конфигураций.
- `root_validate_*`: Проверка ввода, файлов и ОС.
---
**См. также:**
- [Справочник: Справочник ROOT_ API](/root/reference/root-api)
- [Концепция: Архитектура инфраструктуры](/root/concepts/architecture)
@@ -1,190 +0,0 @@
---
title: "Создание узла (First Node)"
description: Практическое руководство по созданию вашего первого узла и подключению общих модулей.
weight: 25
---
**Цель:** Создать репозиторий конфигураций для вашей собственной инфраструктуры, подключить общие модули в качестве подмодуля (submodule) и запустить первый базовый узел.
## 1. Создание репозитория конфигураций
Ваша инфраструктура должна управляться из единого Git-репозитория. Этот репозиторий будет содержать конфигурации для всех ваших серверов (узлов).
{{% steps %}}
### Шаг 1: Инициализация репозитория
Создайте новую директорию и инициализируйте Git.
```bash
mkdir my-infrastructure
cd my-infrastructure
git init
```
### Шаг 2: Добавление общих модулей как подмодуля
Общие модули (`ermnvldmr.com-root-commons`) должны располагаться по пути `.operator/shared`.
```bash
mkdir -p .operator
git submodule add https://github.com/deytenit/ermnvldmr.com-root-commons.git .operator/shared
```
### Шаг 3: Создание загрузочного скрипта (Bootstrap)
Создайте файл `init.sh` в корне вашего репозитория. Этот скрипт свяжет общие модули с вашим локальным окружением.
```bash filename="init.sh"
#!/usr/bin/env bash
# init.sh
# Загрузка общих утилит из подмодуля
source "$(git -C "$(dirname "$0")" rev-parse --show-toplevel)/.operator/shared/scripts/lib/common.sh"
SCRIPT_NAME="init"
navigate_to_repo_root
log_info "Настройка Git hooks..."
git config core.hooksPath .operator/shared/githooks
git config --global --add safe.directory "${REPO_ROOT}"
log_info "Настройка PATH для диспетчера root..."
ABSOLUTE_RUN_DIR="$(realpath "${REPO_ROOT}/.operator/shared/scripts/run")"
BASHRC_ENTRY="export PATH=\"${ABSOLUTE_RUN_DIR}:\$PATH\""
sed -i '/\.operator\/shared\/scripts\/run/d' ~/.bashrc
echo "$BASHRC_ENTRY" >> ~/.bashrc
log_info "Готово. Выполните 'source ~/.bashrc' или перезайдите в терминал."
```
Сделайте его исполняемым:
```bash
chmod +x init.sh
```
{{% /steps %}}
## 2. Определение вашего первого узла
Узел (Node) — это папка в корне репозитория, которая представляет один физический или виртуальный сервер.
### Структура узла
Давайте создадим узел с именем `daedalus`. Внутри него мы определим конфигурацию оператора (например, для резервного копирования) и базовый сервис.
```bash
mkdir -p daedalus/.operator/configs/{cron,crowdsec,systemd,ufw/docker,ufw/host}
mkdir -p daedalus/root
```
### Базовые настройки (Опционально)
Вы можете добавить файлы конфигурации (например, правила UFW или crontab) в директорию `daedalus/.operator/configs/`. Например, простой crontab:
```bash filename="daedalus/.operator/configs/cron/crontab.template"
# Запуск резервного копирования каждую ночь в 3:00
0 3 * * * root sync tiers daedalus
```
## 3. Настройка сервисов (Docker Compose)
Фреймворк опирается на `docker-compose.yml`.
### Инфраструктурный уровень (Узел оператора)
Файл `daedalus/docker-compose.yml` запускает инфраструктурные утилиты, такие как `restic` для бекапов или VPN-агенты. Этот compose-файл имеет прямой доступ к файловой системе через монтирование директорий `@tierX`.
```yaml filename="daedalus/docker-compose.yml"
name: 'operator'
services:
restic:
image: restic/restic:0.18.1
container_name: operator-restic
volumes:
# Пример: монтирование данных для резервного копирования (Только для чтения)
- ./@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...
network_mode: "host"
entrypoint: [ "restic" ]
```
### Корневой уровень (Root)
Проект `root` обычно содержит обратные прокси (Traefik) и сервисы, к которым обращаются другие проекты.
```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 и GID подставляются автоматически фреймворком после команды '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. Развертывание
Теперь, когда структура создана:
1. Закоммитьте и отправьте (push) этот репозиторий на ваш Git-сервер (например, GitHub).
2. Зайдите на ваш VPS.
3. Следуйте руководству по [Установке (Installation)](/root/guides/installation), используя URL вашего нового репозитория.
---
**См. также:**
- [Руководство: Установка на новый хост](/root/guides/installation)
- [Концепция: Архитектура инфраструктуры](/root/concepts/architecture)
@@ -1,199 +0,0 @@
---
title: 'Начальная настройка хоста'
description: 'Настройка чистого хоста Debian с нуля.'
weight: 1
---
Защищенная настройка чистого хоста Debian от нуля до развертывания.
## Процедура настройки
{{% steps %}}
### Основные пакеты
Сначала установите `sudo` и `docker-ce`. Это необходимо, так как последующая настройка пользователя опирается на группу `docker` и конфигурацию `sudo`.
**Установка Sudo**
```bash
# От имени root:
apt update && apt install sudo -y
```
**Установка Docker**
Следуйте [официальному руководству по установке Docker для Debian](https://docs.docker.com/engine/install/debian/), чтобы установить последнюю версию Docker Engine.
### Системный пользователь и привилегии
Пользователь `adam` выполняет все административные задачи. Аутентификация по SSH-ключу и беспарольный `sudo` через группу `wheel` минимизируют трение при сохранении безопасности.
**Создание администратора**
```bash
# От имени root:
# Создать пользователя с оболочкой bash
useradd -m -s /bin/bash adam
# Создать группу wheel (общепринято для единообразия между дистрибутивами)
groupadd wheel
# Создать модульный файл sudoers
# Это позволяет членам группы 'wheel' запускать sudo без пароля
echo "%wheel ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/99-custom-sudoers
# Проверить синтаксис
visudo -c -f /etc/sudoers.d/99-custom-sudoers
# Добавить adam в необходимые группы
usermod -aG wheel,docker adam
```
### Настройка Swap
Настройте файл подкачки (swap), чтобы обеспечить стабильность системы во время операций, требующих большого объема памяти.
```bash
# От имени root:
# Создать файл подкачки размером 2 ГБ (измените размер при необходимости)
fallocate -l 2G /swap
chmod 600 /swap
mkswap /swap
swapon /swap
# Сделать его постоянным
echo '/swap none swap sw 0 0' >> /etc/fstab
```
### SSH Доступ и Усиление
Пароли отключены. Доступ осуществляется строго по SSH-ключам.
**Авторизация ключа оператора**
Импортируйте ваш локальный публичный ключ для пользователя `adam`.
```bash
# От имени root:
# Настроить директории
mkdir -p /home/adam/.ssh
chmod 700 /home/adam/.ssh
# Добавьте свой публичный ключ (Замените [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
```
**Доступ со стороны оператора**
Настройте вашу локальную машину для удобного доступа к хосту.
```bash
# ~/.ssh/config на стороне оператора
Host daedalus.example.com
Port 2222
User adam
IdentityFile ~/.ssh/adam_example_com_ed25519
```
**Усиление демона SSH**
Измените конфигурацию SSH, чтобы сменить порт по умолчанию и отключить вход по паролю.
```bash
# От имени root:
# Создать выделенный файл конфигурации
cat <<EOF > /etc/ssh/sshd_config.d/99-custom-ssh.conf
Port 2222
PasswordAuthentication no
PermitEmptyPasswords no
AllowUsers adam
EOF
# Проверить синтаксис перед перезапуском, чтобы избежать блокировки
sshd -t && systemctl restart ssh
```
### Доступ к GitHub (Deploy Key)
Хосту требуется собственная идентификация для загрузки обновлений из репозитория GitHub.
```bash
# От имени root:
# Сгенерировать специфичный для хоста SSH-ключ (без парольной фразы для автоматизации)
sudo -u adam ssh-keygen -t ed25519 -f /home/adam/.ssh/github_ed25519 -N ""
# Настроить SSH для использования этого ключа для GitHub
cat <<EOF | sudo -u adam tee /home/adam/.ssh/config
Host github.com
AddKeysToAgent yes
IdentityFile ~/.ssh/github_ed25519
EOF
# Отобразить публичный ключ для добавления в GitHub (Settings > Deploy Keys)
cat /home/adam/.ssh/github_ed25519.pub
```
> [!TIP]
> Добавьте вывод выше в настройки Deploy Keys вашего репозитория инфраструктуры (например, `https://github.com/your-username/your-repo/settings/keys`) с правами **read access**.
### Развертывание репозитория
Клонируйте репозиторий вашей инфраструктуры и инициализируйте узел.
```bash
# От имени root:
# Настройка директории сервиса
export REPO_DIR="/srv/your-infrastructure-repo"
mkdir -p $REPO_DIR
chown adam:adam $REPO_DIR
# Клонирование от имени пользователя adam
sudo -u adam git clone git@github.com:your-username/your-repo.git $REPO_DIR
# Инициализировать узел (Установите имя вашего узла, например, daedalus)
export NODE="daedalus"
cd $REPO_DIR
sudo -u adam ./init.sh
```
**Специфичная для узла конфигурация**
Запустите скрипты инициализации с помощью диспетчера `root`:
```bash
# Выполните последовательность для вашего конкретного узла (от имени пользователя 'adam')
# Убедитесь, что вы выполнили 'source ~/.bashrc' или переподключились, если команда 'root' не найдена
root configure base $NODE
root configure ufw $NODE
root configure crowdsec $NODE
root configure cron $NODE
```
### Хранение и усиление безопасности
Определите уровни данных (tiers) и защитите среду, создав непривилегированных пользователей для контейнеризированных сервисов.
```bash
# Создать (или примонтировать) директории хранилища
sudo mkdir -p /srv/my-infrastructure-root-$NODE-{tier1,tier2,tier3}
# Настроить уровни и непривилегированных пользователей
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 %}}
---
**См. также:**
- [Doc: Docker - Install on Debian](https://docs.docker.com/engine/install/debian/)
@@ -1,18 +0,0 @@
---
title: Справочник
description: Справочные материалы и API для разработчиков.
weight: 30
---
Технические справочные материалы и API общих модулей корневой инфраструктуры ermnvldmr.com.
{{% cards %}}
{{< card link="compose" title="Справочник по действиям compose" icon="play" subtitle="Высокоуровневая точка входа для оркестрации docker-compose." >}}
{{< card link="configure" title="Справочник по действиям настройки" icon="arrow-down" subtitle="Действия для настройки системного уровня." >}}
{{< card link="initialization" title="Справочник по действиям инициализации" icon="play" subtitle="Действия для первоначальной настройки узла." >}}
{{< card link="root-api" title="Справочник ROOT_ API" icon="code" subtitle="Стандартизированные переменные окружения и вспомогательные функции логирования." >}}
{{< card link="source" title="Справочник по исходным сервисам" icon="book-open" subtitle="Общие сервисы, собираемые из исходного кода." >}}
{{< card link="sync" title="Справочник по действиям синхронизации" icon="check" subtitle="Действия для поддержания узлов в актуальном состоянии." >}}
{{< card link="tiers" title="Справочник по действиям уровней (Tiers)" icon="archive" subtitle="Управление уровнями хранения данных." >}}
{{< card link="utils" title="Справочник по утилитам" icon="check" subtitle="Вспомогательные скрипты и утилиты." >}}
{{% /cards %}}
@@ -1,50 +0,0 @@
---
title: Операции Compose
description: Стандартизированная точка входа для оркестрации docker-compose в масштабах узла.
weight: 54
---
Действие `compose` предоставляет стандартизированную высокоуровневую точку входа для оркестрации файлов Docker Compose для всех проектов в рамках определенного узла.
## Основная операция Compose {#actions}
| Операция | Описание |
| :--- | :--- |
| `compose <node> <action>` | Выполняет заданную команду Docker Compose (например, `up`, `down`, `restart`) по всей инфраструктуре узла. |
## Порядок оркестрации {#order}
Для поддержания правильных зависимостей (особенно при завершении работы или запуске прокси-серверов и сетей уровня инфраструктуры), действие `compose` интеллектуально упорядочивает выполнение:
### Запуск (`up`, `restart`)
При запуске или перезапуске сервисов действие использует **Прямой порядок** (Forward Order):
1. **Инфраструктура узла (Node Infra)**: Сначала обрабатывается файл `docker-compose.yml` уровня узла (находится в корне директории узла).
2. **Корневая инфраструктура (Root Infra)**: Затем обрабатывается проект `root/docker-compose.yml`, если он существует (обычно содержит Traefik, Socket Proxy и т.д.).
3. **Проекты**: Наконец, в алфавитном порядке обрабатываются все остальные директории проектов.
### Остановка (`down`)
При остановке сервисов действие использует **Обратный порядок** (Reverse Order), чтобы проекты корректно отключились до того, как упадет сеть или прокси:
1. **Проекты**: Все стандартные проекты останавливаются в обратном алфавитном порядке.
2. **Корневая инфраструктура (Root Infra)**: Проект `root/docker-compose.yml` останавливается.
3. **Инфраструктура узла (Node Infra)**: В самом конце отключается `docker-compose.yml` уровня узла.
## Опции {#options}
Вы можете передавать стандартные аргументы Docker Compose в конец команды.
Кроме того, действие поддерживает режим пробного запуска (dry-run):
- `--dry-run`: Выводит команды, которые будут выполнены, без их фактического запуска.
**Пример использования:**
```bash
root compose daedalus up -d --remove-orphans
root compose daedalus restart --dry-run
root compose daedalus down
```
---
**See also:**
- [Концепция: Архитектура инфраструктуры](/root/concepts/architecture)
- [Справочник: Справочник ROOT_ API Reference](/root/reference/root-api)
@@ -1,66 +0,0 @@
---
title: Операции настройки (Configure)
description: Подготовка хоста, движок шаблонов и конфигурация на уровне системы.
weight: 53
---
Операции настройки используются для подготовки хоста и обслуживания системных сервисов. Они в значительной степени полагаются на встроенный движок шаблонов для генерации декларативных конфигурационных файлов.
## Движок шаблонов {#template-engine}
Общие модули используют `envsubst` (из пакета `gettext-base`) для рендеринга шаблонов. Это позволяет использовать стандартные переменные окружения Bash непосредственно в ваших конфигурационных файлах.
### Соглашения по шаблонам
- **Расширение файлов**: Шаблоны обычно используют расширение `.template` (например, `crontab.template`).
- **Синтаксис переменных**: Используйте `${VARIABLE_NAME}` или `$VARIABLE_NAME` для подстановки значений.
- **Автоматический поиск**: Многие действия автоматически ищут шаблоны в определенных директориях внутри репозитория [Configs](/root/glossary#configs).
### Вспомогательные функции рендеринга
Библиотека `root_template.sh` предоставляет несколько вспомогательных функций:
- `root_template_render <input> <output>`: Рендерит один файл.
- `root_template_render_directory <src> <dest>`: Рекурсивно рендерит всю структуру директории.
- `root_template_crontab <template>`: Рендерит и устанавливает crontab для текущего пользователя.
## Основные операции настройки {#actions}
| Операция | Описание |
| :--- | :--- |
| `configure/base` | Устанавливает основные пакеты (`sudo`, `ufw`, `docker`) и настраивает базовых системных пользователей. |
| `configure/cron` | Рендерит и устанавливает специфичные для узла crontab-файлы. |
| `configure/crowdsec` | Настраивает агента CrowdSec и баунсеры (bouncers). |
| `configure/routing` | Настраивает маршрутизацию на уровне системы и сети-мосты (bridge networks). |
| `configure/systemd` | Устанавливает и активирует юниты сервисов systemd. |
| `configure/ufw` | Рендерит и применяет правила брандмауэра с помощью UFW и `ufw-docker`. |
## Пример: Шаблон Nginx {#example}
```nginx filename="nginx.conf.template"
# Этот шаблон использует переменную окружения ROOT_NODE
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Подставляется из окружения
server_name ${ROOT_NODE}.example.com;
}
```
---
**See also:**
- [Концепция: Архитектура инфраструктуры](/root/concepts/architecture)
- [Справочник: Справочник ROOT_ API Reference](/root/reference/root-api)
@@ -1,40 +0,0 @@
---
title: Инициализация системы
description: Настройка репозитория, Git-хуки и конфигурация PATH.
weight: 51
---
Общие модули требуют однократной инициализации на каждом хосте для создания связей путей и конфигураций на уровне репозитория.
## Скрипт `init.sh` {#init-script}
Скрипт `init.sh`, расположенный в корне репозитория, является основным механизмом начальной загрузки. Он выполняет следующие критические задачи:
1. **Инициализация субмодулей**: Гарантирует наличие и актуальность репозитория [Commons](/root/glossary#commons).
2. **Конфигурация Git-хуков**: Направляет `core.hooksPath` на `.operator/shared/githooks` для обеспечения стандартизированных проверок перед коммитом.
3. **Регистрация безопасной директории (Safe Directory)**: Добавляет репозиторий в список `safe.directory` Git, что необходимо для операций, выполняемых разными пользователями (например, `root`, `adam`).
4. **Конфигурация Vim**: Связывает стандартизированный `.vimrc` как для текущего пользователя, так и для пользователя `root` для обеспечения единообразия при редактировании.
5. **Сохранение PATH**: Добавляет директорию `.operator/shared/scripts/run` в `~/.bashrc` пользователя, делая команду `root` доступной глобально.
## Git-хуки {#githooks}
Root обеспечивает соблюдение стандартов через Git-хуки, хранящиеся в `.operator/shared/githooks/`.
- **Pre-commit**: Проверяет, что все скрипты соответствуют соглашениям о пространствах имен и структуре.
- **Commit-msg**: (Опционально) Обеспечивает соблюдение правил Conventional Commits, если это настроено.
## Конфигурация PATH {#path}
Команда `root` — это обертка (wrapper), расположенная по адресу `.operator/shared/scripts/run/root`. Добавляя эту директорию в `PATH`, диспетчер можно вызывать из любой директории в системе; он автоматически определит корень репозитория на основе текущей рабочей директории или переменных окружения.
```bash
# Пример добавления PATH вручную (выполняется автоматически скриптом init.sh)
export PATH="$HOME/repo/.operator/shared/scripts/run:$PATH"
```
---
**See also:**
- [Руководство: Начальная настройка хоста](/root/guides/installation)
- [Справочник: Справочник ROOT_ API Reference](/root/reference/root-api)
@@ -1,62 +0,0 @@
---
title: Справочник ROOT_ API
description: Стандартизированные переменные окружения и библиотеки ядра.
weight: 50
---
Каждый Action-скрипт, выполняемый через диспетчер `root`, имеет доступ к стандартизированному набору переменных окружения и Bash-библиотек. Это обеспечивает согласованный API для взаимодействия с инфраструктурой.
## Диспетчер `root` {#dispatcher}
Команда `root` (находится в `.operator/shared/scripts/run/root`) является основной точкой входа для всей оркестрации. Ее основные обязанности включают:
1. **Разрешение контекста**: Поиск целевого [Узла (Node)](/root/glossary#node) и связанных с ним [Уровней (Tiers)](/root/glossary#tier) хранилища.
2. **Загрузка библиотек**: Подключение основных библиотек ядра (например, `root_core`, `root_sys`).
3. **Выполнение Action-скриптов**: Поиск и запуск запрошенного действия, с приоритетом локальных переопределений.
## Переменные разрешения путей {#paths}
Эти переменные устанавливаются диспетчером и доступны всем Action-скриптам.
| Переменная | Описание |
| :--- | :--- |
| `ROOT_SHARED` | Абсолютный путь к репозиторию [Commons](/root/glossary#commons). |
| `ROOT_CONFIGS` | Абсолютный путь к основному репозиторию конфигураций. |
| `ROOT_LOCAL` | Абсолютный путь к директории локального оператора (`.operator/local`). |
| `ROOT_ACTIONS_SHARED` | Путь к глобальным общим Action-скриптам. |
| `ROOT_ACTIONS_LOCAL` | Путь к специфичным для узла локальным Action-скриптам. |
## Переменные контекста узла {#node-context}
Когда действие нацелено на конкретный узел, следующие переменные устанавливаются вспомогательной функцией `root_require_node`.
| Переменная | Описание |
| :--- | :--- |
| `ROOT_NODE` | Идентификатор целевого узла (например, `daedalus`). |
| `ROOT_NODE_DIR` | Абсолютный путь к директории конфигурации узла. |
| `ROOT_TIER1` | Абсолютный путь к директории [Уровня 1](/root/glossary#tier). |
| `ROOT_TIER2` | Абсолютный путь к директории Уровня 2. |
| `ROOT_TIER3` | Абсолютный путь к директории Уровня 3. |
## Основные функции логирования {#logging}
Стандартизированное логирование обеспечивает согласованный вывод всех действий.
- `root_log_info`: Стандартный информационный вывод.
- `root_log_warn`: Предупреждения, требующие внимания.
- `root_log_error`: Критические ошибки, отправляемые в `stderr`.
- `root_log_success`: Подтверждение успешного завершения задачи.
## Система помощи {#help}
Диспетчер предоставляет встроенную систему помощи, парся блок `action_metadata` в начале каждого скрипта. Это позволяет скриптам оставаться декларативными без реализации собственной обработки аргументов командной строки.
```bash filename="example-action-metadata"
action_metadata() {
cat <<EOF
description: "Краткое описание действия."
args:
- NODE: "Имя целевого узла."
EOF
}
```
@@ -1,42 +0,0 @@
---
title: Директория `source/`
description: Концептуальный обзор структуры изолированной директории исходного кода.
weight: 52
---
Директория `source/` в корне репозитория содержит основные компоненты и проекты, которыми управляют общие модули. Она разработана для максимальной изоляции и самодостаточности.
## Основная философия {#philosophy}
Директория `source/` — это не просто место для хранения кода; это коллекция независимых [Проектов](/root/glossary#project). Каждый проект в этой директории должен следовать следующим принципам:
1. **Изоляция**: Каждый проект живет в своей поддиректории (например, `source/my-app/`).
2. **Самодокументируемость**: Каждая директория проекта **ОБЯЗАНА** содержать собственный файл `README.md`, описывающий его назначение, зависимости и конфигурацию.
3. **Внутренняя логика**: Проекты сами управляют своими процессами сборки, Docker-файлами и внутренними конфигурациями. [Action-скрипты](/root/glossary#action) фреймворка Root просто оркеструют эти существующие компоненты.
## Структура директории {#structure}
Типичный проект в директории `source/` может выглядеть следующим образом:
{{< filetree/container >}}
{{< filetree/folder name="source" state="open" >}}
{{< filetree/folder name="happ-subscription-generator" state="open" >}}
{{< filetree/file name="Dockerfile" >}}
{{< filetree/file name="generator.py" >}}
{{< filetree/file name="README.md" >}}
{{< /filetree/folder >}}
{{< /filetree/folder >}}
{{< /filetree/container >}}
## Связь с Action-скриптами {#actions}
Action-скрипты (такие как `compose` или `sync`) взаимодействуют с директорией `source/`, ссылаясь на пути внутри нее. Например, действие `compose` может использовать файл `docker-compose.yml`, который указывает на `Dockerfile`, расположенный в `source/app/`.
Такое разделение ответственности гарантирует, что логика оркестрации (Action-скрипты) остается отвязанной от деталей реализации (Source).
---
**See also:**
- [Концепция: Архитектура инфраструктуры](/root/concepts/architecture)
- [Справочник: Справочник ROOT_ API Reference](/root/reference/root-api)
@@ -1,36 +0,0 @@
---
title: Операции синхронизации (Sync)
description: Обновление репозитория, синхронизация пакетов и резервное копирование данных.
weight: 54
---
Операции синхронизации гарантируют, что состояние хоста соответствует конфигурациям, определенным в удаленных репозиториях.
## Основные операции синхронизации {#actions}
| Операция | Описание |
| :--- | :--- |
| `sync/packages` | Синхронизирует пакеты узлов и их конфигурации по всей системе. |
| `sync/repository` | Обновляет основной репозиторий конфигураций до последней версии из GitHub. |
| `sync/tiers` | Запускает стратегию резервного копирования для настроенных [Уровней (Tiers)](/root/glossary#tier). |
## Синхронизация репозитория (`sync/repository`) {#repository}
Действие `sync/repository` отвечает за поддержание репозитория конфигураций хоста в актуальном состоянии. Оно обычно выполняет `git pull` в основном репозитории конфигураций и может опционально запускать обновление субмодулей для репозитория [Commons](/root/glossary#commons).
Это гарантирует, что любые изменения в конфигурациях узлов, действиях или исходных файлах будут корректно загружены на целевой хост.
## Синхронизация бэкапов (`sync/tiers`) {#tiers}
Действие `sync/tiers` является основной точкой входа для стратегии резервного копирования узла.
- **Нет реализации по умолчанию**: Сами общие модули не предоставляют механизма резервного копирования по умолчанию, позволяя операторам разработать пользовательскую стратегию, подходящую для их нужд.
- **Пользовательские переопределения**: Будучи действием диспетчера, его можно переопределить, поместив собственный скрипт в `.operator/local/scripts/actions/sync/tiers` для реализации специфичной для узла логики резервного копирования.
- **Пример реализации**: Распространенной практикой является использование такого инструмента, как [Restic](https://restic.net/), в рамках этого пользовательского скрипта для выполнения удаленного резервного копирования критически важных данных (Tiers 1 и 2) в S3-совместимое хранилище.
---
**See also:**
- [Концепция: Модель многоуровневого хранения](/root/concepts/tiered-storage)
- [Справочник: Справочник ROOT_ API Reference](/root/reference/root-api)
@@ -1,44 +0,0 @@
---
title: Операции управления уровнями (Tiers)
description: Классификация хранилища, символические ссылки и изоляция привилегий.
weight: 55
---
Операции управления уровнями отвечают за соблюдение [Модели многоуровневого хранения](/root/concepts/tiered-storage) и обеспечение корректного владения файловой системой и изоляции.
## Основные операции с уровнями (Tier Actions) {#actions}
| Операция | Описание |
| :--- | :--- |
| `tiers/chown` | Устанавливает корректного владельца файловой системы для [Пользователей проекта](#useradd). |
| `tiers/link` | Управляет символическими ссылками между директориями проекта и их соответствующими [Уровнями (Tiers)](/root/glossary#tier). |
| `tiers/useradd` | Создает уникального системного пользователя для каждого проекта для обеспечения [Изоляции привилегий](/root/concepts/security-model). |
## Управление пользователями (`tiers/useradd`) {#useradd}
Действие `tiers/useradd` создает выделенного низкопривилегированного системного пользователя для каждого проекта внутри узла. Этот пользователь затем используется для запуска контейнеров проекта, гарантируя, что компрометация одного проекта не даст злоумышленнику доступ ко всему хосту.
- **Соглашение об именовании**: Пользователи обычно называются в честь проекта.
- **Членство в группах**: Пользователи могут быть опционально добавлены в группу `docker` или взаимодействовать с Docker другими безопасно настроенными способами по выбору оператора.
## Привязка хранилища (`tiers/link`) {#link}
Действие `tiers/link` создает структуру символических ссылок, необходимую для модели многоуровневого хранения. Оно гарантирует, что директории `config`, `data` и `logs` внутри папки проекта указывают на их физическое местоположение в `@tier1`, `@tier2` и `@tier3` соответственно.
```bash
# Пример структуры ссылок, созданной tiers/link
/srv/root/icarus/synapse/config -> /srv/storage/@tier1/synapse
/srv/root/icarus/synapse/data -> /srv/storage/@tier2/synapse
/srv/root/icarus/synapse/logs -> /srv/storage/@tier3/synapse
```
## Управление владельцами (`tiers/chown`) {#chown}
После того как уровни и ссылки созданы, действие `tiers/chown` гарантирует, что физические директории на каждом уровне принадлежат правильному пользователю проекта. Это критически важно для предотвращения ошибок доступа и гарантии того, что проекты могут обращаться только к своим собственным данным.
---
**See also:**
- [Концепция: Модель многоуровневого хранения](/root/concepts/tiered-storage)
- [Концепция: Безопасность и изоляция привилегий](/root/concepts/security-model)
@@ -1,37 +0,0 @@
---
title: Вспомогательные операции (Utils)
description: Общие вспомогательные скрипты для обслуживания, валидации и управления сертификатами.
weight: 56
---
Вспомогательные операции предоставляют общие функции для обслуживания узлов, валидации и выполнения специфических задач проектов.
## Основные вспомогательные операции {#actions}
| Операция | Описание |
| :--- | :--- |
| `utils/extract-traefik-certs` | Извлекает сертификаты SSL/TLS и приватные ключи из хранилища Traefik `acme.json`. |
| `utils/generate-happ-subscriptions` | Автоматически генерирует файлы подписки HApp на основе текущих метаданных проекта. |
| `utils/lint-docker-compose` | Выполняет статический анализ всех файлов `docker-compose.yml` на соответствие стандартам общих модулей. |
## Управление сертификатами (`utils/extract-traefik-certs`) {#certificates}
Traefik сохраняет свои сертификаты, выпущенные через ACME (например, от Let's Encrypt), в одном файле `acme.json`. Действие `utils/extract-traefik-certs` парсит этот файл и извлекает отдельные файлы `fullchain.pem` и `privkey.pem`.
Это особенно полезно, когда другим сервисам (например, почтовым серверам или приложениям вне Docker) требуются те же SSL-сертификаты.
## Контроль качества (`utils/lint-docker-compose`) {#linting}
Для поддержания согласованности и безопасности действие `utils/lint-docker-compose` проверяет все compose-файлы в инфраструктуре. Оно проверяет:
- **Стандарты именования**: Гарантирует, что имена проектов и контейнеров соответствуют соглашению `{node}-{project}`.
- **Контекст безопасности**: Отмечает контейнеры, работающие под пользователем `root` без обоснованного переопределения.
- **Ограничения ресурсов**: Идентифицирует сервисы, у которых отсутствуют лимиты CPU или памяти.
- **Стандарты Label**: Проверяет наличие необходимых меток (labels) для маршрутизации (например, [Traefik](https://traefik.io/)) и [CrowdSec](/root/concepts/security-model#crowdsec).
---
**See also:**
- [Концепция: Принципы инфраструктуры](/root/concepts/principles)
- [Концепция: Безопасность и изоляция привилегий](/root/concepts/security-model)