Everything you need to install, configure, and use Aegira.
# Download
$ wget https://github.com/talatsajafa/Aegira-free-v1-releases/releases/download/v1.0.0/aegira-free-v1.0.0-x86_64.tar.gz
$ tar -xzf aegira-free-v1.0.0-x86_64.tar.gz
# Install (prompts for target)
$ sudo ./install.sh
Requires Linux x86_64. Docker is optional. The installer will guide you through target setup and optional email alerts.
| Command | Description |
|---|---|
| sudo aegira install | Install the Aegira service |
| sudo aegira status | Check if Aegira is running |
| sudo aegira run | Start monitoring in foreground |
| sudo aegira history | View past incidents |
| sudo aegira show-rules | List active rules (short) |
| sudo aegira rules list | List all active rules (detailed) |
| sudo aegira rules show <id> | View rule details |
| sudo aegira rules export | Export all rules as JSON |
| sudo aegira rules disable <id> | Disable a rule |
| sudo aegira rules enable <id> | Enable a disabled rule |
| sudo aegira configure service <name> | Set target systemd service |
| sudo aegira configure container <name> | Set target Docker container |
| sudo aegira configure multi <c1> <c2> ... | Set multiple target containers |
| sudo aegira configure auto <name> [--container] | Auto-configure service or container |
| sudo aegira configure alerts <on|off> [email] | Enable/disable email alerts |
| sudo aegira docker-status <name> | Inspect a container's state |
| aegira --help | Show usage |
Aegira Free allows up to 3 custom rules.
Place JSON files in /etc/aegira/rules/custom/.
/etc/aegira/rules/custom/
$ sudo nano /etc/aegira/rules/custom/my-rule.json
$ sudo systemctl restart aegira.service
$ sudo aegira rules list
{
"id": "redis_restart",
"name": "Restart Redis on connection error",
"severity": "high",
"error_patterns": [
"redis connection failed",
"redis connection refused"
],
"context_patterns": ["redis"],
"trigger": { "type": "log" },
"remediation": {
"type": "service_restart",
"service": "redis"
},
"verification": {
"type": "service_active",
"service": "redis"
},
"action": "auto_recover",
"priority": 50
}
| Field | Required | Description |
|---|---|---|
| id | Yes | Unique rule ID (lowercase, no spaces) |
| name | Yes | Human-readable name |
| severity | No | low / medium / high / critical |
| error_patterns | Yes | Log substrings that trigger the rule |
| context_patterns | No | Additional context substrings (higher match score) |
| trigger | No | Object — see Trigger section below. Defaults to { "type": "log" } |
| remediation | Yes | service_restart, container_restart, command, container_exec, command_sequence, alert_only |
| verification | Yes | service_active, container_running, container_healthy, http_status, container_http_status, command_success, none |
| action | No | auto_recover / alert_only / dry_run / approval_required |
| priority | No | Higher = matched first (default 0) |
The trigger field is an object with a type key.
Supported types:
| Type | Example |
|---|---|
| log | { "type": "log" } |
| docker_exit | { "type": "docker_exit", "container": "my-app", "exit_codes": [137] } |
| docker_health | { "type": "docker_health", "container": "my-app", "status": "unhealthy" } |
| docker_oom | { "type": "docker_oom", "container": "my-app" } |
| http_health | { "type": "http_health", "url": "http://...", "container": "my-app", "expected_status": 200 } |
| container_probe | { "type": "container_probe", "container": "my-db", "executable": "pg_isready" } |
💡 Trigger Format
trigger is always an object, never a string.
Use { "type": "log" } — not "log".
Restart a systemd service on log error:
{
"id": "nginx_restart",
"name": "Restart Nginx on connection error",
"error_patterns": ["nginx", "connection refused", "failed"],
"trigger": { "type": "log" },
"remediation": { "type": "service_restart", "service": "nginx" },
"verification": { "type": "service_active", "service": "nginx" },
"action": "auto_recover",
"priority": 50
}
Restart a Docker container on exit 137:
{
"id": "app_container_restart",
"name": "Restart app container on exit 137",
"error_patterns": ["exit code 137"],
"trigger": { "type": "docker_exit", "container": "my-app", "exit_codes": [137] },
"remediation": { "type": "container_restart", "container": "my-app" },
"verification": { "type": "container_running", "container": "my-app" },
"action": "auto_recover",
"priority": 50
}
Heal a service inside a container without restarting it:
{
"id": "nginx_reload",
"name": "Reload nginx config inside container",
"error_patterns": ["nginx config error"],
"trigger": { "type": "log" },
"remediation": { "type": "container_exec", "container": "nginx", "args": ["nginx", "-s", "reload"] },
"verification": { "type": "container_http_status", "container": "nginx", "url": "http://127.0.0.1:8080/health", "expected_status": 200 },
"action": "auto_recover",
"priority": 50
}
HTTP health check + container exec (fix service inside a running container):
{
"id": "nginx_http_health",
"name": "Nginx HTTP health check + container exec",
"error_patterns": ["HTTP health check failed"],
"trigger": {
"type": "http_health",
"url": "http://localhost:8080/",
"container": "my-app",
"expected_status": 200,
"interval_secs": 5
},
"remediation": {
"type": "container_exec",
"container": "my-app",
"args": ["nginx"]
},
"verification": {
"type": "container_http_status",
"container": "my-app",
"url": "http://localhost:8080/",
"expected_status": 200
},
"action": "auto_recover",
"priority": 50
}
Alert only — no automatic remediation:
{
"id": "disk_full_alert",
"name": "Alert on disk full",
"error_patterns": ["no space left on device"],
"trigger": { "type": "log" },
"remediation": { "type": "alert_only" },
"verification": { "type": "none" },
"action": "alert_only",
"priority": 50
}
⚠️ Important
Rules execute as root. Destructive commands are blocked best-effort, not foolproof. Write your rules carefully.
After creating a rule, follow this sequence to ensure Aegira detects and recovers correctly. Skipping steps (especially the waits) is the most common reason rules don't fire.
💡 Quick Summary
Rule → Restart → Wait → Configure → Restart → Clear Log → Crash → Wait → Check
$ sudo nano /etc/aegira/rules/custom/my-rule.json
Paste your JSON and save.
$ sudo systemctl restart aegira
Aegira reloads rules dynamically when the file changes, but a restart guarantees the new rule is loaded.
$ sudo aegira rules list
Look for your rule in the Custom section. If it's not there, check the journal for rejection reasons.
$ sleep 15
Aegira's monitoring threads need time to start. This ensures journald, Docker events, and HTTP health monitors are running before you test.
TARGET_SERVICE or TARGET_CONTAINER)
$ sudo aegira configure service nginx
# or
$ sudo aegira configure container my-app
$ sudo systemctl restart aegira
$ sleep 15
Target configuration is loaded at startup. Without a restart, the rule won't know which service or container to target.
$ sudo truncate -s 0 /var/log/aegira/incident.log
This ensures only the new incident is visible in the log. Old entries make it hard to verify whether the new rule fired.
# systemd service
$ sudo systemctl stop nginx
# Docker container
$ docker kill my-app
$ sleep 15
Aegira needs time to detect the crash, match the rule, run the recovery, and verify the result.
$ sudo cat /var/log/aegira/incident.log
You should see [WATCHER],
[RECOVER], and
[RESOLVED] entries.
# systemd service
$ sudo systemctl is-active nginx
# Docker container
$ docker inspect -f '{{.State.Status}}' my-app
| Action | Wait Time | Why |
|---|---|---|
| After rule reload | 10–15s | Monitoring threads need to start |
| After target configure | 10–15s | Config loaded at startup |
| After crash | 10–15s | Detect + match + recover + verify |
| HTTP health poll | 5s default | Configurable via interval_secs |
| Cooldown (after recovery) | 30s–600s | Prevents infinite restart loops |
⚠️ Common Mistakes
trigger is an object, not a string: { "type": "log" }.Aegira can send Gmail alerts via Composio when incidents occur. You need a free Composio account.
During install, choose to enable alerts and provide:
app.composio.dev)Or configure later:
$ sudo aegira configure alerts on you@example.com
$ sudo systemctl status aegira.service
$ sudo journalctl -u aegira -n 100
Check the Aegira journal for rejection reasons:
$ sudo journalctl -u aegira -n 50 | grep -i "rules\|skip\|invalid"
Common causes:
error_patternstrigger format (must be object, not string)
Verify your Composio API key and user ID in
/etc/aegira/composio.env.
Then check the incident log:
sudo grep -i alert /var/log/aegira/incident.log
Docker rules use TARGET_CONTAINER.
You must configure a target:
sudo aegira configure container <name>
Aegira monitors journald (systemd logs). If a service isn't detected,
verify it logs to journald:
journalctl -u <service> -n 20.
If no output, the service may not be a systemd unit.