Create comprehensive guide for future Claude Code instances working with this nginx-proxy-manager automation project. Includes: - System architecture overview (Podman + Quadlet + systemd) - Essential development and diagnostic commands - Critical configuration file locations and dependencies - Troubleshooting patterns for rootless container deployment - Security model and performance characteristics Focus on operational knowledge specific to this rootless container setup with privileged port binding and systemd auto-start. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
4.9 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
This repository contains infrastructure automation for deploying nginx-proxy-manager using Podman + Quadlet on Debian systems. The architecture uses rootless containers with systemd-based auto-start for production proxy workloads.
System Architecture
The system is built on a three-layer architecture:
- Container Runtime: Podman 5.4.2 running in rootless mode with pasta networking
- Orchestration: Quadlet (systemd generator) managing container lifecycle
- Host System: Debian 13 with optimized kernel parameters for proxy workloads
Key Design Decisions:
- Rootless containers for security isolation
- Quadlet over Docker Compose for systemd integration
- Kernel tuning specifically for high-connection proxy scenarios
- Auto-start without user login via systemd lingering
Development Commands
Container Management
# Check service status
systemctl --user status nginx-proxy-manager.service
# View logs in real-time
journalctl --user -u nginx-proxy-manager.service -f
# Container inspection
podman ps
podman logs nginx-proxy-manager
podman exec -it nginx-proxy-manager /bin/bash
# Force container recreation
systemctl --user stop nginx-proxy-manager.service
systemctl --user start nginx-proxy-manager.service
Quadlet Configuration Testing
# Validate Quadlet syntax before applying
/usr/libexec/podman/quadlet --user --dryrun
# Reload systemd after Quadlet changes
systemctl --user daemon-reload
System Diagnostics
# Check kernel parameters are applied
cat /proc/sys/net/ipv4/ip_unprivileged_port_start # should be 80
cat /proc/sys/vm/swappiness # should be 10
cat /proc/sys/net/core/somaxconn # should be 65535
# Verify port bindings
ss -tlnp | grep ':80\|:81\|:443'
# Check lingering status
loginctl show-user admin | grep Linger
Critical Configuration Files
Quadlet Container Definition
Location: ~/.config/containers/systemd/nginx-proxy-manager.container
This file defines the container specification in systemd-native format. Key settings:
PublishPort=80:80requiresnet.ipv4.ip_unprivileged_port_start=80AutoUpdate=registryenables automatic image updatesWantedBy=default.targetenables boot-time auto-start
Kernel Tuning
Location: /etc/sysctl.d/99-container-tuning.conf
Critical for rootless containers binding to privileged ports:
net.ipv4.ip_unprivileged_port_start=80- enables port 80 binding without rootnet.core.somaxconn=65535- handles high connection loadsvm.swappiness=10- prioritizes memory over swap for container performance
systemd Resource Limits
Location: /etc/systemd/system.conf.d/limits.conf
Extends default systemd limits for container workloads.
Deployment Architecture
The system requires specific deployment order:
- Host Preparation: Kernel tuning and systemd limits
- User Setup: Enable lingering for non-interactive service start
- Quadlet Deployment: Container definition and systemd integration
- Validation: Auto-start testing via reboot
Port Requirements:
- Port 80: HTTP traffic
- Port 81: Admin interface
- Port 443: HTTPS traffic
Network Architecture
Uses Podman's netavark backend with pasta for network isolation:
- Each container gets isolated network namespace
- Host ports mapped directly to container ports
- DNS forwarding through pasta daemon
- IPv6 disabled via container environment
Troubleshooting Patterns
Service Won't Start: Usually kernel parameter issues
- Check
ip_unprivileged_port_startsetting - Verify Quadlet syntax with dry-run
Port Binding Failures: Permission or conflict issues
- Check if ports are already in use:
ss -tlnp - Verify rootless port permissions
Auto-start Failures: systemd lingering issues
- Ensure lingering enabled:
loginctl enable-linger admin - Check service dependencies
Performance Characteristics
System tuned for proxy workloads:
- Boot Time: ~40 seconds to full service availability
- Connection Handling: 65,535 concurrent connections (somaxconn limit)
- Memory Usage: Optimized for memory-over-swap with vm.swappiness=10
- TCP Optimization: Reduced connection timeouts for proxy traffic
Security Model
Rootless Isolation:
- Container runs without root privileges on host
- User namespace isolation
- Limited blast radius for container escapes
Network Security:
- Pasta provides network namespace isolation
- Only explicitly mapped ports are accessible
- Container has no direct host network access
Extension Points
The architecture supports:
- Multiple container deployment via additional
.containerfiles - Load balancer integration through consistent port mapping
- Monitoring integration via systemd service dependencies
- Backup automation through volume management