Update server config, SSL handling, and port mapping logic

Refactored `run_server` to accept explicit config and SSL paths. Added dynamic environment-based config loading and stricter SSL path checks for production. Updated `docker-compose.yml` to use environment variable for port mapping and adjusted `config_prod.json` to reflect correct port usage.
This commit is contained in:
GotthardG
2025-04-11 12:37:18 +02:00
parent afa473e8a8
commit 86d03285e4
3 changed files with 49 additions and 26 deletions

View File

@ -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)