Fix production deployment: replace serve with nginx reverse proxy

Frontend container now uses nginx to serve static files and proxy
/api/* requests to the backend container internally, eliminating
the hardcoded localhost:8000 build-time URL that caused "Network
error" on any non-local server. CORS origins are also configurable
via ALLOWED_ORIGINS env var.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-06 20:18:38 +02:00
parent a2ca82062e
commit 672f5b74a4
4 changed files with 39 additions and 14 deletions
+9 -1
View File
@@ -1,3 +1,5 @@
import os
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy import text
@@ -9,9 +11,15 @@ Base.metadata.create_all(bind=engine)
app = FastAPI(title="BTC Portfolio API")
_raw_origins = os.environ.get(
"ALLOWED_ORIGINS",
"http://localhost:3000,http://localhost:3001",
)
allowed_origins = [o.strip() for o in _raw_origins.split(",") if o.strip()]
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000", "http://localhost:3001"],
allow_origins=allowed_origins,
allow_credentials=True,
allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
allow_headers=["Content-Type", "Authorization"],
+4 -3
View File
@@ -8,6 +8,7 @@ services:
environment:
- DATABASE_URL=sqlite:////app/data/btc_portfolio.db
- SECRET_KEY=${SECRET_KEY:-dev-insecure-key-change-me}
- ALLOWED_ORIGINS=${ALLOWED_ORIGINS:-http://localhost:3000,http://localhost:3001}
restart: unless-stopped
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/')"]
@@ -20,14 +21,14 @@ services:
build:
context: ./frontend
args:
- REACT_APP_API_URL=http://localhost:8000
- REACT_APP_API_URL=/api
ports:
- "3001:3001"
- "3001:80"
depends_on:
- backend
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3001/"]
test: ["CMD", "wget", "-qO-", "http://localhost:80/"]
interval: 30s
timeout: 10s
retries: 3
+6 -10
View File
@@ -4,16 +4,12 @@ WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
ARG REACT_APP_API_URL=http://localhost:8000
ARG REACT_APP_API_URL=/api
ENV REACT_APP_API_URL=$REACT_APP_API_URL
RUN npm run build
FROM node:18-alpine
RUN npm install -g serve
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --from=build /app/build ./build
RUN chown -R appuser:appgroup /app
USER appuser
EXPOSE 3001
CMD ["serve", "-s", "build", "-l", "3001"]
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
+20
View File
@@ -0,0 +1,20 @@
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
location /api/ {
proxy_pass http://backend:8000/;
proxy_http_version 1.1;
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 / {
try_files $uri $uri/ /index.html;
}
}