feat: HTTPS support with nginx reverse proxy

- Add nginx as reverse proxy (HTTP→HTTPS redirect, self-signed cert)
- start.sh entrypoint: generates SSL cert, starts nginx + uvicorn
- Single-stage Dockerfile (no separate frontend build stage)
- Expose ports 80 and 443 in docker-compose
- Update README port references for HTTPS
This commit is contained in:
Woody 2026-05-18 14:47:22 +08:00
parent 0445fdba19
commit 1e6e41e426
5 changed files with 54 additions and 32 deletions

View File

@ -1,44 +1,27 @@
# Stage 1: Build frontend
FROM node:20-alpine AS frontend-build
WORKDIR /app/frontend
COPY frontend/package.json frontend/package-lock.json ./
RUN npm ci
COPY frontend/ ./
ENV VITE_API_BASE_URL=/api/v1
RUN npm run build
# Stage 2: Production runtime
FROM python:3.11-slim
WORKDIR /app
# Install system dependencies (ffmpeg for video audio extraction)
RUN apt-get update && apt-get install -y --no-install-recommends \
tini \
ffmpeg \
nginx openssl tini ffmpeg curl \
&& rm -rf /var/lib/apt/lists/*
# Install Python dependencies
COPY backend/requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# Copy backend source
COPY backend/ ./
COPY frontend/dist ./frontend/dist
# Copy built frontend from stage 1
COPY --from=frontend-build /app/frontend/dist ./frontend/dist
RUN rm -f /etc/nginx/sites-enabled/default /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Create data directories
RUN mkdir -p /app/chroma_db /app/document_chunk /app/data /app/uploads /app/app/log
COPY start.sh /start.sh
RUN chmod +x /start.sh
# Expose port
EXPOSE 8000
RUN mkdir -p /app/chroma_db /app/document_chunk /app/data /app/uploads /app/app/log \
/etc/nginx/ssl /var/log/nginx /var/lib/nginx
EXPOSE 80 443
# Use tini as init to handle signals properly
ENTRYPOINT ["tini", "--"]
# Start uvicorn
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
CMD ["/start.sh"]

View File

@ -156,7 +156,7 @@ gunzip legco_reranker_amd64.tar.gz
docker load -i legco_reranker_amd64.tar
# Run
docker run -d --name legco -p 80:8000 --env-file backend/.env \
docker run -d --name legco -p 80:80 -p 443:443 --env-file backend/.env \
-v chroma_data:/app/chroma_db \
-v chunk_data:/app/document_chunk \
-v sqlite_data:/app/data \
@ -168,7 +168,7 @@ docker run -d --name legco -p 80:8000 --env-file backend/.env \
Before transferring to the server, test the amd64 image locally. Pass all config inline (no `--env-file`):
```bash
docker run -d --name legco_test -p 8888:8000 \
docker run -d --name legco_test -p 8888:443 \
-e LLM_BASE_URL=https://openrouter.ai/api/v1 \
-e LLM_API_KEY=your_key_here \
-e LLM_MODEL_NAME=qwen/qwen3.6-35b-a3b \
@ -196,8 +196,8 @@ docker run -d --name legco_test -p 8888:8000 \
-v ~/woody/legco/data/data:/app/data \
legco_reranker:amd64.01.02
# Verify
curl http://localhost:8888/health
# Verify (accept self-signed cert with -k)
curl -k https://localhost:8888/health
# Clean up
docker rm -f legco_test

View File

@ -5,6 +5,8 @@ services:
build: .
container_name: legco_reranker
ports:
- "80:80"
- "443:443"
- "8000:8000"
env_file:
- ./backend/.env

View File

@ -1,6 +1,19 @@
# HTTP HTTPS redirect
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
# HTTPS server
server {
listen 443 ssl;
server_name _;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
client_max_body_size 350M;

24
start.sh Normal file
View File

@ -0,0 +1,24 @@
#!/bin/bash
set -e
CERT_DIR="/etc/nginx/ssl"
CERT_FILE="$CERT_DIR/server.crt"
KEY_FILE="$CERT_DIR/server.key"
mkdir -p "$CERT_DIR"
if [ ! -f "$CERT_FILE" ] || [ ! -f "$KEY_FILE" ]; then
echo "Generating self-signed SSL certificate..."
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout "$KEY_FILE" \
-out "$CERT_FILE" \
-subj "/C=HK/ST=HongKong/L=HongKong/O=LegCoReranker/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
echo "Self-signed certificate generated."
fi
echo "Starting nginx..."
nginx
echo "Starting uvicorn..."
exec tini -- uvicorn app.main:app --host 0.0.0.0 --port 8000