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
|
FROM python:3.11-slim
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Install system dependencies (ffmpeg for video audio extraction)
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
tini \
|
nginx openssl tini ffmpeg curl \
|
||||||
ffmpeg \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Install Python dependencies
|
|
||||||
COPY backend/requirements.txt ./
|
COPY backend/requirements.txt ./
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
# Copy backend source
|
|
||||||
COPY backend/ ./
|
COPY backend/ ./
|
||||||
|
COPY frontend/dist ./frontend/dist
|
||||||
|
|
||||||
# Copy built frontend from stage 1
|
RUN rm -f /etc/nginx/sites-enabled/default /etc/nginx/conf.d/default.conf
|
||||||
COPY --from=frontend-build /app/frontend/dist ./frontend/dist
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
# Create data directories
|
COPY start.sh /start.sh
|
||||||
RUN mkdir -p /app/chroma_db /app/document_chunk /app/data /app/uploads /app/app/log
|
RUN chmod +x /start.sh
|
||||||
|
|
||||||
# Expose port
|
RUN mkdir -p /app/chroma_db /app/document_chunk /app/data /app/uploads /app/app/log \
|
||||||
EXPOSE 8000
|
/etc/nginx/ssl /var/log/nginx /var/lib/nginx
|
||||||
|
|
||||||
|
EXPOSE 80 443
|
||||||
|
|
||||||
# Use tini as init to handle signals properly
|
|
||||||
ENTRYPOINT ["tini", "--"]
|
ENTRYPOINT ["tini", "--"]
|
||||||
|
CMD ["/start.sh"]
|
||||||
# Start uvicorn
|
|
||||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@ gunzip legco_reranker_amd64.tar.gz
|
||||||
docker load -i legco_reranker_amd64.tar
|
docker load -i legco_reranker_amd64.tar
|
||||||
|
|
||||||
# Run
|
# 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 chroma_data:/app/chroma_db \
|
||||||
-v chunk_data:/app/document_chunk \
|
-v chunk_data:/app/document_chunk \
|
||||||
-v sqlite_data:/app/data \
|
-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`):
|
Before transferring to the server, test the amd64 image locally. Pass all config inline (no `--env-file`):
|
||||||
|
|
||||||
```bash
|
```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_BASE_URL=https://openrouter.ai/api/v1 \
|
||||||
-e LLM_API_KEY=your_key_here \
|
-e LLM_API_KEY=your_key_here \
|
||||||
-e LLM_MODEL_NAME=qwen/qwen3.6-35b-a3b \
|
-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 \
|
-v ~/woody/legco/data/data:/app/data \
|
||||||
legco_reranker:amd64.01.02
|
legco_reranker:amd64.01.02
|
||||||
|
|
||||||
# Verify
|
# Verify (accept self-signed cert with -k)
|
||||||
curl http://localhost:8888/health
|
curl -k https://localhost:8888/health
|
||||||
|
|
||||||
# Clean up
|
# Clean up
|
||||||
docker rm -f legco_test
|
docker rm -f legco_test
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ services:
|
||||||
build: .
|
build: .
|
||||||
container_name: legco_reranker
|
container_name: legco_reranker
|
||||||
ports:
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
env_file:
|
env_file:
|
||||||
- ./backend/.env
|
- ./backend/.env
|
||||||
|
|
|
||||||
13
nginx.conf
13
nginx.conf
|
|
@ -1,6 +1,19 @@
|
||||||
|
# HTTP → HTTPS redirect
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
server_name _;
|
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;
|
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