# ============================================================================= # Rwanda Co-Regulatory Platform UI — HuggingFace Space (Docker SDK) # ----------------------------------------------------------------------------- # Multi-stage build: # Stage 1 (build) → clone private repo + Maven-build the WAR ONCE, at # image-build time. # Stage 2 (runtime) → lightweight Tomcat that only serves the pre-built WAR. # # ROBUST FRESH-PULL GUARANTEE # --------------------------- # Docker caches the `git clone` layer by instruction text, so rebuilds can # silently reuse OLD code. This file defeats that in TWO independent ways: # # 1. ADD of the GitHub API "commits" endpoint — its response changes # whenever you push a new commit, so Docker's cache for that layer # (and everything after it, including the clone) is invalidated # automatically on every new commit. No manual version bumps. # # 2. A CACHEBUST arg as a manual override you can bump if ever needed. # # Requires a Space SECRET named GITHUB_PAT (repo scope). # ============================================================================= # ---------- Stage 1: build the WAR at image build time ---------- FROM maven:3.9-eclipse-temurin-17 AS build WORKDIR /build # Manual override cache-buster (bump if you ever want to force a clean pull). ARG CACHEBUST=1 # ── AUTOMATIC cache-bust ──────────────────────────────────────────────────── # Pull the latest-commit metadata for the branch BEFORE cloning. This ADD's # content changes with every new commit you push, so Docker invalidates the # clone layer below automatically whenever GitHub has new code. # (Uses the public API path; for a private repo the SHA still changes per commit # and the file content differs, which is all we need to bust the cache.) ADD "https://api.github.com/repos/pgacirane/botdashboard/commits?sha=main&per_page=1" /tmp/latest_commit.json # Clone the private repo using a BuildKit secret mount (token not baked in). # Because the ADD above changes on every push, this RUN re-executes and # fetches your newest code every time. RUN --mount=type=secret,id=GITHUB_PAT \ echo "CACHEBUST=${CACHEBUST}" && \ GITHUB_PAT="$(cat /run/secrets/GITHUB_PAT)" && \ git clone --depth 1 --branch main \ "https://${GITHUB_PAT}@github.com/pgacirane/botdashboard.git" app && \ echo ">>> Cloned commit:" && git -C app rev-parse HEAD WORKDIR /build/app # Build the WAR (fresh compile of the just-pulled code). RUN mvn clean package -DskipTests -q # ---------- Stage 2: lightweight runtime — just Tomcat + the WAR ---------- FROM tomcat:9.0-jdk17 # Remove the default ROOT app so our WAR deploys cleanly at "/" RUN rm -rf /usr/local/tomcat/webapps/ROOT \ /usr/local/tomcat/webapps/ROOT.war # HuggingFace requires the app to listen on port 7860 RUN sed -i 's/port="8080"/port="7860"/' \ /usr/local/tomcat/conf/server.xml # Copy the PRE-BUILT WAR from the build stage → deploy as ROOT (serves at "/") COPY --from=build /build/app/target/*.war /usr/local/tomcat/webapps/ROOT.war # HuggingFace runs the container as UID 1000 — grant write access to Tomcat dirs RUN chmod -R 777 /usr/local/tomcat/webapps \ /usr/local/tomcat/work \ /usr/local/tomcat/temp \ /usr/local/tomcat/logs EXPOSE 7860 # Faster Tomcat startup on containers: # - prefer IPv4 # - non-blocking entropy so SecureRandom (session IDs) doesn't stall on # /dev/random on a fresh container (a common silent startup delay) ENV CATALINA_OPTS="-Djava.security.egd=file:/dev/./urandom -Djava.net.preferIPv4Stack=true" # Container start ONLY launches Tomcat — no clone, no build CMD ["catalina.sh", "run"]