Add Docker deployment (build- and stack-tested)
- backend/Dockerfile: gunicorn, not the dev server.
- frontend/Dockerfile: multi-stage, nginx serves the static build.
- nginx.conf proxies /api and /auth to the backend so both services
share one origin - keeps the session cookie simple first-party,
no SameSite=None/CORS complexity in production.
- docker-compose.yml: bind-mounts ./data/{instance,uploads} (not
named volumes) so the sqlite db and uploaded photos are visible
under the project dir; :Z flag for SELinux-enforcing hosts
(Fedora/RHEL) - without it gunicorn fails with "unable to open
database file".
- FRONTEND_PORT env var to pick the exposed port.
- .env.example: documents CORS_ORIGIN is moot in the compose setup
(same-origin via nginx) and that SESSION_COOKIE_SECURE=true needs
a TLS-terminating reverse proxy in front in real deployment.
Verified: both images build clean, full stack up via docker compose,
login flow starts for real against the actual NC instance through
the nginx proxy, sqlite db persists to the bind mount correctly.
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
node_modules/
|
||||
dist/
|
||||
.env
|
||||
@@ -0,0 +1,13 @@
|
||||
FROM node:22-alpine AS build
|
||||
WORKDIR /app
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
COPY . .
|
||||
# VITE_API_BASE_URL is left empty (see .env.example) - nginx below proxies
|
||||
# /api and /auth to the backend on the same origin, so relative paths work.
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:alpine
|
||||
COPY --from=build /app/dist /usr/share/nginx/html
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
EXPOSE 80
|
||||
@@ -0,0 +1,30 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# Receipt photo uploads can be sizeable.
|
||||
client_max_body_size 20m;
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://backend:5000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /auth/ {
|
||||
proxy_pass http://backend:5000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# SPA - anything else falls back to index.html.
|
||||
location / {
|
||||
try_files $uri /index.html;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user