Production deployment: SSR frontend, Caddy path routing
Update frontend Dockerfile prod stage from Caddy static to Node.js running Astro SSR server. Configure caddy-docker-proxy labels to route /api/* to backend and everything else to frontend on the same domain. Support empty PUBLIC_API_URL for same-origin API calls.
This commit is contained in:
parent
5a2c5730c0
commit
4600a7b0a9
@ -9,6 +9,10 @@ services:
|
||||
networks:
|
||||
- default
|
||||
- caddy
|
||||
labels:
|
||||
caddy: "${SPICEBOOK_DOMAIN:-spicebook.localhost}"
|
||||
caddy.@api.path: "/api/* /health /docs /openapi.json /redoc"
|
||||
caddy.reverse_proxy_0: "@api {{upstreams 8000}}"
|
||||
|
||||
frontend:
|
||||
build:
|
||||
@ -22,7 +26,7 @@ services:
|
||||
- caddy
|
||||
labels:
|
||||
caddy: "${SPICEBOOK_DOMAIN:-spicebook.localhost}"
|
||||
caddy.reverse_proxy: "{{upstreams 4321}}"
|
||||
caddy.reverse_proxy_1: "{{upstreams 4321}}"
|
||||
|
||||
networks:
|
||||
caddy:
|
||||
|
||||
@ -26,23 +26,22 @@ RUN npm run build
|
||||
|
||||
|
||||
# ── Prod stage ───────────────────────────────────────────────────────
|
||||
FROM caddy:2-alpine AS prod
|
||||
FROM node:20-slim AS prod
|
||||
|
||||
COPY --from=build /app/dist /srv
|
||||
WORKDIR /app
|
||||
|
||||
# Simple Caddyfile for serving the static Astro build
|
||||
RUN echo ':4321 {\n\
|
||||
root * /srv\n\
|
||||
encode gzip\n\
|
||||
try_files {path} {path}/index.html /index.html\n\
|
||||
file_server\n\
|
||||
header {\n\
|
||||
X-Content-Type-Options nosniff\n\
|
||||
X-Frame-Options DENY\n\
|
||||
Referrer-Policy strict-origin-when-cross-origin\n\
|
||||
}\n\
|
||||
}' > /etc/caddy/Caddyfile
|
||||
# Copy the built Astro SSR server
|
||||
COPY --from=build /app/dist ./dist
|
||||
COPY --from=build /app/node_modules ./node_modules
|
||||
COPY --from=build /app/package.json ./
|
||||
|
||||
# Run as non-root
|
||||
RUN useradd --create-home --shell /bin/bash astro
|
||||
USER astro
|
||||
|
||||
ENV HOST=0.0.0.0
|
||||
ENV PORT=4321
|
||||
|
||||
EXPOSE 4321
|
||||
|
||||
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile"]
|
||||
CMD ["node", "dist/server/entry.mjs"]
|
||||
|
||||
@ -8,9 +8,10 @@ import type {
|
||||
} from './types';
|
||||
|
||||
const API_BASE = (() => {
|
||||
// In SSR context, import.meta.env may not have PUBLIC_ vars populated the same way.
|
||||
// Prefer the PUBLIC_ env var, fall back to localhost for dev.
|
||||
if (typeof import.meta !== 'undefined' && import.meta.env?.PUBLIC_API_URL) {
|
||||
// PUBLIC_API_URL controls where API requests go:
|
||||
// - Dev (local): 'http://localhost:8099'
|
||||
// - Production: '' (empty = same origin, Caddy routes /api/* to backend)
|
||||
if (typeof import.meta !== 'undefined' && import.meta.env?.PUBLIC_API_URL != null) {
|
||||
return import.meta.env.PUBLIC_API_URL;
|
||||
}
|
||||
return 'http://localhost:8099';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user