Files
homelab/scripts/security/CONTAINER_NAME_FIXES.md
Jordan Ramos e481c95da4 docs(security): comprehensive security audit and remediation documentation
- Add SECURITY.md policy with credential management, Docker security, SSL/TLS guidance
- Add security audit report (2025-12-20) with 31 findings across 4 severity levels
- Add pre-deployment security checklist template
- Update CLAUDE_STATUS.md with security audit initiative
- Expand services/README.md with comprehensive security sections
- Add script validation report and container name fix guide

Audit identified 6 CRITICAL, 3 HIGH, 2 MEDIUM findings
4-phase remediation roadmap created (estimated 6-13 min downtime)
All security scripts validated and ready for execution

Related: Security Audit Q4 2025, CRITICAL-001 through CRITICAL-006

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 13:52:34 -07:00

15 KiB
Raw Permalink Blame 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:

services:
  tinyauth:
    container_name: tinyauth
    # ...

Multi-container services:

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

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

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

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

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

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

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:

services:
  grafana:
    container_name: grafana  # Add this line
    image: grafana/grafana:latest
    # ...

Prometheus - /home/jramos/homelab/monitoring/prometheus/docker-compose.yml:

services:
  prometheus:
    container_name: prometheus  # Add this line
    image: prom/prometheus:latest
    # ...

PVE Exporter - /home/jramos/homelab/monitoring/pve-exporter/docker-compose.yml:

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:

services:
  loki:
    container_name: loki  # Add this line
    image: grafana/loki:latest
    # ...

Promtail - /home/jramos/homelab/monitoring/promtail/docker-compose.yml:

services:
  promtail:
    container_name: promtail  # Add this line
    image: grafana/promtail:latest
    # ...

n8n

File: /home/jramos/homelab/services/n8n/docker-compose.yml

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

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:

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

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

#!/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:

# 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:

# 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:

rate(container_cpu_usage_seconds_total{name="paperless-ngx-webserver-1"}[5m])

After:

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:

{container_name="paperless-ngx-webserver-1"}

After:

{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:

# 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:

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:

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)