Add resource limits to all Docker containers
- fail2ban: 0.5 CPU / 128M memory limit, 0.1 CPU / 64M reserved - backend: 2.0 CPU / 512M memory limit, 1.0 CPU / 256M reserved - frontend: 0.5 CPU / 128M memory limit, 0.25 CPU / 64M reserved Prevents 'noisy neighbor' scenarios where one container exhausts host resources (CPU, memory, disk). Limits are hard caps; reservations guarantee minimum allocation to prevent OOM kills and ensure responsive service even under load. Fixes resource contention issue in production and staging environments. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -26,6 +26,13 @@ services:
|
|||||||
#- /path/to/unificontroller/log:/remotelogs/unificontroller:ro #optional
|
#- /path/to/unificontroller/log:/remotelogs/unificontroller:ro #optional
|
||||||
#- /path/to/vaultwarden/log:/remotelogs/vaultwarden:ro #optional
|
#- /path/to/vaultwarden/log:/remotelogs/vaultwarden:ro #optional
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
deploy:
|
||||||
|
limits:
|
||||||
|
cpus: '0.5'
|
||||||
|
memory: 128M
|
||||||
|
reservations:
|
||||||
|
cpus: '0.1'
|
||||||
|
memory: 64M
|
||||||
|
|
||||||
backend:
|
backend:
|
||||||
image: git.lpl-mind.de/lukas.pupkalipinski/bangui/backend:latest
|
image: git.lpl-mind.de/lukas.pupkalipinski/bangui/backend:latest
|
||||||
@@ -53,6 +60,13 @@ services:
|
|||||||
- "8000"
|
- "8000"
|
||||||
networks:
|
networks:
|
||||||
- bangui-net
|
- bangui-net
|
||||||
|
deploy:
|
||||||
|
limits:
|
||||||
|
cpus: '2'
|
||||||
|
memory: 512M
|
||||||
|
reservations:
|
||||||
|
cpus: '1'
|
||||||
|
memory: 256M
|
||||||
|
|
||||||
# ── Frontend (nginx serving built SPA + API proxy) ──────────
|
# ── Frontend (nginx serving built SPA + API proxy) ──────────
|
||||||
frontend:
|
frontend:
|
||||||
@@ -69,6 +83,13 @@ services:
|
|||||||
condition: service_started
|
condition: service_started
|
||||||
networks:
|
networks:
|
||||||
- bangui-net
|
- bangui-net
|
||||||
|
deploy:
|
||||||
|
limits:
|
||||||
|
cpus: '0.5'
|
||||||
|
memory: 128M
|
||||||
|
reservations:
|
||||||
|
cpus: '0.25'
|
||||||
|
memory: 64M
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
bangui-net:
|
bangui-net:
|
||||||
|
|||||||
131
Docs/Deployment.md
Normal file
131
Docs/Deployment.md
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
# Deployment Guide
|
||||||
|
|
||||||
|
## Docker Compose Setup
|
||||||
|
|
||||||
|
BanGUI is designed to run in Docker containers with proper resource isolation and limits to prevent "noisy neighbor" scenarios where one container exhausts host resources.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resource Allocation
|
||||||
|
|
||||||
|
All containers have hard limits (max usage) and soft reservations (guaranteed allocation). This ensures:
|
||||||
|
- **Isolation**: A misbehaving container cannot crash others or the host
|
||||||
|
- **Predictability**: Reservations guarantee minimum resources even under load
|
||||||
|
- **Efficiency**: Unused reserved capacity can be borrowed by other containers
|
||||||
|
|
||||||
|
### Container Resource Limits
|
||||||
|
|
||||||
|
| Container | Limit CPU | Limit Memory | Reserved CPU | Reserved Memory | Purpose |
|
||||||
|
|-----------|-----------|--------------|--------------|-----------------|---------|
|
||||||
|
| **fail2ban** | 0.5 | 128M | 0.1 | 64M | Monitors logs, bans IPs—typically idle |
|
||||||
|
| **backend** | 2.0 | 512M | 1.0 | 256M | Core app: database, fail2ban API, config management |
|
||||||
|
| **frontend** | 0.5 | 128M | 0.25 | 64M | Nginx: serves SPA + API proxy |
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
- **fail2ban**: Lightweight log monitoring. Occasionally CPU spikes during ban processing but memory usage is minimal.
|
||||||
|
- **backend**: Heavy lifting—Python runtime, SQLite database, background jobs. May need extra memory for large blocklists. Reservation of 1.0 CPU ensures responsive API even when frontend is busy.
|
||||||
|
- **frontend**: Nginx is efficient. Limit of 0.5 CPU and 128M memory is more than sufficient for reverse proxy duties.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Memory Considerations
|
||||||
|
|
||||||
|
### Backend Memory Requirements
|
||||||
|
|
||||||
|
The backend typically runs in 256–512M under normal load. Memory usage depends on:
|
||||||
|
- **Blocklist size**: Large blocklists (>1M entries) require more heap space
|
||||||
|
- **Cache warmth**: First query after startup may require more memory as caches fill
|
||||||
|
- **Concurrent connections**: Each active user session uses a small amount of memory
|
||||||
|
|
||||||
|
**Tuning:** If you see OOM kills in logs, increase backend limits and reservations (e.g., 1024M limit). Test under realistic load before finalizing.
|
||||||
|
|
||||||
|
### Frontend Memory Usage
|
||||||
|
|
||||||
|
Nginx is typically <50M. If you see memory pressure on frontend, check for:
|
||||||
|
- Misconfigured cache headers on static assets
|
||||||
|
- Large log volumes (nginx access logs)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Docker Swarm & Kubernetes
|
||||||
|
|
||||||
|
For production deployments using orchestration platforms:
|
||||||
|
|
||||||
|
### Docker Swarm
|
||||||
|
|
||||||
|
The `deploy` sections in `docker-compose.yml` are compatible with `docker stack deploy`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker stack deploy -c Docker/docker-compose.yml bangui
|
||||||
|
```
|
||||||
|
|
||||||
|
Swarm respects the same `limits` and `reservations` fields.
|
||||||
|
|
||||||
|
### Kubernetes
|
||||||
|
|
||||||
|
For Kubernetes, translate resource constraints to equivalent `resources` fields in your deployment manifests:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
containers:
|
||||||
|
- name: backend
|
||||||
|
image: git.lpl-mind.de/lukas.pupkalipinski/bangui/backend:latest
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: "2"
|
||||||
|
memory: "512Mi"
|
||||||
|
requests:
|
||||||
|
cpu: "1"
|
||||||
|
memory: "256Mi"
|
||||||
|
```
|
||||||
|
|
||||||
|
Kubernetes equivalent mappings:
|
||||||
|
- Docker `deploy.limits` → Kubernetes `resources.limits`
|
||||||
|
- Docker `deploy.reservations` → Kubernetes `resources.requests`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Monitoring Resource Usage
|
||||||
|
|
||||||
|
### Docker Compose (Development)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker stats
|
||||||
|
```
|
||||||
|
|
||||||
|
Shows real-time CPU and memory usage for all running containers.
|
||||||
|
|
||||||
|
### Production (Docker Swarm / Kubernetes)
|
||||||
|
|
||||||
|
Use native monitoring:
|
||||||
|
- **Docker Swarm**: Prometheus + Grafana
|
||||||
|
- **Kubernetes**: Metrics Server + dashboard or Prometheus
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
Resource limits are configured in `Docker/docker-compose.yml` and cannot be overridden via environment variables. To adjust limits:
|
||||||
|
|
||||||
|
1. Edit `Docker/docker-compose.yml`
|
||||||
|
2. Modify the `deploy.limits` and `deploy.reservations` sections
|
||||||
|
3. Restart containers: `make down && make up`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
| Issue | Symptom | Solution |
|
||||||
|
|-------|---------|----------|
|
||||||
|
| Backend OOM kills | "Exit code 137" in logs | Increase backend `memory` limit |
|
||||||
|
| Throttling | CPU at 100%, requests slow | Increase CPU limit or optimize code |
|
||||||
|
| Service startup timeout | Containers not becoming "healthy" | Increase reservation to guarantee capacity at startup |
|
||||||
|
| Host unresponsive | System-wide lag | Reduce container limits to prevent host starvation |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
- **Development**: Run `make up` to start with default limits
|
||||||
|
- **Staging**: Test with realistic data volumes and monitor resource usage
|
||||||
|
- **Production**: Adjust limits based on observed usage patterns, then commit changes
|
||||||
Reference in New Issue
Block a user