exocore-docs / Dockerfile
ChoruYt's picture
Update Dockerfile
098c2e3 verified
Raw
History Blame Contribute Delete
3.3 kB
# ──────────────────────────────────────────────────────────────────────────────
# Exocore Docs — production Docker image
#
# Two-stage build:
# 1. Node 20 builds the Vite + React SPA into ./dist
# 2. nginx-alpine serves the static bundle (no Node runtime in the
# final image — keeps it tiny: ~25 MB compressed)
#
# Build:
# docker build -t exocore-docs:latest -f exocore-docs/Dockerfile exocore-docs
#
# Run (host port 8080 → container port 80):
# docker run --rm -p 8080:80 exocore-docs:latest
#
# Hugging Face Spaces: this image works as-is on a "Docker" Space — HF
# expects something on port 7860, so override at run-time:
# docker run -p 7860:7860 -e PORT=7860 exocore-docs:latest
# ──────────────────────────────────────────────────────────────────────────────
# ───── Stage 1: build the SPA ─────
FROM node:20-bookworm-slim AS builder
WORKDIR /build
# Cache npm install on the lockfile.
COPY package*.json ./
RUN npm install --legacy-peer-deps
# Pull in the rest of the project.
COPY tsconfig.json vite.config.ts index.html ./
COPY public ./public
COPY docs ./docs
COPY src ./src
RUN npm run build
# ───── Stage 2: static serve via nginx ─────
FROM nginx:1.27-alpine AS runtime
# Drop the default nginx site and replace it with one that listens on
# $PORT (defaults to 80) and serves the SPA with hash-routing fallback.
RUN rm /etc/nginx/conf.d/default.conf
# Create the templates directory before writing to it
RUN mkdir -p /etc/nginx/templates
# Inline nginx config — kept here so the image is reproducible without
# any extra files outside the Docker build context.
RUN printf '%s\n' \
'server {' \
' listen ${NGINX_PORT};' \
' server_name _;' \
' root /usr/share/nginx/html;' \
' index index.html;' \
'' \
' # Long cache on hashed assets, short cache on the entry HTML.' \
' location /assets/ {' \
' add_header Cache-Control "public, max-age=31536000, immutable";' \
' try_files $uri =404;' \
' }' \
' location /screenshots/ {' \
' add_header Cache-Control "public, max-age=86400";' \
' try_files $uri =404;' \
' }' \
'' \
' # Hash-router SPA fallback — every unknown path returns index.html.' \
' location / {' \
' add_header Cache-Control "no-cache";' \
' try_files $uri $uri/ /index.html;' \
' }' \
'' \
' gzip on;' \
' gzip_types text/plain text/css application/javascript application/json image/svg+xml;' \
' gzip_min_length 1024;' \
'}' \
> /etc/nginx/templates/default.conf.template
COPY --from=builder /build/dist /usr/share/nginx/html
# Default to Hugging Face's required port
ENV PORT=7860
ENV NGINX_PORT=7860
# Expose the exact port Hugging Face looks for
EXPOSE 7860
CMD ["sh", "-c", "export NGINX_PORT=${PORT:-7860}; exec nginx -g 'daemon off;'"]