Add container entrypoint: wait for DB, create schema, drop privileges
This commit is contained in:
1 parent
333c5143cf
commit
b5aa982794
1 file changed
+80
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env bash
|
||||
# LEGO Instructions Manager - container entrypoint.
|
||||
#
|
||||
# Runs as root just long enough to fix volume ownership, then waits for the
|
||||
# database, creates any missing tables, and drops to the unprivileged user.
|
||||
#
|
||||
# Created by: Jess Rogerson (yelling commands at Claude.AI)
|
||||
set -euo pipefail
|
||||
|
||||
APP_USER=lim
|
||||
|
||||
log() { echo "[entrypoint] $*"; }
|
||||
|
||||
# --- volume ownership -------------------------------------------------------
|
||||
# A freshly created named volume mounts as root:root, so the app user cannot
|
||||
# write to it until we hand it over. Cheap to repeat on every start.
|
||||
if [ "$(id -u)" = '0' ]; then
|
||||
mkdir -p "${UPLOAD_FOLDER:-/data/uploads}" "${BACKUP_FOLDER:-/data/backups}"
|
||||
chown -R "${APP_USER}:${APP_USER}" /data
|
||||
fi
|
||||
|
||||
# --- wait for the database --------------------------------------------------
|
||||
if [ "${DATABASE_URL:-}" != "" ] && [ "${SKIP_DB_WAIT:-0}" != "1" ]; then
|
||||
log "Waiting for database..."
|
||||
for attempt in $(seq 1 60); do
|
||||
if python - <<'PY'
|
||||
import os, sys
|
||||
from sqlalchemy import create_engine, text
|
||||
try:
|
||||
engine = create_engine(os.environ['DATABASE_URL'], pool_pre_ping=True)
|
||||
with engine.connect() as conn:
|
||||
conn.execute(text('SELECT 1'))
|
||||
except Exception as exc:
|
||||
print(f' not ready: {exc.__class__.__name__}', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
PY
|
||||
then
|
||||
log "Database is up."
|
||||
break
|
||||
fi
|
||||
if [ "$attempt" = "60" ]; then
|
||||
log "ERROR: database did not become available in time."
|
||||
exit 1
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
fi
|
||||
|
||||
# --- schema -----------------------------------------------------------------
|
||||
# db.create_all() is additive: it creates missing tables and leaves existing
|
||||
# ones untouched. It does NOT alter columns, so a schema change still needs a
|
||||
# migration — see docs/DOCKER_DEPLOYMENT.md.
|
||||
if [ "${SKIP_DB_INIT:-0}" != "1" ]; then
|
||||
log "Ensuring schema exists..."
|
||||
python - <<'PY'
|
||||
import os
|
||||
from app import create_app, db
|
||||
app = create_app(os.getenv('FLASK_ENV', 'production'))
|
||||
with app.app_context():
|
||||
db.create_all()
|
||||
print('[entrypoint] Schema ready.')
|
||||
PY
|
||||
fi
|
||||
|
||||
# --- hand over --------------------------------------------------------------
|
||||
# Re-chown: create_app() ran as root above and will have created the
|
||||
# uploads subdirectories (pdfs/, images/, covers/, thumbnails/, extra_files/)
|
||||
# owned by root. Without this the app user cannot write uploads.
|
||||
if [ "$(id -u)" = '0' ]; then
|
||||
chown -R "${APP_USER}:${APP_USER}" /data
|
||||
log "Starting as ${APP_USER}: $*"
|
||||
if command -v runuser >/dev/null 2>&1; then
|
||||
exec runuser -u "${APP_USER}" -- "$@"
|
||||
else
|
||||
exec su -s /bin/bash -c 'exec "$0" "$@"' "${APP_USER}" -- "$@"
|
||||
fi
|
||||
fi
|
||||
|
||||
log "Starting: $*"
|
||||
exec "$@"
|
||||
Reference in new issue
Block a user