Fix port binding issue by adding dynamic port selection
This commit is contained in:
parent
8d79a1b61d
commit
e02176bc94
@ -1,3 +1,4 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
@ -10,9 +11,14 @@ class Settings(BaseSettings):
|
||||
extra="ignore"
|
||||
)
|
||||
|
||||
# API settings
|
||||
API_V1_STR: str = "/api/v1"
|
||||
PROJECT_NAME: str = "Todo Application"
|
||||
|
||||
# Server settings
|
||||
HOST: str = "0.0.0.0" # Listen on all available interfaces
|
||||
PORT: int = 8000 # Default port
|
||||
|
||||
# Database settings
|
||||
DB_DIR: Path = Path("/app") / "storage" / "db"
|
||||
SQLALCHEMY_DATABASE_URL: str = f"sqlite:///{DB_DIR}/db.sqlite"
|
||||
@ -20,6 +26,14 @@ class Settings(BaseSettings):
|
||||
def __init__(self, **data):
|
||||
super().__init__(**data)
|
||||
self.DB_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Override settings from environment variables if they exist
|
||||
if "PORT" in os.environ:
|
||||
try:
|
||||
self.PORT = int(os.environ["PORT"])
|
||||
except ValueError:
|
||||
# If PORT env var isn't a valid int, keep the default
|
||||
pass
|
||||
|
||||
|
||||
settings = Settings()
|
49
main.py
49
main.py
@ -1,9 +1,17 @@
|
||||
import logging
|
||||
import socket
|
||||
import sys
|
||||
|
||||
import uvicorn
|
||||
from fastapi import FastAPI
|
||||
|
||||
from app.api.api import api_router
|
||||
from app.core.config import settings
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
app = FastAPI(
|
||||
title=settings.PROJECT_NAME,
|
||||
openapi_url=f"{settings.API_V1_STR}/openapi.json",
|
||||
@ -13,5 +21,44 @@ app = FastAPI(
|
||||
|
||||
app.include_router(api_router, prefix=settings.API_V1_STR)
|
||||
|
||||
def find_available_port(start_port, max_attempts=10):
|
||||
"""Try to find an available port starting from start_port"""
|
||||
for port in range(start_port, start_port + max_attempts):
|
||||
try:
|
||||
# Try to create a socket with the port
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||
s.bind((settings.HOST, port))
|
||||
# If we get here, the port is available
|
||||
return port
|
||||
except OSError:
|
||||
# Port is already in use, try the next one
|
||||
continue
|
||||
|
||||
# If we get here, no ports were available in our range
|
||||
port_range_end = start_port + max_attempts - 1
|
||||
logger.warning(
|
||||
f"Could not find an available port in range {start_port}-{port_range_end}"
|
||||
)
|
||||
return None
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
|
||||
port = settings.PORT
|
||||
|
||||
# Check if the port is already in use
|
||||
try:
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||
s.bind((settings.HOST, port))
|
||||
except OSError:
|
||||
logger.warning(
|
||||
f"Port {port} is already in use. Trying to find an available port..."
|
||||
)
|
||||
port = find_available_port(port + 1)
|
||||
|
||||
if port is None:
|
||||
logger.error("Could not find an available port. Exiting.")
|
||||
sys.exit(1)
|
||||
|
||||
logger.info(f"Using alternative port: {port}")
|
||||
|
||||
# Start the server with the available port
|
||||
uvicorn.run("main:app", host=settings.HOST, port=port, reload=True)
|
Loading…
x
Reference in New Issue
Block a user