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:
parent
0445fdba19
commit
1e6e41e426
39
Dockerfile
39
Dockerfile
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ services:
|
|||
build: .
|
||||
container_name: legco_reranker
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "8000:8000"
|
||||
env_file:
|
||||
- ./backend/.env
|
||||
|
|
|
|||
13
nginx.conf
13
nginx.conf
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Loading…
Reference in New Issue