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:
|
networks:
|
||||||
- default
|
- default
|
||||||
- caddy
|
- caddy
|
||||||
|
labels:
|
||||||
|
caddy: "${SPICEBOOK_DOMAIN:-spicebook.localhost}"
|
||||||
|
caddy.@api.path: "/api/* /health /docs /openapi.json /redoc"
|
||||||
|
caddy.reverse_proxy_0: "@api {{upstreams 8000}}"
|
||||||
|
|
||||||
frontend:
|
frontend:
|
||||||
build:
|
build:
|
||||||
@ -22,7 +26,7 @@ services:
|
|||||||
- caddy
|
- caddy
|
||||||
labels:
|
labels:
|
||||||
caddy: "${SPICEBOOK_DOMAIN:-spicebook.localhost}"
|
caddy: "${SPICEBOOK_DOMAIN:-spicebook.localhost}"
|
||||||
caddy.reverse_proxy: "{{upstreams 4321}}"
|
caddy.reverse_proxy_1: "{{upstreams 4321}}"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
caddy:
|
caddy:
|
||||||
|
|||||||
@ -26,23 +26,22 @@ RUN npm run build
|
|||||||
|
|
||||||
|
|
||||||
# ── Prod stage ───────────────────────────────────────────────────────
|
# ── 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
|
# Copy the built Astro SSR server
|
||||||
RUN echo ':4321 {\n\
|
COPY --from=build /app/dist ./dist
|
||||||
root * /srv\n\
|
COPY --from=build /app/node_modules ./node_modules
|
||||||
encode gzip\n\
|
COPY --from=build /app/package.json ./
|
||||||
try_files {path} {path}/index.html /index.html\n\
|
|
||||||
file_server\n\
|
# Run as non-root
|
||||||
header {\n\
|
RUN useradd --create-home --shell /bin/bash astro
|
||||||
X-Content-Type-Options nosniff\n\
|
USER astro
|
||||||
X-Frame-Options DENY\n\
|
|
||||||
Referrer-Policy strict-origin-when-cross-origin\n\
|
ENV HOST=0.0.0.0
|
||||||
}\n\
|
ENV PORT=4321
|
||||||
}' > /etc/caddy/Caddyfile
|
|
||||||
|
|
||||||
EXPOSE 4321
|
EXPOSE 4321
|
||||||
|
|
||||||
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile"]
|
CMD ["node", "dist/server/entry.mjs"]
|
||||||
|
|||||||
@ -8,9 +8,10 @@ import type {
|
|||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
const API_BASE = (() => {
|
const API_BASE = (() => {
|
||||||
// In SSR context, import.meta.env may not have PUBLIC_ vars populated the same way.
|
// PUBLIC_API_URL controls where API requests go:
|
||||||
// Prefer the PUBLIC_ env var, fall back to localhost for dev.
|
// - Dev (local): 'http://localhost:8099'
|
||||||
if (typeof import.meta !== 'undefined' && import.meta.env?.PUBLIC_API_URL) {
|
// - 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 import.meta.env.PUBLIC_API_URL;
|
||||||
}
|
}
|
||||||
return 'http://localhost:8099';
|
return 'http://localhost:8099';
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user