Files
homelab/scripts/security/CONTAINER_NAME_FIXES.md

622 lines
15 KiB
Markdown
Raw Normal View History

# Container Name Standardization
**Issue**: MED-010 from Security Audit 2025-12-20
**Severity**: Medium (Low priority, continuous improvement)
**Impact**: Inconsistent container naming makes monitoring and automation difficult
---
## Current State
Docker Compose automatically generates container names using the format:
```
<directory>-<service>-<instance>
```
This results in inconsistent and unclear names:
| Current Name | Service | Issue |
|--------------|---------|-------|
| `paperless-ngx-webserver-1` | Paperless webserver | Redundant "ngx" and unclear purpose |
| `paperless-ngx-db-1` | PostgreSQL | Unclear it's Paperless database |
| `speedtest-tracker-app-1` | Speedtest main service | Generic "app" name |
| `tinyauth-tinyauth-1` | TinyAuth | Duplicate service name |
| `monitoring-grafana-1` | Grafana | Directory name included |
| `monitoring-prometheus-1` | Prometheus | Directory name included |
---
## Desired State
Use explicit `container_name` directive for clarity:
| Desired Name | Service | Benefit |
|--------------|---------|---------|
| `paperless-webserver` | Paperless webserver | Clear, no instance suffix |
| `paperless-db` | Paperless PostgreSQL | Obviously Paperless database |
| `paperless-redis` | Paperless Redis | Clear purpose |
| `speedtest-tracker` | Speedtest service | Concise, descriptive |
| `tinyauth` | TinyAuth | Simple, no duplication |
| `grafana` | Grafana | Short, clear |
| `prometheus` | Prometheus | Short, clear |
---
## Naming Convention Standard
### Format
```
<service>[-<component>]
```
### Examples
**Single-container services**:
```yaml
services:
tinyauth:
container_name: tinyauth
# ...
```
**Multi-container services**:
```yaml
services:
webserver:
container_name: paperless-webserver
# ...
db:
container_name: paperless-db
# ...
redis:
container_name: paperless-redis
# ...
```
### Rules
1. **Use lowercase** - All container names lowercase
2. **Use hyphens** - Separate words with hyphens (not underscores)
3. **Be descriptive** - Name should indicate purpose
4. **Be concise** - Avoid redundancy (no "paperless-ngx-paperless-1")
5. **No instance numbers** - Use `container_name` to remove `-1`, `-2` suffixes
6. **Service prefix for multi-container** - e.g., `paperless-db`, `paperless-redis`
7. **No directory names** - Avoid `monitoring-grafana`, just use `grafana`
---
## Implementation
### Step 1: Update docker-compose.yaml Files
For each service, add `container_name` directive.
#### ByteStash
**File**: `/home/jramos/homelab/services/bytestash/docker-compose.yaml`
```yaml
services:
bytestash:
container_name: bytestash # Add this line
image: ghcr.io/jordan-dalby/bytestash:latest
# ... rest of configuration
```
#### FileBrowser
**File**: `/home/jramos/homelab/services/filebrowser/docker-compose.yaml`
```yaml
services:
filebrowser:
container_name: filebrowser # Add this line
image: filebrowser/filebrowser:latest
# ... rest of configuration
```
#### Paperless-ngx
**File**: `/home/jramos/homelab/services/paperless-ngx/docker-compose.yaml`
```yaml
services:
broker:
container_name: paperless-redis # Add this line
image: redis:8
# ...
db:
container_name: paperless-db # Add this line
image: postgres:17
# ...
webserver:
container_name: paperless-webserver # Add this line
image: ghcr.io/paperless-ngx/paperless-ngx:latest
# ...
gotenberg:
container_name: paperless-gotenberg # Add this line
image: gotenberg:8.20
# ...
tika:
container_name: paperless-tika # Add this line
image: apache/tika:latest
# ...
```
#### Portainer
**File**: `/home/jramos/homelab/services/portainer/docker-compose.yaml`
```yaml
services:
portainer:
container_name: portainer # Add this line
image: portainer/portainer-ce:latest
# ... rest of configuration
```
#### Speedtest Tracker
**File**: `/home/jramos/homelab/services/speedtest-tracker/docker-compose.yaml`
```yaml
services:
app:
container_name: speedtest-tracker # Add this line
image: lscr.io/linuxserver/speedtest-tracker:latest
# ... rest of configuration
```
#### TinyAuth
**File**: `/home/jramos/homelab/services/tinyauth/docker-compose.yml`
```yaml
services:
tinyauth:
container_name: tinyauth # Add this line
image: ghcr.io/steveiliop56/tinyauth:v4
# ... rest of configuration
```
#### Monitoring Stack
**Grafana** - `/home/jramos/homelab/monitoring/grafana/docker-compose.yml`:
```yaml
services:
grafana:
container_name: grafana # Add this line
image: grafana/grafana:latest
# ...
```
**Prometheus** - `/home/jramos/homelab/monitoring/prometheus/docker-compose.yml`:
```yaml
services:
prometheus:
container_name: prometheus # Add this line
image: prom/prometheus:latest
# ...
```
**PVE Exporter** - `/home/jramos/homelab/monitoring/pve-exporter/docker-compose.yml`:
```yaml
services:
pve-exporter:
container_name: pve-exporter # Add this line
image: prompve/prometheus-pve-exporter:latest
# ...
```
**Loki** - `/home/jramos/homelab/monitoring/loki/docker-compose.yml`:
```yaml
services:
loki:
container_name: loki # Add this line
image: grafana/loki:latest
# ...
```
**Promtail** - `/home/jramos/homelab/monitoring/promtail/docker-compose.yml`:
```yaml
services:
promtail:
container_name: promtail # Add this line
image: grafana/promtail:latest
# ...
```
#### n8n
**File**: `/home/jramos/homelab/services/n8n/docker-compose.yml`
```yaml
services:
n8n:
container_name: n8n # Add this line
image: n8nio/n8n:latest
# ...
postgres:
container_name: n8n-db # Add this line
image: postgres:15
# ...
```
#### Docker Socket Proxy
**File**: `/home/jramos/homelab/services/docker-socket-proxy/docker-compose.yml`
```yaml
services:
socket-proxy:
container_name: socket-proxy # Add this line
image: tecnativa/docker-socket-proxy:latest
# ...
```
---
### Step 2: Apply Changes
For each service, recreate containers with new names:
```bash
cd /home/jramos/homelab/services/<service-name>
# Stop existing containers
docker compose down
# Start with new container names
docker compose up -d
# Verify new container names
docker compose ps
```
**Important**: This will recreate containers but preserve data in volumes.
---
### Step 3: Update Monitoring
After renaming containers, update Prometheus scrape configs if using container discovery:
**File**: `/home/jramos/homelab/monitoring/prometheus/prometheus.yml`
```yaml
scrape_configs:
- job_name: 'grafana'
static_configs:
- targets: ['grafana:3000'] # Use new container name
- job_name: 'prometheus'
static_configs:
- targets: ['prometheus:9090'] # Use new container name
```
---
### Step 4: Update Documentation
Update references to container names in:
- `/home/jramos/homelab/services/README.md`
- `/home/jramos/homelab/monitoring/README.md`
- Any troubleshooting guides
- Any automation scripts
---
## Automated Fix Script
To automate the container name standardization:
**File**: `/home/jramos/homelab/scripts/security/fix-container-names.sh`
```bash
#!/bin/bash
# Standardize container names across all Docker Compose services
# Addresses MED-010: Container Name Inconsistency
set -euo pipefail
SERVICES_DIR="/home/jramos/homelab/services"
MONITORING_DIR="/home/jramos/homelab/monitoring"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
DRY_RUN=false
if [[ "${1:-}" == "--dry-run" ]]; then
DRY_RUN=true
echo "DRY RUN MODE - No changes will be made"
fi
# Container name mappings
declare -A CONTAINER_NAMES=(
# Services
["bytestash"]="bytestash"
["filebrowser"]="filebrowser"
["paperless-ngx/broker"]="paperless-redis"
["paperless-ngx/db"]="paperless-db"
["paperless-ngx/webserver"]="paperless-webserver"
["paperless-ngx/gotenberg"]="paperless-gotenberg"
["paperless-ngx/tika"]="paperless-tika"
["portainer"]="portainer"
["speedtest-tracker/app"]="speedtest-tracker"
["tinyauth"]="tinyauth"
["n8n/n8n"]="n8n"
["n8n/postgres"]="n8n-db"
["docker-socket-proxy/socket-proxy"]="socket-proxy"
# Monitoring
["monitoring/grafana"]="grafana"
["monitoring/prometheus"]="prometheus"
["monitoring/pve-exporter"]="pve-exporter"
["monitoring/loki"]="loki"
["monitoring/promtail"]="promtail"
)
add_container_name() {
local COMPOSE_FILE=$1
local SERVICE=$2
local CONTAINER_NAME=$3
echo "Processing $COMPOSE_FILE (service: $SERVICE)"
if [[ ! -f "$COMPOSE_FILE" ]]; then
echo " ⚠️ File not found: $COMPOSE_FILE"
return 1
fi
# Backup original file
if [[ "$DRY_RUN" == false ]]; then
cp "$COMPOSE_FILE" "$COMPOSE_FILE.backup-$TIMESTAMP"
echo " ✓ Backup created"
fi
# Check if container_name already exists for this service
if grep -A 5 "^[[:space:]]*$SERVICE:" "$COMPOSE_FILE" | grep -q "container_name:"; then
echo " container_name already set"
return 0
fi
# Add container_name directive
if [[ "$DRY_RUN" == false ]]; then
# Find the service block and add container_name after service name
awk -v service="$SERVICE" -v name="$CONTAINER_NAME" '
/^[[:space:]]*'"$SERVICE"':/ {
print
print " container_name: " name
next
}
{print}
' "$COMPOSE_FILE" > "$COMPOSE_FILE.tmp"
mv "$COMPOSE_FILE.tmp" "$COMPOSE_FILE"
echo " ✓ Added container_name: $CONTAINER_NAME"
else
echo " [DRY RUN] Would add container_name: $CONTAINER_NAME"
fi
# Validate compose file syntax
if [[ "$DRY_RUN" == false ]]; then
if docker compose -f "$COMPOSE_FILE" config > /dev/null 2>&1; then
echo " ✓ Compose file syntax valid"
else
echo " ✗ ERROR: Compose file syntax invalid"
echo " Restoring backup..."
mv "$COMPOSE_FILE.backup-$TIMESTAMP" "$COMPOSE_FILE"
return 1
fi
fi
}
main() {
echo "=== Container Name Standardization ==="
echo ""
# Process all container name mappings
for KEY in "${!CONTAINER_NAMES[@]}"; do
# Parse key: "service" or "service/container"
if [[ "$KEY" == *"/"* ]]; then
# Multi-container service
DIR=$(echo "$KEY" | cut -d'/' -f1)
SERVICE=$(echo "$KEY" | cut -d'/' -f2)
if [[ "$DIR" == "monitoring" ]]; then
COMPOSE_FILE="$MONITORING_DIR/$SERVICE/docker-compose.yml"
else
COMPOSE_FILE="$SERVICES_DIR/$DIR/docker-compose.yaml"
fi
else
# Single-container service
DIR="$KEY"
SERVICE="$KEY"
COMPOSE_FILE="$SERVICES_DIR/$DIR/docker-compose.yaml"
fi
CONTAINER_NAME="${CONTAINER_NAMES[$KEY]}"
add_container_name "$COMPOSE_FILE" "$SERVICE" "$CONTAINER_NAME"
echo ""
done
echo "=== Summary ==="
echo "Services processed: ${#CONTAINER_NAMES[@]}"
if [[ "$DRY_RUN" == true ]]; then
echo "Mode: DRY RUN (no changes made)"
echo "Run without --dry-run to apply changes"
else
echo "Mode: LIVE (changes applied)"
echo ""
echo "⚠️ IMPORTANT: Restart services to use new container names"
echo "Example:"
echo " cd $SERVICES_DIR/paperless-ngx"
echo " docker compose down"
echo " docker compose up -d"
fi
}
main "$@"
```
**Usage**:
```bash
# Test in dry-run mode
./fix-container-names.sh --dry-run
# Apply changes
./fix-container-names.sh
# Restart all services (optional script)
cd /home/jramos/homelab
find services monitoring -name "docker-compose.y*ml" -execdir bash -c 'docker compose down && docker compose up -d' \;
```
---
## Verification
After applying changes, verify new container names:
```bash
# List all containers with new names
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
# Expected output:
# NAMES IMAGE STATUS
# bytestash ghcr.io/jordan-dalby/bytestash:latest Up 5 minutes
# filebrowser filebrowser/filebrowser:latest Up 5 minutes
# paperless-webserver ghcr.io/paperless-ngx/paperless-ngx Up 5 minutes
# paperless-db postgres:17 Up 5 minutes
# paperless-redis redis:8 Up 5 minutes
# grafana grafana/grafana:latest Up 5 minutes
# prometheus prom/prometheus:latest Up 5 minutes
# tinyauth ghcr.io/steveiliop56/tinyauth:v4 Up 5 minutes
```
### Monitoring Dashboard Update
If using Grafana dashboards that reference container names, update queries:
**Before**:
```promql
rate(container_cpu_usage_seconds_total{name="paperless-ngx-webserver-1"}[5m])
```
**After**:
```promql
rate(container_cpu_usage_seconds_total{name="paperless-webserver"}[5m])
```
### Log Aggregation Update
If using Loki/Promtail with container name labels, update label matchers:
**Before**:
```logql
{container_name="paperless-ngx-webserver-1"}
```
**After**:
```logql
{container_name="paperless-webserver"}
```
---
## Benefits
After standardization:
1. **Clarity**: Container names clearly indicate purpose
2. **Consistency**: All containers follow same naming pattern
3. **Automation**: Easier to write scripts targeting specific containers
4. **Monitoring**: Cleaner metrics and log labels
5. **Documentation**: Less confusion in guides and troubleshooting docs
6. **Maintainability**: Easier for new team members to understand infrastructure
---
## Rollback
If issues occur after renaming:
```bash
# Restore original docker-compose.yaml
cd /home/jramos/homelab/services/<service>
mv docker-compose.yaml.backup-<timestamp> docker-compose.yaml
# Recreate containers with original names
docker compose down
docker compose up -d
```
---
## Future Considerations
### Docker Compose Project Names
Consider also standardizing Docker Compose project names using:
```yaml
name: paperless # Add to top of docker-compose.yaml
services:
# ...
```
This controls the prefix used in network and volume names.
### Container Labels
Add labels for better organization:
```yaml
services:
paperless-webserver:
container_name: paperless-webserver
labels:
- "com.homelab.service=paperless"
- "com.homelab.component=webserver"
- "com.homelab.tier=application"
- "com.homelab.environment=production"
```
Labels enable advanced filtering and automation.
---
## Completion Checklist
- [ ] Review current container names
- [ ] Update all docker-compose.yaml files with `container_name`
- [ ] Validate compose file syntax
- [ ] Stop and restart all services
- [ ] Verify new container names
- [ ] Update Prometheus configs (if using container discovery)
- [ ] Update Grafana dashboards
- [ ] Update Loki/Promtail configs
- [ ] Update documentation
- [ ] Update automation scripts
- [ ] Test monitoring and logging
- [ ] Commit changes to git
---
**Issue**: MED-010
**Priority**: Low (Continuous Improvement)
**Estimated Effort**: 2-3 hours
**Status**: Documentation Complete - Ready for Implementation
---
**Document Version**: 1.0
**Last Updated**: 2025-12-20
**Author**: Claude Code (Scribe Agent)