From 144f994d58f816999968f7da11331519478482d6 Mon Sep 17 00:00:00 2001 From: furyhawk Date: Fri, 12 Jun 2026 19:25:24 +0800 Subject: [PATCH] feat: add Docker configuration for backend and frontend with nginx support --- backend/.dockerignore | 19 +++++++++++++ backend/Dockerfile | 50 +++++++++++++++++++++++++++++++++ docker-compose.yml | 63 ++++++++++++++++++++++++++++++++++++++++++ frontend/.dockerignore | 21 ++++++++++++++ frontend/Dockerfile | 28 +++++++++++++++++++ frontend/nginx.conf | 24 ++++++++++++++++ 6 files changed, 205 insertions(+) create mode 100644 backend/.dockerignore create mode 100644 backend/Dockerfile create mode 100644 docker-compose.yml create mode 100644 frontend/.dockerignore create mode 100644 frontend/Dockerfile create mode 100644 frontend/nginx.conf diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..cb3b412 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,19 @@ +# Python +__pycache__ +*.pyc +*.pyo +.env +.venv +*.egg-info + +# IDE +.idea +.vscode + +# OS +.DS_Store +Thumbs.db + +# Git +.git +.gitignore diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..9cd47e3 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,50 @@ +# ────────────────────────────────────────────────────────────────── +# Backend — Python 3.12 + FastAPI + uv +# ────────────────────────────────────────────────────────────────── +FROM python:3.12-slim AS builder + +# Install uv (fast Python package installer) +COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ + +WORKDIR /app + +# Install system deps needed by some wheels +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + gcc \ + libffi-dev \ + && rm -rf /var/lib/apt/lists/* + +# Copy dependency file first for layer caching +COPY pyproject.toml . +RUN uv sync --no-dev --no-install-project + +# ── Runtime stage ───────────────────────────────────────────────── +FROM python:3.12-slim + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + curl \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ + +WORKDIR /app + +# Copy venv from builder +COPY --from=builder /app/.venv ./.venv + +# Copy application code +COPY backend/ ./backend/ +COPY pyproject.toml . + +# Ensure the .venv/bin is in PATH +ENV PATH="/app/.venv/bin:$PATH" + +EXPOSE 8000 + +# Health check +HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ + CMD curl -f http://localhost:8000/api/health || exit 1 + +CMD ["uvicorn", "backend.app:create_app", "--host", "0.0.0.0", "--port", "8000", "--factory"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..ff0f3e6 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,63 @@ +# ────────────────────────────────────────────────────────────────── +# Agent Alpha — Docker Compose +# +# Usage: +# docker compose up -d # start everything +# docker compose up -d --build # rebuild & start +# docker compose down # stop & remove +# +# Requires: +# - Docker (or Podman with docker-compose compatibility) +# - An OpenAI-compatible LLM endpoint (set LLM_BASE_URL) +# ────────────────────────────────────────────────────────────────── + +services: + # ── FastAPI Backend ───────────────────────────────────────────── + backend: + build: + context: . + dockerfile: backend/Dockerfile + container_name: agent-alpha-backend + ports: + - "8000:8000" + environment: + - LLM_BASE_URL=${LLM_BASE_URL:-http://host.docker.internal:11434/v1} + - LLM_MODEL=${LLM_MODEL:-llama} + restart: unless-stopped + # Uncomment to use a local .env file instead of env vars: + # env_file: + # - .env + extra_hosts: + - "host.docker.internal:host-gateway" + + # ── React Frontend (nginx) ────────────────────────────────────── + frontend: + build: + context: frontend + dockerfile: Dockerfile + container_name: agent-alpha-frontend + ports: + - "5173:80" + depends_on: + - backend + restart: unless-stopped + + # ── Ollama (optional — uncomment to run the LLM locally) ──────── + # ollama: + # image: ollama/ollama:latest + # container_name: ollama + # ports: + # - "11434:11434" + # volumes: + # - ollama_data:/root/.ollama + # restart: unless-stopped + # deploy: + # resources: + # reservations: + # devices: + # - driver: nvidia + # count: all + # capabilities: [gpu] + +# volumes: +# ollama_data: diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..ebf2370 --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,21 @@ +# Dependencies +node_modules + +# Build output +dist + +# IDE +.idea +.vscode + +# OS +.DS_Store +Thumbs.db + +# Git +.git +.gitignore + +# Env +.env +.env.local diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..3f3d52b --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,28 @@ +# ────────────────────────────────────────────────────────────────── +# Frontend — React + Vite build, served via nginx +# ────────────────────────────────────────────────────────────────── +FROM node:20-alpine AS builder + +WORKDIR /app + +# Install dependencies first (layer caching) +COPY package.json package-lock.json* ./ +RUN npm ci + +# Copy source and build +COPY . . +RUN npm run build + +# ── Runtime stage — nginx ───────────────────────────────────────── +FROM nginx:alpine + +# Copy our custom nginx config +COPY nginx.conf /etc/nginx/conf.d/default.conf + +# Copy built assets from builder stage +COPY --from=builder /app/dist /usr/share/nginx/html + +EXPOSE 80 + +HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \ + CMD wget -qO- http://localhost:80/ || exit 1 diff --git a/frontend/nginx.conf b/frontend/nginx.conf new file mode 100644 index 0000000..443b4c5 --- /dev/null +++ b/frontend/nginx.conf @@ -0,0 +1,24 @@ +server { + listen 80; + server_name localhost; + + root /usr/share/nginx/html; + index index.html; + + # ── API proxy ───────────────────────────────────────────────── + location /api/ { + proxy_pass http://backend:8000; + 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; + proxy_read_timeout 120s; + } + + # ── Static files ────────────────────────────────────────────── + location / { + try_files $uri $uri/ /index.html; + expires 1y; + add_header Cache-Control "public, immutable"; + } +}