startweb-docker.sh
Rama main · réplica de lectura del repositorio original.
#!/bin/bash
# Docker-specific startup script for Oneirodex
# This script is designed to run inside the Docker container
set -e
# Parse arguments
FORCE_SETUP=false
if [[ "$1" == "--force-setup" || "$1" == "-fs" ]]; then
FORCE_SETUP=true
fi
# We're already in /app directory in Docker, no need to cd
PORT="${PORT:-5006}"
python3 -m scripts.startup_art splash
if [[ "$FORCE_SETUP" == "true" ]]; then
echo "🔄 Force setup mode - resetting database..."
# Load environment for standalone execution
python3 -c "
from dotenv import load_dotenv
load_dotenv()
from oneirodex import create_app, db
from oneirodex.utils.setup import reset_setup_state
# Create app and reset database
app = create_app()
with app.app_context():
print('Dropping all tables...')
db.drop_all()
print('Recreating all tables...')
db.create_all()
print('Database reset complete.')
reset_setup_state()
print('Setup state reset - setup wizard will run on next startup')
print('Database reset complete. Restart the container to start the server.')
"
exit 0
fi
STARTUP_STORY_CLOSED=false
close_startup_story() {
local status="$1"
if [[ "$STARTUP_STORY_CLOSED" != "true" ]]; then
STARTUP_STORY_CLOSED=true
python3 -c "from oneirodex.init_manager import print_startup_epilogue; print_startup_epilogue($status == 0)"
fi
}
trap 'close_startup_story $?' EXIT
echo "ONEI > The launch gate is coming online on port $PORT."
# The public preview keeps its redistributable sample ROMs on the configured
# persistent library volume. DATA_FOLDER_GAMES is also the app's safe download
# allowlist for the /api/downloadrom route.
if [[ "${ONEIRODEX_PUBLIC_DEMO:-false}" == "true" ]]; then
DEMO_LIBRARY_DIR="${ONEIRODEX_LIBRARY_DIR:-/config/library}"
export DATA_FOLDER_GAMES="${DATA_FOLDER_GAMES:-${DEMO_LIBRARY_DIR}/demo-games}"
fi
# Run complete startup initialization once before starting workers
if python3 -c "
from oneirodex.init_manager import run_complete_startup_initialization
import sys; sys.exit(0 if run_complete_startup_initialization() else 1)
"; then
:
else
INIT_STATUS=$?
exit "$INIT_STATUS"
fi
# Render's free Docker service supplies PORT at runtime. The public demo uses
# the same image and keeps the normal Compose/Unraid port unchanged otherwise.
if [[ "${ONEIRODEX_PUBLIC_DEMO:-false}" == "true" ]]; then
printf '\nQUEST BONUS // Gather the public demo field kit for the new camp...\n'
if ! PYTHONPATH=/app python3 /app/scripts/fetch-free-roms.py \
--out "${DATA_FOLDER_GAMES}" \
--id nestest --id dmg-acid2 --id cascade7 --id genmddj --id atari2600-4paddle-tester; then
echo "FIELD NOTE // some demo samples were unavailable; available samples will still be seeded."
fi
# Executing a file under /app/scripts puts that directory, not /app, at
# sys.path[0]. Add the application root so the seed can import oneirodex.
PYTHONPATH=/app python3 /app/scripts/seed_public_demo.py
fi
close_startup_story 0
trap - EXIT
# Ensure environment variables are set for worker processes
export ONEIRODEX_MIGRATIONS_COMPLETE=true
export ONEIRODEX_INITIALIZATION_COMPLETE=true
# Start uvicorn for Docker (bind to all interfaces).
# Default 1 worker — SSE/schedulers, cache, login rate limit, and EventBus stay
# single-process. Override UVICORN_WORKERS=2+ only when you accept per-worker state
# (or after a shared cache lands).
WORKERS="${UVICORN_WORKERS:-1}"
exec uvicorn asgi:asgi_app --host 0.0.0.0 --port "$PORT" --workers "$WORKERS" --no-proxy-headers --timeout-graceful-shutdown "${UVICORN_GRACEFUL_TIMEOUT:-5}"