From 0a6da2f9c19eafe9a08de1c9280b4f75ceab196a Mon Sep 17 00:00:00 2001 From: sirius0xdev Date: Tue, 7 Jul 2026 18:24:01 -0400 Subject: [PATCH] Run migrations via entrypoint (alembic upgrade head) instead of nested asyncio.run in startup hook --- Dockerfile | 3 ++- app/docker-entrypoint.sh | 10 ++++++++++ app/main.py | 10 +++++----- 3 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 app/docker-entrypoint.sh diff --git a/Dockerfile b/Dockerfile index 9ca7f24..c1d4a3a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,8 @@ RUN pip install --no-cache-dir -r requirements.txt COPY app/ ./app/ COPY alembic.ini ./alembic.ini COPY alembic/ ./alembic/ +RUN chmod +x /app/app/docker-entrypoint.sh EXPOSE 8000 ENV PYTHONPATH=/app/app -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] +ENTRYPOINT ["/app/app/docker-entrypoint.sh"] diff --git a/app/docker-entrypoint.sh b/app/docker-entrypoint.sh new file mode 100644 index 0000000..d424e23 --- /dev/null +++ b/app/docker-entrypoint.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# App entrypoint: apply migrations, then launch the API. +set -e + +cd /app +echo "[entrypoint] running migrations..." +alembic upgrade head + +echo "[entrypoint] starting uvicorn..." +exec uvicorn app.main:app --host 0.0.0.0 --port 8000 diff --git a/app/main.py b/app/main.py index 01be05b..58305cc 100644 --- a/app/main.py +++ b/app/main.py @@ -124,12 +124,12 @@ async def health(): @app.on_event("startup") async def startup(): - """Initialize extensions and run migrations.""" + """Initialize PostGIS/TimescaleDB extensions on first connection. + + Schema migrations are applied by the container entrypoint (alembic upgrade + head) before uvicorn starts, so they don't run nested inside the event loop. + """ await init_extensions() - from alembic import command - from alembic.config import Config - alembic_cfg = Config(str(Path(__file__).parent.parent / "alembic.ini")) - command.upgrade(alembic_cfg, "head") # ── Feed Sources ──────────────────────────────────────────────────────────