Spaces:
Running
Running
| # ============================================================================= | |
| # 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"] |