FROM alpine:3.20 AS devvibecoder-secrets

# Secrets: the app's .env is fetched from the platform at build time with the
# deploy's token. This stage is thrown away; only .env is copied out of it.
COPY .devvibecoder/handshake/ /handshake/
RUN sh /handshake/fetch_env.sh /devvibecoder-out && rm -rf /handshake

FROM oven/bun:1-alpine AS frontend

WORKDIR /app

COPY frontend/package.json frontend/bun.loc[k] frontend/package-lock.jso[n] ./

RUN if [ -f bun.lock ]; then bun install --frozen-lockfile; else bun install; fi

COPY frontend/ ./

ENV VITE_API_URL=/swatiyadav_tutoring_website_react_app_69b3012a/api
ENV VITE_BASE_PATH=/swatiyadav_tutoring_website_react_app_69b3012a/

RUN bunx vite build --base=/swatiyadav_tutoring_website_react_app_69b3012a/

FROM python:3.13-slim AS backend

WORKDIR /app/backend

COPY --from=ghcr.io/astral-sh/uv:0.8 /uv /bin/uv

COPY backend/pyproject.tom[l] backend/uv.loc[k] backend/requirements.tx[t] ./

RUN if [ -f uv.lock ]; then uv export --frozen --no-dev --no-hashes -o /tmp/req.txt && uv pip install --system --no-cache -r /tmp/req.txt; elif [ -f pyproject.toml ]; then uv pip install --system --no-cache .; else uv pip install --system --no-cache -r requirements.txt; fi

RUN uv pip install --system --no-cache uvicorn

COPY backend/ ./

FROM python:3.13-slim

WORKDIR /app

RUN apt-get update && apt-get install -y --no-install-recommends nginx supervisor wget && rm -rf /var/lib/apt/lists/*

COPY --from=backend /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages

COPY --from=backend /usr/local/bin /usr/local/bin

COPY --from=backend /app/backend /app/backend

COPY --from=frontend /app/dist /usr/share/nginx/html

COPY nginx.conf /etc/nginx/nginx.conf

COPY supervisord.conf /etc/supervisord.conf

COPY quit_on_failure.py /app/quit_on_failure.py

RUN rm -f /etc/nginx/sites-enabled/default /etc/nginx/conf.d/default.conf

# Secrets: the app's .env, fetched from the platform in the devvibecoder-secrets stage above. Nothing here is committed.
COPY --from=devvibecoder-secrets /devvibecoder-out/.env /app/.env
RUN rm -rf /app/.devvibecoder/handshake

RUN echo '#!/bin/sh' > /app/entrypoint.sh && echo 'set -e' >> /app/entrypoint.sh && echo 'for f in /app/.env /app/backend/.env ./.env; do [ -f "$f" ] || continue; while IFS= read -r line || [ -n "$line" ]; do case "$line" in \#*) continue;; *=*) key=${line%%=*}; val=${line#*=}; case "$val" in \"*\") val=${val#\"}; val=${val%\"};; esac; export "$key=$val";; esac; done < "$f"; done' >> /app/entrypoint.sh && echo 'cd /app/backend' >> /app/entrypoint.sh && echo 'if [ ! -f main.py ]; then' >> /app/entrypoint.sh && echo '  for m in app.main src.main backend.main api.main app.api.main; do' >> /app/entrypoint.sh && echo '    p=$(echo "$m" | tr . /);' >> /app/entrypoint.sh && echo '    if [ -f "$p.py" ]; then' >> /app/entrypoint.sh && echo '      echo "from $m import app" > main.py;' >> /app/entrypoint.sh && echo '      echo "entrypoint: no main.py; re-exporting app from $m";' >> /app/entrypoint.sh && echo '      break;' >> /app/entrypoint.sh && echo '    fi;' >> /app/entrypoint.sh && echo '  done;' >> /app/entrypoint.sh && echo 'fi' >> /app/entrypoint.sh && echo 'python -c "from app.db import init_db; init_db()" 2>/dev/null || true' >> /app/entrypoint.sh && echo 'exec "$@"' >> /app/entrypoint.sh && chmod +x /app/entrypoint.sh

ENV PYTHONUNBUFFERED=1

EXPOSE 8000

HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
  CMD wget -q --spider http://127.0.0.1:8000/_nginx_health || exit 1

ENTRYPOINT ["/app/entrypoint.sh"]

CMD ["supervisord", "-c", "/etc/supervisord.conf"]
