# Архитектура

На этой странице описывается внутреннее устройство Rediacc: архитектура из двух инструментов, обнаружение адаптера, модель безопасности и структура конфигурации.

## Full Stack Overview

Traffic flows from the internet through a reverse proxy, into isolated Docker daemons, each backed by encrypted storage:

![Full Stack Architecture](/img/arch-full-stack.svg)

Each repository gets its own Docker daemon, loopback IP subnet (/26 = 64 IPs), and LUKS-encrypted BTRFS volume. The route server discovers running containers across all daemons and feeds routing configuration to Traefik.

## Архитектура из двух инструментов

Rediacc использует два бинарных файла, работающих совместно через SSH:

![Архитектура из двух инструментов](/img/arch-two-tool.svg)

- **rdc** работает на вашей рабочей станции (macOS, Linux или Windows). Он считывает локальную конфигурацию, подключается к удаленным машинам по SSH и вызывает команды renet.
- **renet** работает на удаленном сервере с привилегиями root. Он управляет LUKS-зашифрованными образами дисков, изолированными Docker-демонами, оркестрацией сервисов и конфигурацией обратного прокси.

Каждая команда, которую вы вводите локально, транслируется в SSH-вызов, выполняющий renet на удаленной машине. Вам никогда не нужно подключаться к серверам по SSH вручную.

Советы для операторов см. в разделе [rdc vs renet](/ru/docs/rdc-vs-renet). Также вы можете использовать `rdc ops` для запуска локального кластера VM для тестирования, см. [Экспериментальные VM](/ru/docs/experimental-vms).

## Конфигурация

Всё состояние CLI хранится в плоских JSON-файлах конфигурации в `~/.config/rediacc/`.

### Локальный адаптер (по умолчанию)

Режим по умолчанию для самостоятельного размещения. Всё состояние хранится в файле конфигурации на вашей рабочей станции (например, `~/.config/rediacc/rediacc.json`).

- Прямые SSH-подключения к машинам
- Не требуются внешние сервисы
- Один пользователь, одна рабочая станция
- Конфигурация по умолчанию создаётся автоматически при первом использовании CLI. Именованные конфигурации создаются с помощью `rdc config init <name>`

### Облачный адаптер (экспериментальный)

Активируется автоматически, когда конфигурация содержит поля `apiUrl` и `token`. Использует API Rediacc для управления состоянием и командной работы.

- Состояние хранится в облачном API
- Многопользовательские команды с ролевым доступом
- Веб-консоль для визуального управления
- Настраивается с помощью `rdc auth login`

> **Примечание:** Команды облачного адаптера являются экспериментальными. Включите их, установив переменную `REDIACC_EXPERIMENTAL=1`.

Оба адаптера используют одни и те же команды CLI. Адаптер влияет только на то, где хранится состояние и как работает аутентификация.

## Пользователь rediacc

При выполнении `rdc config machine setup` renet создает системного пользователя `rediacc` на удаленном сервере:

- **UID**: 7111
- **Оболочка**: `/sbin/nologin` (не может входить через SSH)
- **Назначение**: Владеет файлами репозиториев и выполняет функции Rediaccfile

Пользователь `rediacc` не может быть доступен через SSH напрямую. Вместо этого rdc подключается как SSH-пользователь, которого вы настроили (например, `deploy`), а renet выполняет операции с репозиториями через `sudo -u rediacc /bin/sh -c '...'`. Это означает:

1. Вашему SSH-пользователю нужны привилегии `sudo`
2. Все данные репозитория принадлежат `rediacc`, а не вашему SSH-пользователю
3. Функции Rediaccfile (`up()`, `down()`) выполняются от имени `rediacc`

Такое разделение обеспечивает единообразное владение данными репозитория независимо от того, какой SSH-пользователь управляет им.

## Изоляция Docker

Каждый репозиторий получает собственный изолированный Docker-демон. При монтировании репозитория renet запускает выделенный процесс `dockerd` с уникальным сокетом:

![Изоляция Docker](/img/arch-docker-isolation.svg)

```
/var/run/rediacc/docker-{networkId}.sock
```

Например, репозиторий с идентификатором сети `2816` использует:
```
/var/run/rediacc/docker-2816.sock
```

Это означает:
- Контейнеры из разных репозиториев не могут видеть друг друга
- Каждый репозиторий имеет собственный кеш образов, сети и тома
- Docker-демон хоста (если есть) полностью отделен

Функции Rediaccfile автоматически получают переменную `DOCKER_HOST`, указывающую на правильный сокет.

## Шифрование LUKS

Репозитории представляют собой LUKS-зашифрованные образы дисков, хранящиеся в хранилище данных сервера (по умолчанию: `/mnt/rediacc`). Каждый репозиторий:

1. Имеет случайно сгенерированную парольную фразу шифрования ("учетные данные")
2. Хранится как файл: `{datastore}/repos/{guid}.img`
3. Монтируется через `cryptsetup` при доступе

Учетные данные хранятся в вашем файле конфигурации, но **никогда** на сервере. Без учетных данных данные репозитория не могут быть прочитаны. При включении автозапуска на сервере хранится вторичный LUKS-ключевой файл для автоматического монтирования при загрузке.

## Структура конфигурации

Каждая конфигурация, это плоский JSON-файл, хранящийся в `~/.config/rediacc/`. Конфигурация по умолчанию, `rediacc.json`; именованные конфигурации используют имя в качестве имени файла (например, `production.json`). Вот аннотированный пример:

```json
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "version": 1,
  "ssh": {
    "privateKeyPath": "/home/you/.ssh/id_ed25519"
  },
  "machines": {
    "prod-1": {
      "ip": "203.0.113.50",
      "user": "deploy",
      "port": 22,
      "datastore": "/mnt/rediacc",
      "knownHosts": "203.0.113.50 ssh-ed25519 AAAA..."
    }
  },
  "storages": {
    "backblaze": {
      "provider": "b2",
      "vaultContent": { "...": "..." }
    }
  },
  "repositories": {
    "webapp": {
      "repositoryGuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "credential": "base64-encoded-random-passphrase",
      "networkId": 2816
    }
  },
  "nextNetworkId": 2880,
  "universalUser": "rediacc"
}
```

**Ключевые поля:**

| Поле | Описание |
|------|----------|
| `id` | Уникальный идентификатор этого файла конфигурации |
| `version` | Версия схемы файла конфигурации |
| `ssh.privateKeyPath` | Приватный SSH-ключ, используемый для всех подключений к машинам |
| `machines.<name>.user` | Имя пользователя SSH для подключения к машине |
| `machines.<name>.knownHosts` | SSH-ключи хоста из `ssh-keyscan` |
| `repositories.<name>.repositoryGuid` | UUID, идентифицирующий зашифрованный образ диска |
| `repositories.<name>.credential` | Парольная фраза шифрования LUKS (**не хранится на сервере**) |
| `repositories.<name>.networkId` | Определяет IP-подсеть (2816 + n*64), назначается автоматически |
| `nextNetworkId` | Глобальный счётчик для назначения идентификаторов сети |
| `universalUser` | Переопределение системного пользователя по умолчанию (`rediacc`) |

> Этот файл содержит конфиденциальные данные (пути к SSH-ключам, учетные данные LUKS). Он хранится с правами `0600` (чтение/запись только для владельца). Не делитесь им и не добавляйте в систему контроля версий.