chore: docker compose, dockerfiles, caddy snippet, readme

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BCrwHHnGCB5XH968Nxokqw
This commit is contained in:
nikita.hohlov
2026-09-04 08:35:59 -03:00
parent 95c0e53eb8
commit 10eb65e9c4
5 changed files with 119 additions and 0 deletions

42
README.md Normal file
View File

@@ -0,0 +1,42 @@
# Hado — 波 · ядро умных уведомлений
Сервисы пушат события с датой, ядро само считает каскад напоминаний, окна и
доставляет туда, где ты сейчас доступен (веб, Telegram, webhook/Home Assistant).
Спека: `docs/superpowers/specs/2026-09-03-hado-core-design.md`.
## Dev
```bash
cp core/.env.example core/.env
docker compose up -d --build
docker compose exec app php artisan key:generate
docker compose exec app php artisan migrate
docker compose exec app php artisan hado:source:create docs # токен печатается один раз
```
- http://localhost:8080/ — инбокс (нужен заголовок `X-Remote-User`; локально: расширение
браузера для заголовков или `curl -H 'X-Remote-User: nikita' localhost:8080/me`)
- `PUT /api/events` с `Authorization: Bearer <токен>` — см. спеку §5
Тесты локально: `cd core && php artisan test` (SQLite in-memory, нужны расширения
`pdo_sqlite`, `intl` в php.ini). Стиль: `vendor/bin/pint`.
## Telegram
1. Создай бота у @BotFather, положи токен и username в `core/.env`.
2. Придумай `TELEGRAM_WEBHOOK_SECRET`, зарегистрируй webhook:
`curl "https://api.telegram.org/bot<TOKEN>/setWebhook?url=https://hado.<домен>/hooks/telegram&secret_token=<SECRET>"`
3. В инбоксе «Подключить Telegram» → отправь боту `/start <код>`.
## Home Assistant
В инбоксе добавь webhook-канал: `deliver_url` — HA webhook-триггер
(`https://ha/api/webhook/<id>`), `presence_url` — любой URL, отвечающий
`{"present": true|false}` (например, template-сенсор через REST API или Node-RED).
Автоматизация в HA получает JSON `{event, actions}` и может дёрнуть `actions.done`
POST-ом без авторизации.
## Прод
`core/Dockerfile` (serversideup/php), compose с `scheduler` и `worker`, Caddy —
`deploy/Caddyfile.snippet` в хаб sekai.

4
core/Dockerfile Normal file
View File

@@ -0,0 +1,4 @@
FROM serversideup/php:8.4-fpm-nginx AS base
USER www-data
COPY --chown=www-data:www-data . /var/www/html
RUN composer install --no-dev --optimize-autoloader

7
core/Dockerfile.dev Normal file
View File

@@ -0,0 +1,7 @@
FROM php:8.4-cli
RUN apt-get update && apt-get install -y --no-install-recommends libpq-dev git unzip \
&& docker-php-ext-install pdo_pgsql pgsql \
&& rm -rf /var/lib/apt/lists/*
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /app
CMD ["php", "artisan", "serve", "--host=0.0.0.0", "--port=8000"]

12
deploy/Caddyfile.snippet Normal file
View File

@@ -0,0 +1,12 @@
# Hado: публичные пути (клиенты по токену, кнопки из каналов, Telegram) идут мимо SSO,
# всё остальное — через forward_auth хаба. Порядок матчеров важен.
hado.{$DOMAIN} {
@public path /api/* /a/* /hooks/* /up
handle @public {
reverse_proxy <hado-wireguard-ip>:8080
}
handle {
import protected
reverse_proxy <hado-wireguard-ip>:8080
}
}

54
docker-compose.yml Normal file
View File

@@ -0,0 +1,54 @@
services:
app:
build:
context: ./core
dockerfile: Dockerfile.dev
volumes:
- ./core:/app
ports:
- "8080:8000"
env_file: ./core/.env
depends_on:
postgres:
condition: service_healthy
scheduler:
build:
context: ./core
dockerfile: Dockerfile.dev
command: php artisan schedule:work
volumes:
- ./core:/app
env_file: ./core/.env
depends_on:
postgres:
condition: service_healthy
worker:
build:
context: ./core
dockerfile: Dockerfile.dev
command: php artisan queue:work --tries=3 --sleep=1
volumes:
- ./core:/app
env_file: ./core/.env
depends_on:
postgres:
condition: service_healthy
postgres:
image: postgres:17
environment:
POSTGRES_DB: hado
POSTGRES_USER: hado
POSTGRES_PASSWORD: hado
volumes:
- pg_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U hado -d hado"]
interval: 5s
timeout: 3s
retries: 10
volumes:
pg_data: