Port Mappings¶
Service port configurations and mappings.
Overview¶
Port mappings control how services are accessed and communicate within the homelab infrastructure.
Port Mapping Strategy¶
Internal vs External Ports¶
- Internal Ports: Ports used within Docker containers
- External Ports: Ports exposed to the host system
- Proxy Ports: Ports used by Caddy reverse proxy
Recommended Approach¶
- Use Caddy Proxy: Most services should use Caddy for external access
- Limit Direct Port Exposure: Only expose ports when necessary
- Use Standard Ports: Use standard port ranges when possible
Service Port Configurations¶
Core Services¶
Caddy¶
# No port mapping needed (uses host network)
# Caddy handles all external traffic
ports: []
# Uses ports 80 (HTTP) and 443 (HTTPS) on host
PostgreSQL¶
# Internal only, no external access
ports: []
# Internal port: 5432
# Access via internal_db network only
Management Services¶
Portainer¶
# Direct access for Docker management
ports:
- "9000:9000"
# Internal port: 9000
# External access: https://docker.brennan.page (via Caddy)
# Direct access: http://localhost:9000
Monitor (Enhanced Monitor)¶
# Direct access for system monitoring
ports:
- "61208:61208"
# Internal port: 61208
# External access: https://monitor.brennan.page (via Caddy)
# Direct access: http://localhost:61208
FileBrowser¶
# No port mapping (uses Caddy proxy)
ports: []
# Internal port: 80
# External access: https://files.brennan.page (via Caddy)
Productivity Services¶
Vikunja¶
# No port mapping (uses Caddy proxy)
ports: []
# Internal port: 80
# External access: https://tasks.brennan.page (via Caddy)
HedgeDoc¶
# No port mapping (uses Caddy proxy)
ports: []
# Internal port: 3000
# External access: https://notes.brennan.page (via Caddy)
Linkding¶
# No port mapping (uses Caddy proxy)
ports: []
# Internal port: 9090
# External access: https://bookmarks.brennan.page (via Caddy)
Navidrome¶
# No port mapping (uses Caddy proxy)
ports: []
# Internal port: 4533
# External access: https://music.brennan.page/music/app/ (via Caddy)
Phase 4 Services¶
WriteFreely¶
# No port mapping (uses Caddy proxy)
ports: []
# Internal port: 8080
# External access: https://blog.brennan.page (via Caddy)
Flarum¶
# No port mapping (uses Caddy proxy)
ports: []
# Internal port: 8888
# External access: https://forum.brennan.page (via Caddy)
FreshRSS¶
# No port mapping (uses Caddy proxy)
ports: []
# Internal port: 80
# External access: https://rss.brennan.page (via Caddy)
Port Mapping Examples¶
Direct Port Access¶
# When direct access is needed
services:
service_name:
image: service:latest
ports:
- "8080:80" # Host port 8080 -> Container port 80
- "8443:443" # Host port 8443 -> Container port 443
No Port Mapping (Proxy Only)¶
# When using Caddy proxy
services:
service_name:
image: service:latest
ports: [] # No direct port access
networks:
- caddy # Only accessible via Caddy
Host Network¶
# When container needs host network
services:
service_name:
image: service:latest
network_mode: host # Uses host network
ports: [] # No port mapping needed
Port Allocation¶
Standard Port Ranges¶
- 8000-8999: Development services
- 9000-9999: Management services
- 10000-10999: Specialized services
Current Port Usage¶
# Check port usage
netstat -tulpn | grep -E ":80|:443|:5432|:9000|:61208|:8080|:8888"
# Docker port mappings
docker ps --format "table {{.Names}}\t{{.Ports}}"
Port Conflicts¶
# Check for port conflicts
ss -tulpn | grep ":8080"
# Find available ports
netstat -tulpn | grep ":808[0-9]"
Caddy Proxy Configuration¶
Service Proxy Configuration¶
# Standard service proxy
service.brennan.page {
import compression
import security
reverse_proxy service:internal_port
handle_errors {
respond "Service unavailable" 503
}
}
# Service with specific path
service.brennan.page {
import compression
import security
reverse_proxy service:internal_port {
/api/* service:internal_port
/static/* service:internal_port
}
}
Internal Port Mapping¶
# WriteFreely (internal port 8080)
blog.brennan.page {
reverse_proxy writefreely:8080
}
# Flarum (internal port 8888)
forum.brennan.page {
reverse_proxy flarum:8888
}
# FreshRSS (internal port 80)
rss.brennan.page {
reverse_proxy freshrss:80
}
Port Management¶
Checking Port Usage¶
# Check all listening ports
netstat -tulpn
# Check Docker port mappings
docker ps --format "table {{.Names}}\t{{.Ports}}"
# Check specific port
netstat -tulpn | grep ":8080"
Finding Available Ports¶
# Find available port in range
for port in {8080..8090}; do
if ! netstat -tulpn | grep -q ":$port "; then
echo "Port $port is available"
break
fi
done
Resolving Port Conflicts¶
# Find process using port
lsof -i :8080
# Kill process if necessary
kill -9 <PID>
# Or change service port
# Edit docker-compose.yml
ports:
- "8081:80" # Use different host port
Security Considerations¶
Port Exposure¶
# Limit port exposure
services:
service_name:
ports:
- "127.0.0.1:8080:80" # Only localhost
- "10.0.0.0:8080:80" # Only internal network
Firewall Configuration¶
# UFW firewall rules
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw allow 22/tcp # SSH
ufw deny 8080/tcp # Block direct access
ufw deny 9000/tcp # Block direct access
Network Isolation¶
# Use internal networks
networks:
caddy:
external: true
internal_db:
external: true
service_network:
driver: bridge
internal: true # No external access
Port Configuration Templates¶
Web Service Template¶
services:
web_service:
image: service:latest
ports: [] # No direct access
networks:
- caddy # Only via proxy
Management Service Template¶
services:
management_service:
image: service:latest
ports:
- "9000:9000" # Direct access
networks:
- caddy
- management
Database Service Template¶
services:
database_service:
image: postgres:14
ports: [] # No external access
networks:
- internal_db # Only internal access
Troubleshooting¶
Port Not Accessible¶
# Check if port is listening
netstat -tulpn | grep ":8080"
# Check Docker port mapping
docker port service_name
# Check Caddy configuration
docker exec caddy cat /etc/caddy/Caddyfile | grep service_name
Proxy Issues¶
# Test direct service access
curl -I http://localhost:8080
# Test proxy access
curl -I https://service.brennan.page
# Check Caddy logs
docker logs caddy | grep service_name
Port Conflicts¶
# Find conflicting process
lsof -i :8080
# Check Docker containers using port
docker ps --format "table {{.Names}}\t{{.Ports}}" | grep 8080
# Resolve conflict
docker stop conflicting_container
# or change port mapping
Best Practices¶
Port Management¶
- Use Caddy proxy for web services when possible
- Limit direct port exposure to management services only
- Use standard port ranges for consistency
- Document all port mappings
Security¶
- Use firewall to restrict port access
- Limit port exposure to localhost when possible
- Use internal networks for database access
- Regularly audit port usage
Performance¶
- Avoid port conflicts with proper planning
- Use load balancing for high-traffic services
- Monitor port usage and performance
- Use connection pooling for database connections
Getting Help¶
Before Reporting Issues¶
- Checked port usage
- Verified port mappings
- Tested direct access
- Checked proxy configuration
Information to Include¶
- Port usage output
- Docker port mappings
- Caddy configuration
- Error messages
- Network configuration