Skip to content

Commit 738ca8a

Browse files
authored
Start alembic revision history (#240)
* Alembic bootstrap with alembic_version table Signed-off-by: Madhav Kandukuri <[email protected]> * Remove migration dependence Signed-off-by: Madhav Kandukuri <[email protected]>
1 parent 5f84d4d commit 738ca8a

File tree

5 files changed

+67
-27
lines changed

5 files changed

+67
-27
lines changed

alembic/env.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919
# Interpret the config file for Python logging.
2020
# This line sets up loggers basically.
2121
if config.config_file_name is not None:
22-
fileConfig(config.config_file_name)
22+
fileConfig(
23+
config.config_file_name,
24+
disable_existing_loggers=False,
25+
)
2326

2427
# First-Party
2528
# add your model's MetaData object here

docker-compose.yml

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ services:
5858
condition: service_healthy # ▶ wait for DB
5959
redis:
6060
condition: service_started
61-
migration:
62-
condition: service_completed_successfully
61+
# migration:
62+
# condition: service_completed_successfully
6363

6464
healthcheck:
6565
test: ["CMD", "curl", "-f", "http://localhost:4444/health"]
@@ -121,19 +121,19 @@ services:
121121
# volumes: [mongodata:/data/db]
122122
# networks: [mcpnet]
123123

124-
migration:
125-
#image: ghcr.io/ibm/mcp-context-forge:0.2.0 # Use the release MCP Context Forge image
126-
image: mcpgateway/mcpgateway:latest # Use the local latest image. Run `make docker-prod` to build it.
127-
build:
128-
context: .
129-
dockerfile: Containerfile
130-
environment:
131-
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD:-mysecretpassword}@postgres:5432/mcp
132-
command: alembic upgrade head
133-
depends_on:
134-
postgres:
135-
condition: service_healthy
136-
networks: [mcpnet]
124+
# migration:
125+
# #image: ghcr.io/ibm/mcp-context-forge:0.2.0 # Use the release MCP Context Forge image
126+
# image: mcpgateway/mcpgateway:latest # Use the local latest image. Run `make docker-prod` to build it.
127+
# build:
128+
# context: .
129+
# dockerfile: Containerfile
130+
# environment:
131+
# - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD:-mysecretpassword}@postgres:5432/mcp
132+
# command: alembic upgrade head
133+
# depends_on:
134+
# postgres:
135+
# condition: service_healthy
136+
# networks: [mcpnet]
137137

138138
###############################################################################
139139
# CACHE

mcpgateway/bootstrap_db.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# mcpgateway/bootstrap_db.py
2+
# Standard
3+
import asyncio
4+
import logging
5+
from pathlib import Path
6+
7+
# First-Party
8+
from alembic import command
9+
from alembic.config import Config
10+
from mcpgateway.config import settings
11+
from mcpgateway.db import Base
12+
13+
# Third-Party
14+
from sqlalchemy import create_engine, inspect
15+
16+
logger = logging.getLogger(__name__)
17+
18+
19+
async def main():
20+
"""
21+
Bootstrap or upgrade the database schema, then log readiness.
22+
23+
Runs `create_all()` + `alembic stamp head` on an empty DB, otherwise just
24+
executes `alembic upgrade head`, leaving application data intact.
25+
"""
26+
engine = create_engine(settings.database_url)
27+
project_root = Path(__file__).resolve().parents[1]
28+
ini_path = project_root / "alembic.ini"
29+
cfg = Config(ini_path) # path in container
30+
cfg.attributes["configure_logger"] = False
31+
32+
command.ensure_version(cfg)
33+
34+
insp = inspect(engine)
35+
if "gateways" not in insp.get_table_names():
36+
logger.info("Empty DB detected – creating baseline schema")
37+
Base.metadata.create_all(engine)
38+
command.stamp(cfg, "head") # record baseline
39+
else:
40+
command.upgrade(cfg, "head") # apply any new revisions
41+
logger.info("Database ready")
42+
43+
44+
if __name__ == "__main__":
45+
asyncio.run(main())

mcpgateway/main.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@
3535
# First-Party
3636
from mcpgateway import __version__
3737
from mcpgateway.admin import admin_router
38+
from mcpgateway.bootstrap_db import main as bootstrap_db
3839
from mcpgateway.cache import ResourceCache, SessionRegistry
3940
from mcpgateway.config import jsonpath_modifier, settings
40-
from mcpgateway.db import Base, engine, SessionLocal
41+
from mcpgateway.db import SessionLocal
4142
from mcpgateway.handlers.sampling import SamplingHandler
4243
from mcpgateway.schemas import (
4344
GatewayCreate,
@@ -144,7 +145,7 @@
144145
wait_for_db_ready(max_tries=int(settings.db_max_retries), interval=int(settings.db_retry_interval_ms) / 1000, sync=True) # Converting ms to s
145146

146147
# Create database tables
147-
Base.metadata.create_all(bind=engine)
148+
asyncio.run(bootstrap_db())
148149

149150
# Initialize services
150151
tool_service = ToolService()

run-gunicorn.sh

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,6 @@ if [[ "${SSL}" == "true" ]]; then
7474
echo "✓ TLS enabled – using ${CERT_FILE} / ${KEY_FILE}"
7575
fi
7676

77-
# ──────────────────────────────
78-
# Database migrations / checks
79-
# ──────────────────────────────
80-
"${PYTHON}" -m mcpgateway.db
81-
if [[ $? -ne 0 ]]; then
82-
echo "✘ Database migration/check failed. Please resolve issues before starting the server."
83-
exit 1
84-
fi
85-
8677
exec gunicorn -c gunicorn.config.py \
8778
--worker-class uvicorn.workers.UvicornWorker \
8879
--workers "${GUNICORN_WORKERS}" \

0 commit comments

Comments
 (0)