The frontend calls the API with relative paths (fetch('/api/...')), so in
production those requests hit the nginx frontend container on :8080 — which
previously only served the SPA and would 404 every API call and WebSocket
route. nginx.conf now proxies /api/ to the archnest-backend service with
WebSocket upgrade support, long timeouts for terminals/tunnels/transfers, and
a 1GB body limit matching the backend's upload cap.
The backend Dockerfile now installs python3/make/g++ in both the build and
runtime stages so the native modules (better-sqlite3, ssh2, node-pty) compile
on alpine instead of crashing the container at startup.
The deploy workflow gains a validate job (type-check + build both apps before
touching the host), a pre-flight check that refuses to deploy without the
host-side .env, and a post-deploy health check against /api/health and the
frontend, with concurrency guarding.
20 lines
667 B
Docker
20 lines
667 B
Docker
FROM node:22-alpine AS build
|
|
WORKDIR /app
|
|
# Native modules (better-sqlite3, ssh2, node-pty) need a toolchain to compile.
|
|
RUN apk add --no-cache python3 make g++
|
|
COPY package.json package-lock.json* ./
|
|
RUN npm install --omit=dev=false
|
|
COPY . .
|
|
RUN npm run build
|
|
|
|
FROM node:22-alpine
|
|
WORKDIR /app
|
|
ENV NODE_ENV=production
|
|
# Toolchain is needed again here: production deps are reinstalled fresh, and the
|
|
# native modules (better-sqlite3, ssh2, node-pty) compile from source on install.
|
|
RUN apk add --no-cache python3 make g++
|
|
COPY package.json package-lock.json* ./
|
|
RUN npm install --omit=dev
|
|
COPY --from=build /app/dist ./dist
|
|
EXPOSE 4000
|
|
CMD ["node", "dist/server.js"]
|