Skip to content

SOP-009: Container Setup for Safety

Document Control

FieldValue
Document IDSOP-009
Version1.0
StatusActive
OwnerClaude AI Operations
Last Updated2024-12-01
Review Date2025-03-01

Overview

This SOP defines procedures for setting up secure container environments for Claude AI operations. It covers Docker configuration, security isolation, resource limits, and safe execution environments to minimize risks and ensure controlled operation.

Container Architecture

┌─────────────────────────────────────────────────────────────┐
│                   Container Security Stack                  │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐        │
│  │    Base     │  │  Security   │  │  Resource   │        │
│  │ Container   │  │ Isolation   │  │   Limits    │        │
│  │             │  │             │  │             │        │
│  │ • Minimal   │  │ • User      │  │ • CPU       │        │
│  │ • Hardened  │  │ • Network   │  │ • Memory    │        │
│  │ • Patched   │  │ • Filesystem│  │ • Disk I/O  │        │
│  └─────────────┘  └─────────────┘  └─────────────┘        │
├─────────────────────────────────────────────────────────────┤
│                   Orchestration Layer                       │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐        │
│  │   Docker    │  │ Kubernetes  │  │ Monitoring  │        │
│  │  Engine     │  │  Optional   │  │ & Logging   │        │
│  └─────────────┘  └─────────────┘  └─────────────┘        │
└─────────────────────────────────────────────────────────────┘

Prerequisites

  • Docker Engine installed and running
  • Administrative privileges for container management
  • Understanding of container security principles
  • Basic knowledge of Dockerfile and docker-compose

Procedure

Step 1: Docker Environment Setup

1.1 Docker Installation and Configuration

bash
# Install Docker (Ubuntu/Debian)
if ! command -v docker >/dev/null 2>&1; then
    echo "📦 Installing Docker..."
    
    # Update package index
    sudo apt-get update
    
    # Install prerequisites
    sudo apt-get install -y ca-certificates curl gnupg lsb-release
    
    # Add Docker GPG key
    sudo mkdir -m 0755 -p /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    
    # Add Docker repository
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    
    # Install Docker
    sudo apt-get update
    sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    
    echo "✅ Docker installed successfully"
fi

# Configure Docker security
sudo tee /etc/docker/daemon.json << 'EOF'
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "default-runtime": "runc",
  "runtimes": {
    "runc": {
      "path": "runc"
    }
  },
  "userland-proxy": false,
  "no-new-privileges": true,
  "seccomp-profile": "/etc/docker/seccomp/default.json",
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
EOF

# Restart Docker with new configuration
sudo systemctl restart docker

# Add user to docker group (logout/login required)
sudo usermod -aG docker $USER

1.2 Security Hardening

bash
# Create secure Docker configuration directory
sudo mkdir -p /etc/docker/seccomp
sudo mkdir -p /etc/docker/apparmor
sudo mkdir -p /var/log/docker

# Download default seccomp profile
sudo curl -L https://raw.githubusercontent.com/moby/moby/master/profiles/seccomp/default.json -o /etc/docker/seccomp/default.json

# Create custom seccomp profile for Claude
sudo tee /etc/docker/seccomp/claude-profile.json << 'EOF'
{
  "defaultAction": "SCMP_ACT_ERRNO",
  "archMap": [
    {
      "architecture": "SCMP_ARCH_X86_64",
      "subArchitectures": [
        "SCMP_ARCH_X86",
        "SCMP_ARCH_X32"
      ]
    }
  ],
  "syscalls": [
    {
      "names": [
        "accept",
        "access",
        "alarm",
        "bind",
        "brk",
        "chdir",
        "chmod",
        "chown",
        "clone",
        "close",
        "connect",
        "dup",
        "dup2",
        "execve",
        "exit",
        "exit_group",
        "fchmod",
        "fchown",
        "fcntl",
        "fork",
        "fstat",
        "futex",
        "getdents",
        "getgid",
        "getpid",
        "getppid",
        "getrandom",
        "getsid",
        "getsockname",
        "getsockopt",
        "getuid",
        "listen",
        "lseek",
        "mmap",
        "mprotect",
        "munmap",
        "nanosleep",
        "open",
        "openat",
        "pipe",
        "poll",
        "read",
        "recv",
        "recvfrom",
        "select",
        "send",
        "sendto",
        "set_robust_list",
        "setsid",
        "setsockopt",
        "socket",
        "stat",
        "write"
      ],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}
EOF

# Set proper permissions
sudo chmod 644 /etc/docker/seccomp/*.json

Step 2: Claude Container Images

2.1 Base Security Image

bash
# Create Claude container directory
mkdir -p ~/claude-containers/{base,development,production}

# Create base Dockerfile
cat > ~/claude-containers/base/Dockerfile << 'EOF'
# Claude AI Base Container
FROM ubuntu:22.04

# Metadata
LABEL maintainer="Claude AI Operations"
LABEL version="1.0"
LABEL description="Secure base container for Claude AI operations"

# Create non-root user
RUN groupadd -r claude && \
    useradd -r -g claude -d /home/claude -s /bin/bash claude && \
    mkdir -p /home/claude && \
    chown claude:claude /home/claude

# Install essential packages only
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        ca-certificates \
        curl \
        python3 \
        python3-pip \
        python3-venv \
        git \
        nano \
        jq \
        wget && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# Install Claude CLI (if available)
# RUN pip3 install claude-cli

# Create secure working directories
RUN mkdir -p /app/workspace /app/config /app/logs && \
    chown -R claude:claude /app

# Set security limits
RUN echo "claude soft nproc 100" >> /etc/security/limits.conf && \
    echo "claude hard nproc 200" >> /etc/security/limits.conf && \
    echo "claude soft nofile 1024" >> /etc/security/limits.conf && \
    echo "claude hard nofile 2048" >> /etc/security/limits.conf

# Switch to non-root user
USER claude
WORKDIR /home/claude

# Set environment variables
ENV PYTHONPATH=/app
ENV CLAUDE_HOME=/home/claude
ENV CLAUDE_WORKSPACE=/app/workspace
ENV CLAUDE_CONFIG=/app/config
ENV CLAUDE_LOGS=/app/logs

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
    CMD curl -f http://localhost:8000/health || exit 1

# Default command
CMD ["/bin/bash"]
EOF

# Build base image
cd ~/claude-containers/base
docker build -t claude-base:latest .

2.2 Development Container

bash
cat > ~/claude-containers/development/Dockerfile << 'EOF'
# Claude AI Development Container
FROM claude-base:latest

# Switch to root for package installation
USER root

# Install development tools
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        nodejs \
        npm \
        postgresql-client \
        redis-tools \
        sqlite3 \
        vim \
        tmux \
        htop \
        strace \
        tcpdump && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# Install Python development packages
RUN pip3 install --no-cache-dir \
    jupyter \
    ipython \
    pytest \
    black \
    flake8 \
    mypy \
    requests \
    numpy \
    pandas

# Install Node.js packages globally
RUN npm install -g \
    typescript \
    prettier \
    eslint \
    @anthropic/claude

# Create development directories
RUN mkdir -p /app/projects /app/tests && \
    chown -R claude:claude /app

# Switch back to claude user
USER claude

# Set development environment variables
ENV NODE_ENV=development
ENV PYTHON_ENV=development
ENV CLAUDE_ENV=development
ENV CLAUDE_DEBUG=true

# Expose development ports
EXPOSE 3000 8000 8080 8888

# Default command for development
CMD ["/bin/bash", "-l"]
EOF

# Build development image
cd ~/claude-containers/development
docker build -t claude-dev:latest .

2.3 Production Container

bash
cat > ~/claude-containers/production/Dockerfile << 'EOF'
# Claude AI Production Container
FROM claude-base:latest

# Metadata for production
LABEL environment="production"
LABEL security-level="high"

# Switch to root for minimal package installation
USER root

# Install only essential production packages
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        supervisor \
        logrotate && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# Install production Python packages
RUN pip3 install --no-cache-dir \
    gunicorn \
    prometheus_client \
    psutil

# Configure supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# Configure log rotation
COPY logrotate.conf /etc/logrotate.d/claude

# Remove unnecessary packages and files
RUN apt-get autoremove -y && \
    rm -rf /tmp/* /var/tmp/* && \
    find /var/log -type f -exec truncate -s 0 {} \;

# Switch back to claude user
USER claude

# Set production environment variables
ENV NODE_ENV=production
ENV PYTHON_ENV=production
ENV CLAUDE_ENV=production
ENV CLAUDE_DEBUG=false

# Only expose necessary ports
EXPOSE 8000

# Health check for production
HEALTHCHECK --interval=60s --timeout=5s --start-period=30s --retries=5 \
    CMD curl -f http://localhost:8000/health || exit 1

# Production command
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
EOF

# Create supervisor configuration
cat > ~/claude-containers/production/supervisord.conf << 'EOF'
[supervisord]
nodaemon=true
user=root
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid

[program:claude-app]
command=/usr/bin/python3 /app/main.py
user=claude
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/app/logs/claude-app.log
EOF

# Create logrotate configuration
cat > ~/claude-containers/production/logrotate.conf << 'EOF'
/app/logs/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    copytruncate
    create 644 claude claude
}
EOF

# Build production image
cd ~/claude-containers/production
docker build -t claude-prod:latest .

Step 3: Docker Compose Configuration

3.1 Development Environment

bash
cat > ~/claude-containers/docker-compose.dev.yml << 'EOF'
version: '3.8'

services:
  claude-dev:
    image: claude-dev:latest
    container_name: claude-development
    hostname: claude-dev
    
    # Security settings
    security_opt:
      - no-new-privileges:true
      - seccomp=/etc/docker/seccomp/claude-profile.json
    cap_drop:
      - ALL
    cap_add:
      - CHOWN
      - DAC_OVERRIDE
      - FOWNER
      - SETGID
      - SETUID
    
    # Resource limits
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 4G
        reservations:
          cpus: '0.5'
          memory: 1G
    
    # Network configuration
    networks:
      - claude-network
    ports:
      - "3000:3000"
      - "8000:8000"
      - "8888:8888"
    
    # Volume mounts
    volumes:
      - claude-workspace:/app/workspace
      - claude-config:/app/config
      - claude-logs:/app/logs
      - /var/run/docker.sock:/var/run/docker.sock:ro  # For Docker-in-Docker if needed
    
    # Environment variables
    environment:
      - CLAUDE_ENV=development
      - CLAUDE_DEBUG=true
      - CLAUDE_LOG_LEVEL=DEBUG
      - PYTHONPATH=/app
    
    # User namespace
    user: "1000:1000"  # Map to host user
    
    # Health check
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    
    # Restart policy
    restart: unless-stopped

  # Optional: Database for development
  postgres-dev:
    image: postgres:15-alpine
    container_name: claude-postgres-dev
    environment:
      POSTGRES_DB: claude_dev
      POSTGRES_USER: claude
      POSTGRES_PASSWORD: development_only
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - claude-network
    ports:
      - "5432:5432"
    restart: unless-stopped

  # Optional: Redis for caching
  redis-dev:
    image: redis:7-alpine
    container_name: claude-redis-dev
    volumes:
      - redis-data:/data
    networks:
      - claude-network
    ports:
      - "6379:6379"
    restart: unless-stopped

networks:
  claude-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16

volumes:
  claude-workspace:
    driver: local
  claude-config:
    driver: local
  claude-logs:
    driver: local
  postgres-data:
    driver: local
  redis-data:
    driver: local
EOF

3.2 Production Environment

bash
cat > ~/claude-containers/docker-compose.prod.yml << 'EOF'
version: '3.8'

services:
  claude-prod:
    image: claude-prod:latest
    container_name: claude-production
    hostname: claude-prod
    
    # Enhanced security for production
    security_opt:
      - no-new-privileges:true
      - seccomp=/etc/docker/seccomp/claude-profile.json
      - apparmor:docker-default
    cap_drop:
      - ALL
    cap_add:
      - CHOWN
      - SETGID
      - SETUID
    read_only: true
    
    # Strict resource limits
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 2G
        reservations:
          cpus: '0.25'
          memory: 512M
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
    
    # Network configuration
    networks:
      - claude-prod-network
    ports:
      - "8000:8000"
    
    # Minimal volume mounts
    volumes:
      - claude-config-prod:/app/config:ro
      - claude-logs-prod:/app/logs
      - /tmp:/tmp  # Temporary writable directory
    
    # Production environment variables
    environment:
      - CLAUDE_ENV=production
      - CLAUDE_DEBUG=false
      - CLAUDE_LOG_LEVEL=INFO
      - PYTHONPATH=/app
    
    # User namespace
    user: "claude:claude"
    
    # Enhanced health check
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 60s
      timeout: 5s
      retries: 5
      start_period: 30s
    
    # Restart policy
    restart: always
    
    # Logging configuration
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "5"

  # Monitoring container
  monitoring:
    image: prom/prometheus:latest
    container_name: claude-monitoring
    volumes:
      - prometheus-config:/etc/prometheus
      - prometheus-data:/prometheus
    networks:
      - claude-prod-network
    ports:
      - "9090:9090"
    restart: always

networks:
  claude-prod-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.21.0.0/16
    driver_opts:
      com.docker.network.enable_ipv6: "false"

volumes:
  claude-config-prod:
    driver: local
    driver_opts:
      type: none
      o: bind,ro
      device: /opt/claude/config
  claude-logs-prod:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /var/log/claude
  prometheus-config:
    driver: local
  prometheus-data:
    driver: local
EOF

Step 4: Container Management Scripts

4.1 Container Management Tool

bash
cat > ~/.local/bin/claude-container << 'EOF'
#!/bin/bash
# Claude Container Management Tool

set -euo pipefail

CONTAINERS_DIR="$HOME/claude-containers"
COMPOSE_DEV="$CONTAINERS_DIR/docker-compose.dev.yml"
COMPOSE_PROD="$CONTAINERS_DIR/docker-compose.prod.yml"

show_help() {
    cat << 'EOF'
Claude Container Management Tool

Usage: claude-container [COMMAND] [OPTIONS]

Commands:
    build [env]           Build containers (dev/prod/all)
    start [env]           Start environment (dev/prod)
    stop [env]            Stop environment (dev/prod)
    restart [env]         Restart environment
    status               Show container status
    logs [service]       Show logs for service
    shell [service]      Open shell in container
    clean               Clean up containers and volumes
    security-scan       Run security scan on containers

Options:
    --force             Force operation
    --detach           Run in background
    --build            Build before starting

Examples:
    claude-container build dev
    claude-container start prod --detach
    claude-container shell claude-dev
    claude-container security-scan
EOF
}

build_containers() {
    local env="${1:-all}"
    
    echo "🔨 Building Claude containers..."
    
    case "$env" in
        "dev"|"development")
            echo "Building development environment..."
            cd "$CONTAINERS_DIR"
            docker-compose -f "$COMPOSE_DEV" build
            ;;
        "prod"|"production")
            echo "Building production environment..."
            cd "$CONTAINERS_DIR"
            docker-compose -f "$COMPOSE_PROD" build
            ;;
        "all")
            build_containers "dev"
            build_containers "prod"
            ;;
        *)
            echo "❌ Unknown environment: $env"
            echo "Valid environments: dev, prod, all"
            return 1
            ;;
    esac
    
    echo "✅ Build completed"
}

start_environment() {
    local env="$1"
    local detach="${detach:-false}"
    local build="${build:-false}"
    
    echo "🚀 Starting $env environment..."
    
    local compose_file
    case "$env" in
        "dev"|"development")
            compose_file="$COMPOSE_DEV"
            ;;
        "prod"|"production")
            compose_file="$COMPOSE_PROD"
            ;;
        *)
            echo "❌ Unknown environment: $env"
            return 1
            ;;
    esac
    
    local args=()
    if [ "$detach" = "true" ]; then
        args+=(-d)
    fi
    
    if [ "$build" = "true" ]; then
        args+=(--build)
    fi
    
    cd "$CONTAINERS_DIR"
    docker-compose -f "$compose_file" up "${args[@]}"
    
    echo "✅ $env environment started"
}

stop_environment() {
    local env="$1"
    
    echo "🛑 Stopping $env environment..."
    
    local compose_file
    case "$env" in
        "dev"|"development")
            compose_file="$COMPOSE_DEV"
            ;;
        "prod"|"production")
            compose_file="$COMPOSE_PROD"
            ;;
        *)
            echo "❌ Unknown environment: $env"
            return 1
            ;;
    esac
    
    cd "$CONTAINERS_DIR"
    docker-compose -f "$compose_file" down
    
    echo "✅ $env environment stopped"
}

show_status() {
    echo "📊 Container Status"
    echo "==================="
    
    echo "Development Environment:"
    cd "$CONTAINERS_DIR"
    docker-compose -f "$COMPOSE_DEV" ps
    
    echo
    echo "Production Environment:"
    docker-compose -f "$COMPOSE_PROD" ps
    
    echo
    echo "Docker System Info:"
    docker system df
}

show_logs() {
    local service="${1:-}"
    local env="${2:-dev}"
    
    local compose_file
    case "$env" in
        "dev"|"development")
            compose_file="$COMPOSE_DEV"
            ;;
        "prod"|"production")
            compose_file="$COMPOSE_PROD"
            ;;
        *)
            echo "❌ Unknown environment: $env"
            return 1
            ;;
    esac
    
    cd "$CONTAINERS_DIR"
    if [ -n "$service" ]; then
        docker-compose -f "$compose_file" logs -f "$service"
    else
        docker-compose -f "$compose_file" logs -f
    fi
}

open_shell() {
    local service="${1:-claude-dev}"
    
    echo "🐚 Opening shell in $service..."
    
    if docker ps --filter "name=$service" --filter "status=running" | grep -q "$service"; then
        docker exec -it "$service" /bin/bash
    else
        echo "❌ Container $service is not running"
        return 1
    fi
}

clean_containers() {
    local force="${force:-false}"
    
    echo "🧹 Cleaning up containers and volumes..."
    
    if [ "$force" = "true" ] || read -p "This will remove all Claude containers and volumes. Continue? (y/N): " -n 1 -r && [[ $REPLY =~ ^[Yy]$ ]]; then
        echo
        
        # Stop all containers
        docker-compose -f "$COMPOSE_DEV" down -v 2>/dev/null || true
        docker-compose -f "$COMPOSE_PROD" down -v 2>/dev/null || true
        
        # Remove Claude images
        docker images | grep claude | awk '{print $3}' | xargs -r docker rmi
        
        # Clean up system
        docker system prune -f
        
        echo "✅ Cleanup completed"
    else
        echo "❌ Cleanup cancelled"
    fi
}

security_scan() {
    echo "🔒 Running security scan on Claude containers..."
    
    # Check for available security scanners
    local scanners=()
    
    if command -v trivy >/dev/null 2>&1; then
        scanners+=("trivy")
    fi
    
    if command -v docker-bench-security >/dev/null 2>&1; then
        scanners+=("docker-bench")
    fi
    
    if [ ${#scanners[@]} -eq 0 ]; then
        echo "⚠️  No security scanners found. Install trivy or docker-bench-security"
        return 1
    fi
    
    # Scan images
    for image in claude-base claude-dev claude-prod; do
        if docker images | grep -q "$image"; then
            echo "Scanning $image..."
            
            for scanner in "${scanners[@]}"; do
                case "$scanner" in
                    "trivy")
                        trivy image "$image:latest"
                        ;;
                    "docker-bench")
                        docker run --rm -it \
                            -v /var/run/docker.sock:/var/run/docker.sock \
                            -v /etc:/etc:ro \
                            -v /usr/bin/docker-containerd:/usr/bin/docker-containerd:ro \
                            -v /usr/bin/docker-runc:/usr/bin/docker-runc:ro \
                            -v /usr/lib/systemd:/usr/lib/systemd:ro \
                            -v /var/lib:/var/lib:ro \
                            -v /var/run:/var/run:ro \
                            --label docker_bench_security \
                            docker/docker-bench-security
                        ;;
                esac
            done
        fi
    done
    
    echo "✅ Security scan completed"
}

# Parse command line arguments
force=false
detach=false
build=false

while [[ $# -gt 0 ]]; do
    case $1 in
        --force)
            force=true
            shift
            ;;
        --detach)
            detach=true
            shift
            ;;
        --build)
            build=true
            shift
            ;;
        build)
            build_containers "${2:-all}"
            exit 0
            ;;
        start)
            if [ -z "${2:-}" ]; then
                echo "❌ Environment required"
                exit 1
            fi
            start_environment "$2"
            exit 0
            ;;
        stop)
            if [ -z "${2:-}" ]; then
                echo "❌ Environment required"
                exit 1
            fi
            stop_environment "$2"
            exit 0
            ;;
        restart)
            if [ -z "${2:-}" ]; then
                echo "❌ Environment required"
                exit 1
            fi
            stop_environment "$2"
            start_environment "$2"
            exit 0
            ;;
        status)
            show_status
            exit 0
            ;;
        logs)
            show_logs "${2:-}" "${3:-dev}"
            exit 0
            ;;
        shell)
            open_shell "${2:-claude-dev}"
            exit 0
            ;;
        clean)
            clean_containers
            exit 0
            ;;
        security-scan)
            security_scan
            exit 0
            ;;
        help|--help|-h)
            show_help
            exit 0
            ;;
        *)
            echo "❌ Unknown command: $1"
            show_help
            exit 1
            ;;
    esac
done

show_help
EOF

chmod +x ~/.local/bin/claude-container

Step 5: Security Monitoring

5.1 Container Security Monitor

bash
cat > ~/.local/bin/claude-container-monitor << 'EOF'
#!/bin/bash
# Claude Container Security Monitor

set -euo pipefail

MONITOR_LOG="/var/log/claude/container-monitor.log"
CHECK_INTERVAL=60

log_event() {
    local level="$1"
    local message="$2"
    local timestamp=$(date --iso-8601=seconds)
    echo "[$timestamp] [$level] $message" | tee -a "$MONITOR_LOG"
}

check_container_security() {
    echo "🔒 Checking container security..."
    
    # Check for privileged containers
    local privileged=$(docker ps --filter "status=running" --format "table {{.Names}}\t{{.Command}}" | grep -i privileged || true)
    if [ -n "$privileged" ]; then
        log_event "WARNING" "Privileged containers detected: $privileged"
    fi
    
    # Check for containers running as root
    local root_containers=$(docker ps --format "table {{.Names}}" | tail -n +2 | while read container; do
        local user_info=$(docker inspect "$container" --format '{{.Config.User}}' 2>/dev/null || echo "")
        if [ -z "$user_info" ] || [ "$user_info" = "0" ] || [ "$user_info" = "root" ]; then
            echo "$container"
        fi
    done)
    
    if [ -n "$root_containers" ]; then
        log_event "WARNING" "Containers running as root: $root_containers"
    fi
    
    # Check for excessive capabilities
    local cap_check=$(docker ps --format "{{.Names}}" | while read container; do
        local caps=$(docker inspect "$container" --format '{{.HostConfig.CapAdd}}' 2>/dev/null || echo "")
        if [ "$caps" != "<nil>" ] && [ -n "$caps" ]; then
            echo "$container: $caps"
        fi
    done)
    
    if [ -n "$cap_check" ]; then
        log_event "INFO" "Containers with added capabilities: $cap_check"
    fi
}

check_resource_usage() {
    echo "📊 Checking resource usage..."
    
    # Check memory usage
    docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}" | tail -n +2 | while read line; do
        local container=$(echo "$line" | awk '{print $1}')
        local cpu_percent=$(echo "$line" | awk '{print $2}' | tr -d '%')
        local mem_percent=$(echo "$line" | awk '{print $4}' | tr -d '%')
        
        # Alert on high resource usage
        if (( $(echo "$cpu_percent > 80" | bc -l) )); then
            log_event "WARNING" "High CPU usage in $container: ${cpu_percent}%"
        fi
        
        if (( $(echo "$mem_percent > 90" | bc -l) )); then
            log_event "WARNING" "High memory usage in $container: ${mem_percent}%"
        fi
    done
}

check_network_security() {
    echo "🌐 Checking network security..."
    
    # Check for containers with host networking
    local host_network=$(docker ps --format "{{.Names}}" | while read container; do
        local network_mode=$(docker inspect "$container" --format '{{.HostConfig.NetworkMode}}' 2>/dev/null || echo "")
        if [ "$network_mode" = "host" ]; then
            echo "$container"
        fi
    done)
    
    if [ -n "$host_network" ]; then
        log_event "WARNING" "Containers using host network: $host_network"
    fi
    
    # Check for exposed ports
    local exposed_ports=$(docker ps --format "{{.Names}}\t{{.Ports}}" | grep -v "127.0.0.1" | grep "::" | cut -f1)
    if [ -n "$exposed_ports" ]; then
        log_event "INFO" "Containers with exposed ports: $exposed_ports"
    fi
}

check_volume_security() {
    echo "💾 Checking volume security..."
    
    # Check for dangerous volume mounts
    local dangerous_mounts=$(docker ps --format "{{.Names}}" | while read container; do
        local mounts=$(docker inspect "$container" --format '{{range .Mounts}}{{.Source}}:{{.Destination}} {{end}}' 2>/dev/null || echo "")
        if echo "$mounts" | grep -E "(:/etc|:/var|:/usr|:/bin|:/sbin)" | grep -v ":ro"; then
            echo "$container: $mounts"
        fi
    done)
    
    if [ -n "$dangerous_mounts" ]; then
        log_event "WARNING" "Potentially dangerous volume mounts: $dangerous_mounts"
    fi
}

generate_report() {
    echo "📋 Generating security report..."
    
    local report_file="/tmp/claude-container-security-$(date +%Y%m%d_%H%M%S).txt"
    
    cat > "$report_file" << EOF
Claude Container Security Report
Generated: $(date)
===============================

Container Status:
$(docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}")

Security Checks:
$(tail -20 "$MONITOR_LOG")

Resource Usage:
$(docker stats --no-stream)

Network Information:
$(docker network ls)

Volume Information:
$(docker volume ls)

Image Information:
$(docker images | grep claude)
EOF
    
    echo "✅ Report generated: $report_file"
}

monitor_loop() {
    echo "🔄 Starting container monitoring loop..."
    
    while true; do
        log_event "INFO" "Starting security check cycle"
        
        check_container_security
        check_resource_usage
        check_network_security
        check_volume_security
        
        log_event "INFO" "Security check cycle completed"
        
        sleep "$CHECK_INTERVAL"
    done
}

case "${1:-monitor}" in
    "monitor")
        monitor_loop
        ;;
    "check")
        check_container_security
        check_resource_usage
        check_network_security
        check_volume_security
        ;;
    "report")
        generate_report
        ;;
    *)
        echo "Usage: $0 [monitor|check|report]"
        echo ""
        echo "  monitor  Start continuous monitoring"
        echo "  check    Run single security check"
        echo "  report   Generate security report"
        ;;
esac
EOF

chmod +x ~/.local/bin/claude-container-monitor

Verification

Container Setup Verification

bash
# Build and test containers
claude-container build all

# Start development environment
claude-container start dev --detach

# Check container status
claude-container status

# Test container security
claude-container security-scan

# Run security monitoring
claude-container-monitor check

Security Testing

bash
# Test container isolation
docker exec -it claude-development whoami
docker exec -it claude-development id

# Check resource limits
docker stats --no-stream

# Verify network isolation
docker exec -it claude-development ip route

# Test volume permissions
docker exec -it claude-development ls -la /app

Troubleshooting

Common Issues

IssueSymptomsResolution
Build failuresDocker build errorsCheck Dockerfile syntax and base image availability
Permission deniedContainer access errorsVerify user namespaces and volume permissions
Resource exhaustionHigh CPU/memory usageAdjust resource limits in docker-compose
Network connectivityConnection failuresCheck network configuration and firewall rules

Debug Commands

bash
# Debug container build
docker build --no-cache --progress=plain -t claude-base .

# Check container logs
docker logs claude-development

# Inspect container configuration
docker inspect claude-development

# Test security settings
docker exec -it claude-development cat /proc/1/status | grep Cap

Recovery Procedures

bash
# Reset container environment
claude-container clean --force

# Rebuild all containers
claude-container build all

# Emergency container stop
docker kill $(docker ps -q)
docker system prune -af

See Also

Claude Code Documentation Hub