fix: ensure data persistence across reinstallations

- Add entrypoint.sh: creates /app/data, stamps legacy DBs, runs alembic upgrade head
- Update Dockerfile to use new entrypoint and pre-create /app/data
- Change default DATABASE_URL to sqlite:///./data/dmarq.db
- Add _ensure_sqlite_dir() to database.py for automatic directory creation
- Update docker-compose.yml with app_data named volume for /app/data
- Add 6 tests for _ensure_sqlite_dir and updated default URL

Agent-Logs-Url: https://github.com/christianlouis/dmarq/sessions/2bac317b-97a2-450b-84f1-3e316f7ef54c

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-29 18:53:00 +00:00
parent 7c471b2800
commit 423c596c28
6 changed files with 139 additions and 5 deletions
+57
View File
@@ -0,0 +1,57 @@
#!/bin/sh
# entrypoint.sh prepare the database and start the application.
#
# Responsibilities:
# 1. Create the data directory so SQLite can write its file there.
# 2. Ensure Alembic migration tracking is consistent (stamp existing
# databases that were created before Alembic was introduced).
# 3. Apply all pending Alembic migrations (alembic upgrade head).
# 4. Hand off to the real application process.
set -e
DATA_DIR="${DATA_DIR:-/app/data}"
mkdir -p "$DATA_DIR"
echo "==> Running database migrations …"
# If the database already has tables but no alembic_version table (i.e. it
# was bootstrapped via SQLAlchemy create_all before this entrypoint was
# introduced), stamp it at the current head so that subsequent 'upgrade head'
# calls are no-ops rather than errors.
python - <<'PYEOF'
import sys
try:
from sqlalchemy import inspect, text
from app.core.database import engine
with engine.connect() as conn:
insp = inspect(conn)
tables = insp.get_table_names()
if "alembic_version" not in tables and tables:
import subprocess
print(
"WARNING: database has tables but no alembic_version "
"stamping head to record current schema state."
)
result = subprocess.run(
["alembic", "stamp", "head"],
capture_output=True,
text=True,
)
if result.returncode != 0:
print("ERROR: alembic stamp failed:", result.stderr, file=sys.stderr)
sys.exit(1)
print(result.stdout)
except Exception as exc: # noqa: BLE001
# If we cannot connect at all (e.g. Postgres not ready yet), let
# 'alembic upgrade head' handle the error with a clear message.
print(f"WARNING: pre-migration inspection skipped: {exc}")
PYEOF
alembic upgrade head
echo "==> Migrations complete."
echo "==> Starting application …"
exec uvicorn app.main:app --host 0.0.0.0 --port "${PORT:-8080}"