#!/usr/bin/env bash # ============================================================================= # Container entrypoint. # # Waits for the dependencies the API cannot start without, applies migrations, # and optionally seeds the dataset - all guarded by environment flags so a # production deploy can opt out of every side effect. # ============================================================================= set -Eeuo pipefail log() { printf '{"level":"INFO","logger":"entrypoint","message":"%s"}\n' "$1"; } fail() { printf '{"level":"ERROR","logger":"entrypoint","message":"%s"}\n' "$1" >&2; exit 1; } wait_for() { local name="$1" host="$2" port="$3" attempts="${4:-60}" log "waiting for ${name} at ${host}:${port}" for _ in $(seq 1 "${attempts}"); do if (echo > "/dev/tcp/${host}/${port}") >/dev/null 2>&1; then log "${name} is reachable" return 0 fi sleep 2 done fail "${name} did not become reachable at ${host}:${port}" } : "${POSTGRES_HOST:=postgres}" : "${POSTGRES_PORT:=5432}" : "${RUN_MIGRATIONS:=true}" : "${SEED_DATASET:=false}" : "${SEED_USERS:=false}" : "${WAIT_FOR_ELASTICSEARCH:=true}" wait_for "postgres" "${POSTGRES_HOST}" "${POSTGRES_PORT}" if [[ "${SEARCH_BACKEND:-elasticsearch}" == "elasticsearch" && "${WAIT_FOR_ELASTICSEARCH}" == "true" ]]; then wait_for "elasticsearch" "${ELASTICSEARCH_HOST:-elasticsearch}" "${ELASTICSEARCH_PORT:-9200}" 90 fi if [[ "${RUN_MIGRATIONS}" == "true" ]]; then log "applying database migrations" python manage.py migrate --noinput fi if [[ "${SEED_USERS}" == "true" ]]; then log "seeding demo users" python manage.py seed_users fi # Importing ~300 profiles takes a few seconds and is idempotent, but it is still # opt-in so restarting a production container never touches the data. if [[ "${SEED_DATASET}" == "true" ]]; then if python manage.py shell -c " import sys from apps.profiles.models import Profile sys.exit(0 if Profile.objects.exists() else 1) " >/dev/null 2>&1; then log "dataset already present, skipping import" else log "importing dataset" python manage.py import_profiles fi if [[ "${SEARCH_BACKEND:-elasticsearch}" == "elasticsearch" ]]; then log "building the search index" python manage.py search_index --rebuild fi fi log "starting: $*" exec "$@"