158 lines
5.7 KiB
Markdown
158 lines
5.7 KiB
Markdown
# Contract: Application Binary
|
||
|
||
Version: 1.0
|
||
|
||
## Purpose
|
||
|
||
Правила сборки, упаковки ресурсов и первого запуска Go-приложений.
|
||
|
||
---
|
||
|
||
## Расположение на хосте
|
||
|
||
> Это правило применяется когда ИИ самостоятельно разворачивает приложение или выполняет команды на build-машине (деплой, копирование файлов, запуск сервисов).
|
||
|
||
Бинарник приложения размещается в директории:
|
||
|
||
```
|
||
/appdata/<appname>/
|
||
```
|
||
|
||
где `<appname>` — имя приложения (строчными буквами, без пробелов).
|
||
|
||
Пример: приложение `myservice` → `/appdata/myservice/myservice`.
|
||
|
||
Все файлы, связанные с конкретным приложением (бинарник, вспомогательные скрипты запуска, `docker-compose.yml`), хранятся внутри этой директории. Конфиг и данные — по правилам секций ниже.
|
||
|
||
### Примеры внедрения
|
||
|
||
При деплое, копировании файлов или запуске сервисов ИИ **всегда по умолчанию** использует этот путь:
|
||
|
||
```bash
|
||
# Копирование бинарника
|
||
scp bin/myservice user@host:/appdata/myservice/myservice
|
||
|
||
# Копирование docker-compose
|
||
scp docker-compose.yml user@host:/appdata/myservice/docker-compose.yml
|
||
|
||
# Запуск на хосте
|
||
ssh user@host "cd /appdata/myservice && docker compose up -d"
|
||
```
|
||
|
||
```bash
|
||
# Создание директории если не существует
|
||
ssh user@host "mkdir -p /appdata/myservice"
|
||
```
|
||
|
||
Не предлагать альтернативные пути (`/opt/`, `/usr/local/bin/`, `~/`) — только `/appdata/<appname>/`.
|
||
|
||
---
|
||
|
||
## Бинарник
|
||
|
||
Бинарник самодостаточен — все ресурсы встроены через `//go:embed`:
|
||
|
||
- HTML-шаблоны
|
||
- Статика (JS, CSS, иконки)
|
||
- Шаблон конфиг-файла (`config.template.yaml`)
|
||
- Миграции БД
|
||
|
||
Никаких внешних папок рядом с бинарником не требуется для запуска.
|
||
|
||
---
|
||
|
||
## Конфиг-файл
|
||
|
||
Создаётся автоматически при первом запуске, если не существует.
|
||
|
||
### Расположение
|
||
|
||
| Режим приложения | Путь |
|
||
|---|---|
|
||
| Однопользовательское | `~/.config/<appname>/config.yaml` |
|
||
| Серверное / многопользовательское | `/etc/<appname>/config.yaml` или рядом с бинарником |
|
||
|
||
Приложение само определяет путь и создаёт директорию если её нет.
|
||
|
||
### Содержимое
|
||
|
||
Конфиг хранит:
|
||
|
||
- Настройки приложения (порт, язык, таймауты, feature flags)
|
||
- Параметры подключения к централизованной СУБД (host, port, user, password, dbname)
|
||
|
||
Конфиг **не хранит**:
|
||
|
||
- Данные пользователя
|
||
- Кеш или состояние
|
||
- Что-либо что относится к SQLite (см. ниже)
|
||
|
||
### Шаблон
|
||
|
||
Шаблон конфига встроен в бинарник. При создании файла шаблон копируется в целевой путь.
|
||
Шаблон содержит все ключи с комментариями и дефолтными значениями.
|
||
|
||
```yaml
|
||
# <appname> configuration
|
||
# Generated on first run. Edit as needed.
|
||
|
||
server:
|
||
port: 8080
|
||
|
||
database:
|
||
host: localhost
|
||
port: 5432
|
||
user: ""
|
||
password: ""
|
||
dbname: ""
|
||
|
||
# ... остальные настройки
|
||
```
|
||
|
||
---
|
||
|
||
## SQLite (однопользовательский режим)
|
||
|
||
Если приложение использует локальную SQLite:
|
||
|
||
- Файл хранится рядом с конфигом: `~/.config/<appname>/<appname>.db`
|
||
- Путь к файлу не выносится в конфиг — приложение вычисляет его из пути конфига
|
||
- SQLite **не хранит** параметры подключения к централизованной СУБД — только локальные данные приложения
|
||
|
||
---
|
||
|
||
## Первый запуск — алгоритм
|
||
|
||
```
|
||
Старт приложения
|
||
│
|
||
├── Конфиг существует? → Нет → создать директорию → скопировать шаблон → сообщить пользователю путь
|
||
│ → завершить с кодом 0
|
||
│ (пользователь заполняет конфиг)
|
||
└── Конфиг существует? → Да → валидировать → запустить приложение
|
||
```
|
||
|
||
При первом создании конфига приложение **не запускается** — выводит сообщение:
|
||
|
||
```
|
||
Config created: ~/.config/<appname>/config.yaml
|
||
Edit the file and restart the application.
|
||
```
|
||
|
||
---
|
||
|
||
## Сборка
|
||
|
||
Финальный бинарник собирается без CGO если это возможно (для SQLite — с CGO):
|
||
|
||
```
|
||
CGO_ENABLED=0 go build -ldflags="-s -w" -o bin/<appname> ./cmd/<appname>
|
||
```
|
||
|
||
С SQLite:
|
||
```
|
||
CGO_ENABLED=1 go build -ldflags="-s -w" -o bin/<appname> ./cmd/<appname>
|
||
```
|
||
|
||
Бинарник не зависит от рабочей директории запуска.
|