From 880f5caf2dd56ef0d97f8963c38a41ccdfc3127f Mon Sep 17 00:00:00 2001 From: 1iaan Date: Thu, 9 Apr 2026 08:52:40 +0000 Subject: [PATCH] docker --- .dockerignore | 15 +++++++++++++++ README.md | 26 ++++++++++++++++++++++++++ backend/Dockerfile | 20 ++++++++++++++++++++ backend/app/main.py | 8 +++++++- docker-compose.yml | 26 ++++++++++++++++++++++++++ frontend/Dockerfile | 20 ++++++++++++++++++++ frontend/nginx.conf | 29 +++++++++++++++++++++++++++++ frontend/src/App.jsx | 2 +- 8 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 .dockerignore create mode 100644 backend/Dockerfile create mode 100644 docker-compose.yml create mode 100644 frontend/Dockerfile create mode 100644 frontend/nginx.conf diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0226346 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,15 @@ +.git +.gitignore +backend/.venv +backend/__pycache__ +backend/app/__pycache__ +frontend/node_modules +frontend/dist +storage/uploads/* +storage/processed/* +storage/covers/* +storage/hls/* +!storage/uploads/.gitkeep +!storage/processed/.gitkeep +!storage/covers/.gitkeep +!storage/hls/.gitkeep diff --git a/README.md b/README.md index 4b5b7aa..8747a49 100644 --- a/README.md +++ b/README.md @@ -130,13 +130,16 @@ vplatform/ │ │ ├── config.py │ │ ├── main.py │ │ └── schemas.py +│ ├── Dockerfile │ └── requirements.txt ├── frontend/ │ ├── src/ │ │ ├── App.jsx │ │ ├── main.jsx │ │ └── styles.css +│ ├── Dockerfile │ ├── index.html +│ ├── nginx.conf │ ├── package.json │ └── vite.config.js ├── storage/ @@ -144,8 +147,10 @@ vplatform/ │ ├── hls/ │ ├── processed/ │ └── uploads/ +├── .dockerignore ├── .gitignore ├── README.md +├── docker-compose.yml └── prompt.md ``` @@ -194,6 +199,27 @@ npm run dev - 后端:http://localhost:8000 - 健康检查:http://localhost:8000/api/health +## Docker 启动 + +如果你希望在 Ubuntu 24.04 或其他装有 Docker 的环境中快速运行,直接使用: + +```bash +docker compose up --build +``` + +启动后访问: + +- 前端:http://localhost:8080 +- 后端 API:http://localhost:8000 +- 健康检查:http://localhost:8000/api/health + +容器方案说明: + +- 后端镜像基于 `python:3.12-slim`,容器内安装 `ffmpeg` +- 前端镜像采用 Node 构建 + Nginx 静态托管 +- Nginx 会把 `/api` 和 `/media` 反向代理到后端容器 +- `docker-compose.yml` 把宿主机 `./storage` 挂载到容器 `/app/storage`,所以上传文件和处理结果会保留 + ## API 说明 ### `POST /api/upload` diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..e8670d1 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,20 @@ +FROM python:3.12-slim + +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 + +WORKDIR /app/backend + +RUN apt-get update \ + && apt-get install -y --no-install-recommends ffmpeg \ + && rm -rf /var/lib/apt/lists/* + +COPY backend/requirements.txt ./requirements.txt +RUN pip install --no-cache-dir -r requirements.txt + +COPY backend /app/backend +COPY storage /app/storage + +EXPOSE 8000 + +CMD ["python", "-m", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/backend/app/main.py b/backend/app/main.py index a225de9..6ec58cc 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -1,3 +1,4 @@ +import os from typing import Dict, List from fastapi import FastAPI, File, HTTPException, UploadFile @@ -10,10 +11,15 @@ from app.services.storage import get_upload_path, save_upload from app.services.tasks import task_manager +def get_allowed_origins() -> List[str]: + origins = os.getenv("CORS_ORIGINS", "http://localhost:5173,http://localhost:8080") + return [origin.strip() for origin in origins.split(",") if origin.strip()] + + app = FastAPI(title="VPlatform API", version="0.1.0") app.add_middleware( CORSMiddleware, - allow_origins=["http://localhost:5173"], + allow_origins=get_allowed_origins(), allow_credentials=True, allow_methods=["*"], allow_headers=["*"], diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..3df009d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,26 @@ +services: + backend: + build: + context: . + dockerfile: backend/Dockerfile + container_name: vplatform-backend + environment: + CORS_ORIGINS: http://localhost:5173,http://localhost:8080 + ports: + - "8000:8000" + volumes: + - ./storage:/app/storage + restart: unless-stopped + + frontend: + build: + context: . + dockerfile: frontend/Dockerfile + args: + VITE_API_BASE_URL: "" + container_name: vplatform-frontend + depends_on: + - backend + ports: + - "8080:80" + restart: unless-stopped diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..fcfdd7d --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,20 @@ +FROM node:20-alpine AS build + +WORKDIR /app/frontend + +COPY frontend/package*.json ./ +RUN npm install + +COPY frontend /app/frontend + +ARG VITE_API_BASE_URL= +ENV VITE_API_BASE_URL=${VITE_API_BASE_URL} + +RUN npm run build + +FROM nginx:1.27-alpine + +COPY frontend/nginx.conf /etc/nginx/conf.d/default.conf +COPY --from=build /app/frontend/dist /usr/share/nginx/html + +EXPOSE 80 diff --git a/frontend/nginx.conf b/frontend/nginx.conf new file mode 100644 index 0000000..93a5fab --- /dev/null +++ b/frontend/nginx.conf @@ -0,0 +1,29 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + location /api/ { + proxy_pass http://backend:8000/api/; + 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 /media/ { + proxy_pass http://backend:8000/media/; + 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; + } +} diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 4115006..ce4accb 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react' -const API_BASE = 'http://localhost:8000' +const API_BASE = import.meta.env.VITE_API_BASE_URL || '' const defaultForm = { clip_seconds: 8,