from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates import docker import dotenv from routers.deploy import router as deploy_router, deployed_projects from routers.controls import router as controls_router from routers.logs import router as logs_router # Load environment variables dotenv.load_dotenv() app = FastAPI() # --- Templating --- templates = Jinja2Templates(directory="templates") # --- Routers --- app.include_router(controls_router, prefix="/controls") app.include_router(logs_router, prefix="/logs") app.include_router(deploy_router, prefix="/deploy") # --- Docker Client --- client = docker.from_env() # --- Endpoints --- @app.get("/", response_class=HTMLResponse) async def dashboard(request: Request): """Serves the main dashboard page.""" return templates.TemplateResponse("dashboard.html", {"request": request}) @app.get("/projects") def get_projects(): """Returns a list of all deployed projects with their status and URL.""" # Create a list of projects from the deployed_projects dictionary projects_list = [] for project_id, details in deployed_projects.items(): container_name = details.get("container_name", "N/A") public_url = details.get("public_url", "#") local_url = "#" if container_name != "N/A": try: container = client.containers.get(container_name) port_bindings = client.api.inspect_container(container.id)['NetworkSettings']['Ports'] if '8080/tcp' in port_bindings and port_bindings['8080/tcp'] is not None: host_port = port_bindings['8080/tcp'][0]['HostPort'] # Get the local IP address of the machine import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: # Doesn't matter if the host is reachable s.connect(('10.255.255.255', 1)) host_ip = s.getsockname()[0] except Exception: host_ip = '127.0.0.1' # Fallback to localhost finally: s.close() local_url = f"http://{host_ip}:{host_port}" except docker.errors.NotFound: print(f"Container {container_name} not found for project {project_id}.") except Exception as e: print(f"Error getting local URL for container {container_name}: {e}") projects_list.append({ "id": project_id, "name": details.get("app_name", "N/A"), "status": details.get("status", "Unknown"), "public_url": public_url, "local_url": local_url, "container_name": container_name }) return projects_list