Skip to content

Формат профиля ​

Профиль — это описание желаемого состояния хоста на YAML: какие пакеты должны стоять, какие службы работать, что лежать в конфигурационных файлах, какие порты открыты, кто имеет доступ и какие сервисы подняты из compose. Это не язык программирования: ни порядка выполнения, ни условий, ни переменных — плоский список того, что должно быть.

Профиль аддитивный и не выключает того, о чём молчит: пакет, которого нет в списке, не удаляется, а не упомянутая служба не останавливается. Поэтому «не указано» и «должно быть выключено» — разные вещи: у служб это разница между отсутствующим ключом и «active: false».

Порядок работы такой: правите описание и сохраняете его, нажимаете «план» — хост сравнивает описанное с действительным и показывает расхождения по пунктам; снимаете галочки с того, что применять не надо, и нажимаете «применить» — каждый пункт выполняется как фоновое задание с журналом. Сохранённый профиль дальше проверяется сам, и разошедшееся состояние показывается среди находок хоста.

Как профили хранятся, применяются и назначаются группам — Профили.

Коротко ​

РазделЧто задаёт
Заголовок: version и nameversion — версия формата (сейчас 1), name — имя профиля; под ним он показывается в списке и в журнале заданий.
packages — пакетыПакеты, которые должны быть установлены; ставятся apt.
services — службы systemdУ каждой службы два независимых признака: enabled — включён ли автозапуск, active — работает ли она сейчас.
files — файлы конфигурацииСодержимое целиком, а не хеш: по хешу видно расхождение, но нечем его закрыть.
firewall — открытые портыПеречисляются порты, доступ к которым должен быть открыт.
users — учётные записиУчётная запись заводится, если её нет; sudo: true выдаёт право sudo без пароля; keys добавляются в authorized_keys.
system — имя машины и часовой поясhostname видно в сертификатах, журналах и приглашении оболочки, поэтому смена помечается опасной.
compose — сервисы из docker composeСтек описывается целиком: name — имя стека (оно же имя каталога и имя проекта docker), content — сам compose-файл, up — должен ли стек быть поднят (по умолчанию да).

Разделы ​

Заголовок: version и name ​

version — версия формата (сейчас 1), name — имя профиля; под ним он показывается в списке и в журнале заданий.

Пример:

yaml
version: 1
name: web-server

packages — пакеты ​

Пакеты, которые должны быть установлены; ставятся apt. Лишние не удаляются — профиль только добавляет.

Пример:

yaml
packages:
  - nginx
  - btop

services — службы systemd ​

У каждой службы два независимых признака: enabled — включён ли автозапуск, active — работает ли она сейчас. Указывайте только то, что вам важно: пропущенный ключ значит «не моё дело», false — «должно быть выключено».

Пример:

yaml
services:
  nginx:
    enabled: true
    active: true
  apache2:
    active: false

files — файлы конфигурации ​

Содержимое целиком, а не хеш: по хешу видно расхождение, но нечем его закрыть. Запись идёт тем же путём, что и ручная правка: содержимое проверяется самой службой (nginx -t, docker compose config и т. д.), сохраняется в истории версий и откатывается, если проверка не прошла. mode — права в восьмеричном виде, без него новый файл создаётся с 0644, а у существующего права не меняются.

Пример:

yaml
files:
  - path: /etc/motd
    mode: "0644"
    content: |
      Managed by nkt

firewall — открытые порты ​

Перечисляются порты, доступ к которым должен быть открыт. Чем именно закрыт хост — ufw или firewalld — профиль не решает: это выбирает сам хост. proto по умолчанию tcp, from ограничивает источник адресом или подсетью. Правило для порта 22 помечается опасным: им можно отрезать себе доступ.

Пример:

yaml
firewall:
  allow:
    - port: 443
    - port: 5432
      proto: tcp
      from: 10.0.0.0/24

users — учётные записи ​

Учётная запись заводится, если её нет; sudo: true выдаёт право sudo без пароля; keys добавляются в authorized_keys. Чужие ключи не удаляются — их мог положить человек, а не забытый профиль. Выдача sudo и правка ключей помечаются опасными.

Пример:

yaml
users:
  - name: deploy
    sudo: true
    keys:
      - "ssh-ed25519 AAAA... deploy@laptop"

system — имя машины и часовой пояс ​

hostname видно в сертификатах, журналах и приглашении оболочки, поэтому смена помечается опасной. timezone — имя зоны из базы tzdata.

Пример:

yaml
system:
  hostname: web-1
  timezone: Europe/Moscow

compose — сервисы из docker compose ​

Стек описывается целиком: name — имя стека (оно же имя каталога и имя проекта docker), content — сам compose-файл, up — должен ли стек быть поднят (по умолчанию да). Файл без явного path кладётся в /srv/compose/<имя>/docker-compose.yml — свой каталог, чтобы применение не переписывало то, что вы ведёте руками. В плане это два отдельных пункта: записать описание и поднять стек — чтобы было видно, когда перезапустятся работающие контейнеры. up: false выполняет docker compose down; тома при этом не трогаются. Если docker на хосте нет, план первым пунктом предложит его установить — по официальной инструкции, из репозитория docker.com: в репозитории дистрибутива пакет отстаёт, а compose-плагина может не быть вовсе. Пункт отдельный и снимается галочкой.

Пример:

yaml
compose:
  - name: shop
    up: true
    content: |
      services:
        web:
          image: nginx:1.27
          ports: ["8080:80"]

Чего профиль не делает ​

  • Не удаляет пакеты, службы, файлы и учётные записи, которых нет в описании.
  • Не следит за файлом после применения: следующая проверка просто покажет расхождение.
  • Не задаёт порядок и зависимости — пункты плана выполняются сверху вниз, как показаны.
  • Не удаляет данные: docker compose down оставляет тома, а удаление диска или каталога делается отдельно и вручную.

Готовые профили ​

Базовый сервер ​

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

yaml
version: 1
name: base
packages:
  - htop
  - curl
  - ncdu
system:
  timezone: Europe/Moscow
users:
  - name: deploy
    keys:
      - "ssh-ed25519 AAAA... deploy@laptop"
firewall:
  allow:
    - port: 22

Веб-сервер nginx ​

nginx установлен, включён и работает, порты 80 и 443 открыты, приветствие при входе — из профиля.

yaml
version: 1
name: web-server
packages:
  - nginx
services:
  nginx:
    enabled: true
    active: true
firewall:
  allow:
    - port: 80
    - port: 443
files:
  - path: /etc/motd
    mode: "0644"
    content: |
      web server, managed by nkt

Docker-хост со стеком ​

Стек compose с веб-сервером поднят; если Docker на хосте нет, план первым пунктом предложит его поставить.

yaml
version: 1
name: docker-host
compose:
  - name: web
    up: true
    content: |
      services:
        web:
          image: nginx:1.27
          ports: ["8080:80"]
          restart: unless-stopped