home-docker/scripts/check-port-conflicts.py
2025-06-21 16:14:29 -05:00

81 lines
No EOL
2.7 KiB
Python
Executable file

#!/usr/bin/env python3
import os
import re
import sys
from pathlib import Path
def extract_ports_from_compose(file_path):
"""Extract host ports from a docker-compose file using regex."""
ports = []
try:
with open(file_path, 'r') as f:
content = f.read()
# Find ports section and extract port mappings
# Match patterns like: - "8080:8080", - 8080:8080, - "127.0.0.1:8080:8080"
port_pattern = r'^\s*-\s*["\']?(?:\d+\.\d+\.\d+\.\d+:)?(\d+):\d+["\']?'
for line in content.split('\n'):
match = re.match(port_pattern, line)
if match:
host_port = int(match.group(1))
ports.append(host_port)
except Exception as e:
print(f"Error reading {file_path}: {e}")
return ports
def find_next_available_port(used_ports, starting_port):
"""Find the next available port starting from the given port."""
port = starting_port
while port in used_ports:
port += 1
return port
def check_port_conflicts():
"""Check for port conflicts within each docker group."""
base_dir = Path('.')
docker_groups = ['main-docker', 'auth-docker', 'admin-docker', 'komodo-periphery']
conflicts_found = False
for group in docker_groups:
group_path = base_dir / group
if not group_path.exists():
continue
group_ports = {} # port -> [service_files]
all_used_ports = set()
# Find all compose files in this group
for compose_file in group_path.rglob('compose.yaml'):
service_name = compose_file.parent.name
ports = extract_ports_from_compose(compose_file)
for port in ports:
all_used_ports.add(port)
if port not in group_ports:
group_ports[port] = []
group_ports[port].append(f"{group}/{service_name}")
# Check for conflicts within this group
for port, services in group_ports.items():
if len(services) > 1:
suggested_port = find_next_available_port(all_used_ports, port + 1)
print(f"❌ Port conflict in {group}: Port {port} used by {', '.join(services)}")
print(f"💡 Suggestion: Use port {suggested_port} for one of the conflicting services")
conflicts_found = True
if group_ports and not any(len(services) > 1 for services in group_ports.values()):
print(f"✅ No port conflicts in {group}")
return conflicts_found
if __name__ == "__main__":
if check_port_conflicts():
sys.exit(1)
else:
print("🎉 No port conflicts detected!")
sys.exit(0)