# infra-controller Python-based controller that discovers active apps and ensures required infrastructure services are present. Services are expected to be managed as Docker Compose projects on the services server (e.g. `/opt/grafana`, `/opt/prometheus`). ## Requirements - Python 3.11+ - Docker and Docker Compose installed on the services server ## Quick Start 1. Create a `.infra.toml` file in your app directory: ```toml [requires] services = ["postgres", "redis"] ``` That's it. The controller will: - Find your `.infra.toml` file - Start `postgres` and `redis` - Keep them running while your app is present - Stop them **15 minutes** after your app is removed (configurable) ## Service Directory Structure Services should be in `/opt//docker-compose.yml`: ```text /opt/ postgres/ docker-compose.yml redis/ docker-compose.yml ``` ## Recommended Architecture For a lightweight, user-friendly system: ```text User Workflow: 1. Put .infra.toml in app directory (e.g., /home/user/myapp/.infra.toml) 2. Controller scans and finds it automatically 3. Services start/stop automatically No manual registration needed! ``` ## Config Preferred config file: - `/etc/infra-controller/config.toml` Copy the example config: - `config/controller.toml.example` -> `/etc/infra-controller/config.toml` Optional YAML config: - `config/controller.yml.example` -> `/etc/infra-controller/config.yml` ## Run - `infra-controller --once` ## systemd (event-driven) If you want path-based triggering (no polling), you can run `infra-controller --once` whenever a `.infra.*` file changes under your configured scan paths. Note: `systemd.path` does not support recursive watches, so for scan-based discovery the practical approach is an inotify watcher. Example watcher (requires `inotify-tools`): `/etc/systemd/system/infra-controller-watch.service` ```ini [Unit] Description=Watch for .infra.* changes and run infra-controller [Service] Type=simple ExecStart=/bin/sh -lc 'inotifywait -m -r -e create,modify,delete,move --format "%w%f" /home /opt/apps | while read -r p; do case "$p" in *"/.infra."*) infra-controller --once ;; esac; done' Restart=always RestartSec=2 ``` Enable it: - `sudo systemctl enable --now infra-controller-watch.service` - `journalctl -u infra-controller-watch.service -f` Services that are no longer required are stopped after `grace_period_minutes` (see config) using `docker compose down`.