diff --git a/.env.example b/.env.example index f3e25f3..37a2904 100644 --- a/.env.example +++ b/.env.example @@ -14,4 +14,7 @@ ROMS_PATH=/path/to/your/roms # These are automatically derived from DOSFRONTEND_CONFIG_DIR in Docker # DOSVAULT_HOST=localhost # DOSVAULT_PORT=8080 -# DOSVAULT_WEBSOCKET_PORT=8081 \ No newline at end of file +# DOSVAULT_WEBSOCKET_PORT=8081 +# DOSVAULT_ADMIN_USERNAME=admin +# DOSVAULT_ADMIN_EMAIL=admin@dos.vault +# DOSVAULT_ADMIN_PASSWORD=admin diff --git a/DOCKER.md b/DOCKER.md index 90e12b6..5061537 100644 --- a/DOCKER.md +++ b/DOCKER.md @@ -10,6 +10,9 @@ 2. **Edit `.env` with your configuration:** - Set `IGDB_CLIENT_ID` and `IGDB_SECRET_KEY` (required) - Set `ROMS_PATH` to your ROM collection directory + - Set `DOSVAULT_ADMIN_USERNAME` to you admin username + - Set `DOSVAULT_ADMIN_EMAIL` to your admin email + - Set `DOSVAULT_ADMIN_PASSWORD` to your admin password - Optionally customize host/port settings 3. **Start the application:** @@ -58,7 +61,7 @@ Configuration changes made through the web interface are automatically persisted ### Initialize Database ```bash -docker-compose exec dosvault python src/migrate.py db-init +docker-compose exec dosvault python src/migrate.py init ``` ### Run Migrations @@ -106,4 +109,4 @@ docker-compose exec dosvault bash ```bash docker-compose down -v docker-compose up -d -``` \ No newline at end of file +``` diff --git a/Dockerfile b/Dockerfile index d2c11d4..9b1c0fc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,6 +25,7 @@ COPY templates/ ./templates/ COPY migrations/ ./migrations/ COPY alembic.ini ./ COPY CLAUDE.md README.md ./ +COPY entrypoint.sh ./ # Create necessary directories RUN mkdir -p /app/data/logs /app/data/images /app/data/roms /app/data/metadata @@ -46,5 +47,5 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD curl -f http://localhost:8080/health || exit 1 # Default command -CMD ["python", "src/migrate.py", "init"] -CMD ["python", "-m", "uvicorn", "src.webapp:app", "--host", "0.0.0.0", "--port", "8080"] +# CMD ["python", "-m", "uvicorn", "src.webapp:app", "--host", "0.0.0.0", "--port", "8080"] +ENTRYPOINT ["./entrypoint.sh"] diff --git a/docker-compose.yml b/docker-compose.yml index 7b89800..036c8dc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.8' - services: dosvault: build: . @@ -7,9 +5,7 @@ services: - "8080:8080" - "8081:8081" volumes: - # Mount data directory for persistence - dosvault_data:/app/data - # Mount ROM directory (customize this path) - "${ROMS_PATH:-./roms}:/app/data/roms:ro" environment: # IGDB API Configuration @@ -17,6 +13,9 @@ services: - IGDB_SECRET_KEY=${IGDB_SECRET_KEY} # Application Configuration - DOSFRONTEND_CONFIG_DIR=/app/data + - DOSVAULT_ADMIN_USERNAME=${DOSVAULT_ADMIN_USERNAME:-} + - DOSVAULT_ADMIN_EMAIL=${DOSVAULT_ADMIN_EMAIL:-} + - DOSVAULT_ADMIN_PASSWORD=${DOSVAULT_ADMIN_PASSWORD:-} restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] @@ -27,4 +26,4 @@ services: volumes: dosvault_data: - driver: local \ No newline at end of file + driver: local diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..591e47b --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +set -euo pipefail + +DATA_DIR="${DOSFRONTEND_CONFIG_DIR:-/app/data}" +DB_PATH="${DATA_DIR}/roms.db" + +# Make sure data dir exists & is writable for uid 1000 +mkdir -p "$DATA_DIR" "$DATA_DIR/images" "$DATA_DIR/logs" "$DATA_DIR/roms" "$DATA_DIR/metadata" +# Attempt to fix perms when volume mounted as root +if [ "$(id -u)" -ne 0 ]; then + # we're not root; try a writable touch to detect perms + if ! touch "$DATA_DIR/.permcheck" 2>/dev/null; then + echo "WARNING: $DATA_DIR not writable by current user. Consider running as root or fixing volume ownership." + else + rm -f "$DATA_DIR/.permcheck" + fi +else + chown -R 1000:1000 "$DATA_DIR" || true +fi + +# Initialize / migrate DB +if [ ! -f "$DB_PATH" ]; then + echo "No database found. Initializing…" + python /app/src/migrate.py init || true +fi +# Always try to move to latest +python /app/src/migrate.py upgrade || true + +# Non-interactive admin creation (optional) +if [ "${DOSVAULT_ADMIN_USERNAME:-}" ] && [ "${DOSVAULT_ADMIN_EMAIL:-}" ] && [ "${DOSVAULT_ADMIN_PASSWORD:-}" ]; then +python - <<'PY' +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker +from os import getenv +from libs.config import Config +from libs.database import User_table, UserRole +from libs.auth import AuthManager + +cfg=Config() +engine=create_engine(f"sqlite+pysqlite:///{cfg.database_path}") +Session=sessionmaker(bind=engine) +db=Session() +try: + existing = db.query(User_table).filter(User_table.role==UserRole.SUPER.value).first() + if not existing: + AuthManager.create_user( + db, + getenv("DOSVAULT_ADMIN_USERNAME"), + getenv("DOSVAULT_ADMIN_EMAIL"), + getenv("DOSVAULT_ADMIN_PASSWORD"), + UserRole.SUPER.value + ) + print("Admin user created.") + else: + print(f"Admin already exists: {existing.username}") +finally: + db.close() +PY +fi + +# Run app +exec python -m uvicorn src.webapp:app --host 0.0.0.0 --port 8080 +