Локальный генератор Dockerfile и k8s‑манифестов из app.yaml и Go text/template.
Использует шаблоны из папки templates/ и умеет подставлять значения по окружениям.
Сборка не требуется, можно запускать через go run:
go run ./cmd/manman \
-app ./app.yaml \
-templates ./templates \
-mode helm \
-team _default \
-env dev \
-image myrepo/app:tag \
-project-name myapp \
-branch main \
-commit abc123Выходной файл будет в текущей директории (manifests.yaml или Dockerfile по умолчанию).
Сборка бинарника:
go build -o manman ./cmd/manman
./manman -h-app— путь кapp.yaml(обязательный).-templates— каталог шаблонов (обязательный). Внутри ожидаются_default,<team>/_default,<team>/<language>.-mode—helmилиdockerfile(обязательный).-output— имя выходного файла (по умолчаниюmanifests.yamlилиDockerfile).-team— имя команды (по умолчанию_default).-env— окружение для env‑оверрайдов (по умолчаниюdev).-image— образ контейнера для манифестов.-project-name— имя проекта, попадает в шаблоны.-project-id— передается в генератор (по умолчанию не используется в шаблонах).-branch,-commit,-release— значения, доступные в шаблонах.-secret-key— hex‑ключ AES для расшифровкиsecrets.envsиsecret-values.yaml.
Шаблоны ищутся в порядке:
_default<team>/_default<team>/<language>
Если файл найден позже, он перекрывает предыдущий.
Поддерживаемые файлы в шаблонах (пример из templates/_default):
dockerfile.tmplapi.yaml.tmplapi_hpa.yaml.tmplcronjob.yaml.tmplworker.yaml.tmplmigration.yaml.tmplingress.yaml.tmpltolerations.yaml,affinity.yaml(данные для подстановки в pod spec)
Почти любое поле в app.yaml может быть обычным значением или map с ключами окружений.
Правило выбора:
- если есть ключ текущего окружения, берется он;
- иначе берется
_default; - если ничего нет, поле считается пустым.
Пример:
port:
_default: 8000
production: 80Ниже — «полный» пример, в котором есть все поддерживаемые секции и поля. Можно копировать и удалять ненужное.
engine:
language:
name: python # влияет на выбор папки шаблонов <team>/<language>
version: "3.11" # используется в Dockerfile шаблоне
additional_system_packages: [] # список пакетов для apt-get (Dockerfile)
package_manager:
name: pip # Dockerfile (опционально)
version: "23.2"
envs:
LOG_LEVEL:
_default: INFO
production: WARN
apis:
- name: api
command: python app.py
enabled: true
replicas:
_default: 2
production: 4
port: 8000
memory_limits: 512Mi
requests:
memory: 256Mi
cpu: 250m
envs:
SERVICE_MODE: api
hpa:
min_replicas: 2
max_replicas: 10
target_cpu_utilization_percent: 70
ingress:
domain:
_default: api.dev.example.com
production: api.example.com
proxy-body-size: 70M
workers:
- name: queue
command: python worker.py
enabled: true
replicas: 1
memory_limits: 256Mi
requests:
memory: 128Mi
cpu: 100m
envs:
WORKER_QUEUE: main
cronjobs:
- name: cleanup
command: ./bin/cleanup
enabled: true
schedule: "*/5 * * * *"
concurrency: forbid # allow|forbid|replace (регистр не важен)
envs:
CLEANUP_MODE: fast
db_migrations:
- command: ./bin/migrate up
envs:
MIGRATE_LOCK: "true"
secrets:
envs:
DATABASE_URL: "ENCRYPTED_HEX"
API_KEY:
_default: "ENCRYPTED_HEX"
production: "ENCRYPTED_HEX"Шаблоны _default (по умолчанию) формируют:
- Deployment для
apisиworkers - CronJob для
cronjobs - Job для
db_migrations - HPA для
apisпри наличииhpa - Ingress + Certificate для
apisпри наличииingress.domain - Dockerfile на основе
engine.*
Если ingress.domain пустой, ingress не рендерится.
Эти значения доступны как .xxx в шаблонах:
.image,.project_name,.current_env.branch_name,.commit,.manman_release.team.envs(глобальныеenvs+envsконкретной сущности).tolerations,.affinity(изtolerations.yaml/affinity.yaml)
Дополнительно для каждого типа:
- API:
.name,.command,.replicas,.port,.memory_limits,.memory_requests,.cpu_requests,.is_hpa_enabled - Worker:
.name,.command,.replicas,.memory_limits,.memory_requests,.cpu_requests - CronJob:
.name,.command,.schedule,.concurrency - Migration:
.command - Ingress:
.name,.domain,.proxy_body_size
Есть два источника секретов:
app.yaml→secrets.envs- файл рядом с
app.yaml:secret-values.yaml
secret-values.yaml автоматически подмешивается. Вложенные ключи превращаются в имена
переменных окружения через __:
videosdk:
api_key: ENCстановится videosdk__api_key: ENC.
Если значение — это env‑оверрайд карта (_default, production), она сохраняется как есть:
db:
url:
_default: ENC_DEV
production: ENC_PRODстановится db__url: { _default: ENC_DEV, production: ENC_PROD }.
Если в итоговом манифесте есть secrets.envs, обязательно передайте -secret-key
(hex‑ключ AES). Иначе генерация завершится с ошибкой.
enabledможет бытьtrue/false, строкой ("true") или числом (1/0).cronjobs[].concurrencyнормализуется вAllow/Forbid/Replace. Пустое значение приведет к невалидному манифесту — укажите его явно.envsу сущностей перекрывают одноименные ключи из глобальныхenvs.- Автоматически добавляются env:
CURRENT_ENVиCOMMIT(если передан флаг-commit). - В дефолтном
api.yaml.tmplпорт контейнера захардкожен в8000; полеapis[].portбудет учитываться только если вы используете свой шаблон. - В дефолтном
api_hpa.yaml.tmplscaleTargetRef.nameравенproject_name; если deployment назван иначе, обновите шаблон под себя.
engine:
language:
name: python
version: "3.11"
additional_system_packages: []
apis:
- name: api
command: python app.py
enabled: true
replicas: 1
port: 8000
cronjobs:
- name: cleanup
command: ./bin/cleanup
enabled: true
schedule: "0 * * * *"
concurrency: allow