diff --git a/backend/config_prod.json b/backend/config_prod.json index 77e4269..7ce6819 100644 --- a/backend/config_prod.json +++ b/backend/config_prod.json @@ -1,10 +1,10 @@ { "ssl_cert_path": "/app/backend/ssl/mx-aare-test.psi.ch.pem", "ssl_key_path": "/app/backend/ssl/mx-aare-test.psi.ch.key", - "OPENAPI_URL": "https://backend:8000/openapi.json", + "PORT": 1492, + "OPENAPI_URL": "https://backend:1492/openapi.json", "SCHEMA_PATH": "/app/src/openapi.json", "OUTPUT_DIRECTORY": "/app/openapi", - "PORT": 8000, "SSL_KEY_PATH": "/app/backend/ssl/mx-aare-test.psi.ch.key", "SSL_CERT_PATH": "/app/backend/ssl/mx-aare-test.psi.ch.pem" } \ No newline at end of file diff --git a/backend/main.py b/backend/main.py index fbe6c72..7c80506 100644 --- a/backend/main.py +++ b/backend/main.py @@ -50,21 +50,26 @@ def get_project_metadata(): ) -def run_server(): +def run_server(config, cert_path, key_path): import uvicorn + environment = os.getenv( + "ENVIRONMENT", "dev" + ) # needs to be set explicitly here if not globally available + print(f"[INFO] Starting server in {environment} environment...") print(f"[INFO] SSL Certificate Path: {cert_path}") print(f"[INFO] SSL Key Path: {key_path}") - port = config.get("PORT", os.getenv("PORT")) + port = config.get("PORT") if not port: print("[ERROR] No port defined in config or environment variables. Aborting!") sys.exit(1) # Exit if no port is defined port = int(port) print(f"[INFO] Running on port {port}") + uvicorn.run( app, - host="0.0.0.0" if environment in ["dev", "test"] else "0.0.0.0", + host="0.0.0.0", port=port, log_level="debug", ssl_keyfile=key_path, @@ -214,6 +219,9 @@ if __name__ == "__main__": # Load environment variables from .env file load_dotenv() + environment = os.getenv("ENVIRONMENT", "dev") + config_file = Path(__file__).resolve().parent / f"config_{environment}.json" + # Check if `generate-openapi` option is passed if len(sys.argv) > 1 and sys.argv[1] == "generate-openapi": from fastapi.openapi.utils import get_openapi @@ -230,28 +238,42 @@ if __name__ == "__main__": print("openapi.json generated successfully.") sys.exit(0) # Exit after generating the file - # Default behavior: Run the server based on the environment - environment = os.getenv("ENVIRONMENT", "dev") - port = int(os.getenv("PORT", 8000)) + # Explicitly load the configuration file + with open(config_file, "r") as f: + config = json.load(f) + + # Explicitly obtain SSL paths from config + if environment in ["test", "dev"]: + cert_path = config.get("ssl_cert_path", "ssl/cert.pem") + key_path = config.get("ssl_key_path", "ssl/key.pem") + elif environment == "prod": + cert_path = config.get("SSL_CERT_PATH") + key_path = config.get("SSL_KEY_PATH") + if not cert_path or not key_path: + raise ValueError( + "SSL_CERT_PATH and SSL_KEY_PATH must be explicitly" + "set in config_prod.json for production." + ) + else: + raise ValueError(f"Unknown environment: {environment}") + is_ci = os.getenv("CI", "false").lower() == "true" + # Handle certificates for dev/test if not available + ssl_dir = Path(cert_path).parent + ssl_dir.mkdir(parents=True, exist_ok=True) + if environment in ["dev", "test"] and ( + not Path(cert_path).exists() or not Path(key_path).exists() + ): + print(f"[INFO] Generating SSL certificates at {ssl_dir}") + ssl_heidi.generate_self_signed_cert(cert_path, key_path) + if is_ci or environment == "test": - # Test or CI Mode: Run server process temporarily for test validation - ssl_dir = Path(cert_path).parent - ssl_dir.mkdir(parents=True, exist_ok=True) - - # Generate self-signed certs if missing - if not Path(cert_path).exists() or not Path(key_path).exists(): - print(f"[INFO] Generating self-signed SSL certificates at {ssl_dir}") - ssl_heidi.generate_self_signed_cert(cert_path, key_path) - - # Start the server as a subprocess, wait, then terminate - server_process = Process(target=run_server) + server_process = Process(target=run_server, args=(config, cert_path, key_path)) server_process.start() - sleep(5) # Wait for 5 seconds to verify the server is running - server_process.terminate() # Terminate the server process (for CI) - server_process.join() # Ensure proper cleanup - print("CI: Server started and terminated successfully for test validation.") + sleep(5) + server_process.terminate() + server_process.join() + print("CI/Test environment: Server started and terminated successfully.") else: - # Dev or Prod: Start the server as usual - run_server() + run_server(config, cert_path, key_path) diff --git a/docker-compose.yml b/docker-compose.yml index 12e25a3..4c1a4f2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,7 +7,7 @@ services: dockerfile: backend/Dockerfile ports: - - "8000:8000" # Map container port 8000 to host + - "${PORT}:${PORT}" # Map container port 8000 to host volumes: - ./backend:/app/backend # Map backend directory to /app/backend - ./app:/app/app # Map app directory to /app/app @@ -28,6 +28,7 @@ services: DB_PASSWORD: ${DB_PASSWORD} DB_HOST: postgres DB_NAME: ${DB_NAME} + PORT: ${PORT} postgres: # ⬅️ New service (our PostgreSQL database) image: postgres:16