#!/usr/bin/env bash set -euo pipefail umask 002 # so group-writable files end up 664 and dirs 775 (good for volumes) APP_DIR="/app" UPLOADS_DIR="${APP_DIR}/uploads" DATA_DIR="/data" DBFILE="${DATA_DIR}/app.db" INIT_SQL="${APP_DIR}/init_db.sql" FLAG_FILE="/flag.txt" # Create required dirs mkdir -p "${UPLOADS_DIR}" "${DATA_DIR}" # Try to ensure runtime ownership (works for named volumes; bind-mounts may ignore) chown -R ctfuser:ctfuser "${UPLOADS_DIR}" "${APP_DIR}" 2>/dev/null || true chown -R ctfuser:ctfuser "${DATA_DIR}" 2>/dev/null || true # Minimum perms so SQLite can create -wal/-shm alongside the DB chmod 775 "${DATA_DIR}" || true chmod 775 "${UPLOADS_DIR}" || true # Initialize database as ctfuser so the file is owned/writable by the app user if [ ! -f "${DBFILE}" ]; then echo "Initializing database at ${DBFILE}..." # ensure parent dir writable if [ ! -w "${DATA_DIR}" ]; then echo "WARN: ${DATA_DIR} is not writable by root; continuing…" fi # create empty DB as ctfuser (so ownership is correct), then run schema su -s /bin/bash -c "touch '${DBFILE}'" ctfuser || true # permissions suitable for SQLite + group access chmod 664 "${DBFILE}" || true # run schema if present if [ -f "${INIT_SQL}" ]; then su -s /bin/bash -c "sqlite3 '${DBFILE}' < '${INIT_SQL}'" ctfuser fi fi # (Optional) If your host FS hates WAL, uncomment these lines to switch to DELETE mode on first run # su -s /bin/bash -c "sqlite3 '${DBFILE}' 'PRAGMA journal_mode=DELETE; PRAGMA synchronous=NORMAL;'" ctfuser || true # Environment for Flask (your app still runs via python app.py) export FLASK_APP="${APP_DIR}/app.py" export FLASK_ENV=production # Start SSH (Debian slim may not have full init; fall back to raw sshd) if command -v service >/dev/null 2>&1; then service ssh start || /usr/sbin/sshd & else /usr/sbin/sshd & fi # Handle flag (keep owned by root, world-readable OK for CTF unless you want to restrict) if [ "${FLAG:-}" != "" ]; then echo "$FLAG" > "${FLAG_FILE}" chown root:root "${FLAG_FILE}" || true chmod 644 "${FLAG_FILE}" || true fi echo "Starting Flask app (port 8000) as ctfuser…" # Final sanity: make sure runtime dirs stay writable for WAL/SHM/uploads chmod g+w "${DATA_DIR}" "${UPLOADS_DIR}" 2>/dev/null || true # Exec the app as ctfuser exec su -s /bin/bash -c "cd '${APP_DIR}' && python3 app.py" ctfuser