009 add docker compose
This commit is contained in:
+16
@@ -0,0 +1,16 @@
|
||||
FROM python:3.14-slim
|
||||
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN pip install --no-cache-dir poetry
|
||||
|
||||
COPY pyproject.toml poetry.lock ./
|
||||
RUN poetry config virtualenvs.create false \
|
||||
&& poetry install --no-interaction --no-root
|
||||
|
||||
COPY app ./app
|
||||
COPY config.yaml ./config.yaml
|
||||
|
||||
CMD ["poetry", "run", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||
+25
-1
@@ -1,6 +1,25 @@
|
||||
services:
|
||||
app:
|
||||
image: yusupal1ev/g2s-aggregator:0.0.0
|
||||
environment:
|
||||
G2S_CONFIG_FILE: /app/config.yaml
|
||||
G2S_REPOSITORY__REDIS_DSN: redis://redis:6379/0
|
||||
G2S_OBSERVABILITY__OTLP_ENDPOINT: http://signoz:4317
|
||||
PYTHONUNBUFFERED: "1"
|
||||
ports:
|
||||
- "8000:8000"
|
||||
depends_on:
|
||||
- redis
|
||||
- signoz
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
command: ["redis-server", "--save", "", "--appendonly", "no"]
|
||||
ports:
|
||||
- "6379:6379"
|
||||
|
||||
signoz:
|
||||
image: signoz/signoz:0.82.0
|
||||
image: signoz/signoz:latest
|
||||
container_name: signoz
|
||||
environment:
|
||||
G2S_ALERTS__TELEGRAM_BOT_TOKEN: ${G2S_ALERTS__TELEGRAM_BOT_TOKEN:-}
|
||||
@@ -9,5 +28,10 @@ services:
|
||||
SIGNOZ_ALERTS_RULES_FILE: /etc/signoz/alerts/signoz_alert_rules.yaml
|
||||
ports:
|
||||
- "3301:3301"
|
||||
- "4317:4317"
|
||||
volumes:
|
||||
- signoz_data:/var/lib/signoz
|
||||
- ./infra/alerts:/etc/signoz/alerts:ro
|
||||
|
||||
volumes:
|
||||
signoz_data:
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# Local Infrastructure Stack
|
||||
|
||||
## Services
|
||||
|
||||
- `app`: FastAPI service (`uvicorn app.main:app`) built from root `Dockerfile`
|
||||
- `redis`: price cache backend
|
||||
- `signoz`: observability backend (UI + OTLP receiver)
|
||||
|
||||
## Environment wiring
|
||||
|
||||
### `app` service
|
||||
|
||||
- `G2S_CONFIG_FILE=/app/config.yaml`
|
||||
- `G2S_REPOSITORY__REDIS_DSN=redis://redis:6379/0`
|
||||
- `G2S_OBSERVABILITY__OTLP_ENDPOINT=http://signoz:4317`
|
||||
- `PYTHONUNBUFFERED=1`
|
||||
|
||||
### `signoz` service
|
||||
|
||||
- `G2S_ALERTS__TELEGRAM_BOT_TOKEN` (optional for Telegram alerts)
|
||||
- `G2S_ALERTS__TELEGRAM_CHAT_ID` (optional for Telegram alerts)
|
||||
|
||||
## Startup instructions
|
||||
|
||||
1. Validate compose syntax:
|
||||
- `docker compose config`
|
||||
2. Start dependencies:
|
||||
- `docker compose up -d redis signoz`
|
||||
3. Verify running containers:
|
||||
- `docker compose ps`
|
||||
4. Start application:
|
||||
- `docker compose up -d app`
|
||||
5. Stop local stack:
|
||||
- `docker compose down`
|
||||
|
||||
## Smoke command sequence
|
||||
|
||||
```bash
|
||||
docker compose config
|
||||
docker compose up -d redis signoz
|
||||
docker compose ps
|
||||
```
|
||||
+5
-4
@@ -1,7 +1,7 @@
|
||||
# Spec Tasks Index
|
||||
|
||||
> ⚠️ This file is generated. Do not edit manually.
|
||||
> Generated at (UTC): `2026-03-08T09:04:29+00:00`
|
||||
> Generated at (UTC): `2026-03-08T12:18:20+00:00`
|
||||
|
||||
## Tasks
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
| 006 | DONE | 2026-03-07 | Add delivery price controller endpoint | `spec/tasks/006_add_delivery_price_controller.md` |
|
||||
| 007 | DONE | 2026-03-07 | Add observability correlation and telemetry | `spec/tasks/007_add_observability_correlation.md` |
|
||||
| 008 | DONE | 2026-03-07 | Add SigNoz to Telegram alerting configuration | `spec/tasks/008_add_signoz_telegram_alerting.md` |
|
||||
| 009 | TODO | 2026-03-07 | Add local infrastructure stack | `spec/tasks/009_add_local_infra_stack.md` |
|
||||
| 009 | DONE | 2026-03-07 | Add local infrastructure stack | `spec/tasks/009_add_local_infra_stack.md` |
|
||||
| 010 | TODO | 2026-03-08 | Migrate to YAML-only configuration loading | `spec/tasks/010_migrate_to_yaml_only_configuration.md` |
|
||||
|
||||
## Summary
|
||||
|
||||
- Total: **10**
|
||||
- Total: **11**
|
||||
- TODO: **1**
|
||||
- DONE: **9**
|
||||
- DONE: **10**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: 009
|
||||
title: Add local infrastructure stack
|
||||
status: TODO
|
||||
status: DONE
|
||||
created: 2026-03-07
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: 010
|
||||
title: Migrate to YAML-only configuration loading
|
||||
status: TODO
|
||||
created: 2026-03-08
|
||||
---
|
||||
|
||||
## Context
|
||||
В проекте используется смешанный подход конфигурации с переменными окружения. Требуется унифицировать источник конфигурации и оставить только `config.yaml`.
|
||||
|
||||
## Goal
|
||||
Убрать использование переменных окружения из runtime-конфигурации приложения и перевести загрузку всех параметров на чтение из `config.yaml`.
|
||||
|
||||
## Constraints
|
||||
- Соблюдать layered architecture из `AGENTS.md`.
|
||||
- Scope задачи: только механизм загрузки конфигурации и места её потребления.
|
||||
- Запрещено менять бизнес-правила и поведение use-case, не связанное с конфигурацией.
|
||||
- Не изменять файлы в `spec/`.
|
||||
|
||||
## Acceptance criteria
|
||||
- Runtime-конфигурация приложения загружается только из `config.yaml`.
|
||||
- Переменные окружения не используются для чтения параметров Controller, Service, Business Logic, Repository, Adapter, Observability и Alerts.
|
||||
- При отсутствии обязательных полей в `config.yaml` приложение завершает запуск с детерминированной ошибкой валидации конфигурации.
|
||||
- Тесты конфигурации больше не опираются на `monkeypatch` переменных окружения и проверяют чтение из YAML.
|
||||
|
||||
## Definition of Done
|
||||
- [ ] Удалено чтение переменных окружения из конфигурационного слоя.
|
||||
- [ ] Все компонентные секции конфигурации продолжают читаться из `config.yaml`.
|
||||
- [ ] Обновлены тесты конфигурации под YAML-only поведение.
|
||||
- [ ] Smoke test старта приложения проходит с валидным `config.yaml`.
|
||||
|
||||
## Tests
|
||||
- Обновить `tests/config/test_config_sections.py` под проверку YAML-only загрузки.
|
||||
- Добавить/обновить негативные тесты отсутствующих обязательных YAML-полей.
|
||||
- Проверить app startup smoke test с валидным `config.yaml`.
|
||||
|
||||
## Commands
|
||||
- `poetry run pytest tests/config/test_config_sections.py -q`
|
||||
- `poetry run pytest tests/smoke/test_app_import.py -q`
|
||||
@@ -0,0 +1,50 @@
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
||||
COMPOSE_FILE = PROJECT_ROOT / "docker-compose.yml"
|
||||
INFRA_README = PROJECT_ROOT / "infra" / "README.md"
|
||||
|
||||
|
||||
def _load_compose() -> dict:
|
||||
content = yaml.safe_load(COMPOSE_FILE.read_text(encoding="utf-8"))
|
||||
assert isinstance(content, dict)
|
||||
return content
|
||||
|
||||
|
||||
def test_compose_defines_required_services() -> None:
|
||||
compose = _load_compose()
|
||||
services = compose.get("services")
|
||||
assert isinstance(services, dict)
|
||||
assert {"app", "redis", "signoz"}.issubset(services.keys())
|
||||
|
||||
|
||||
def test_app_service_contains_cache_and_observability_wiring() -> None:
|
||||
compose = _load_compose()
|
||||
app_service = compose["services"]["app"]
|
||||
|
||||
build_config = app_service.get("build")
|
||||
assert isinstance(build_config, dict)
|
||||
assert build_config["context"] == "."
|
||||
assert build_config["dockerfile"] == "Dockerfile"
|
||||
|
||||
environment = app_service.get("environment")
|
||||
assert isinstance(environment, dict)
|
||||
assert environment["G2S_REPOSITORY__REDIS_DSN"] == "redis://redis:6379/0"
|
||||
assert environment["G2S_OBSERVABILITY__OTLP_ENDPOINT"] == "http://signoz:4317"
|
||||
assert environment["G2S_CONFIG_FILE"] == "/app/config.yaml"
|
||||
|
||||
depends_on = app_service.get("depends_on")
|
||||
assert isinstance(depends_on, list)
|
||||
assert "redis" in depends_on
|
||||
assert "signoz" in depends_on
|
||||
|
||||
|
||||
def test_smoke_command_sequence_is_documented() -> None:
|
||||
readme = INFRA_README.read_text(encoding="utf-8")
|
||||
|
||||
assert "docker compose config" in readme
|
||||
assert "docker compose up -d redis signoz" in readme
|
||||
assert "docker compose ps" in readme
|
||||
Reference in New Issue
Block a user