botsuit / Dockerfile
Gacirane Patrick
update
742def5
Raw
History Blame Contribute Delete
3.87 kB
# =============================================================================
# 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"]