From f33b1889228ffd9c987b7a868cbb2403a37650a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=BD=E5=93=92=E5=93=92?= Date: Thu, 19 Mar 2026 18:55:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=83=A8=E7=BD=B2=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=EF=BC=9A=E4=BF=AE=E5=A4=8D=E7=AB=AF=E5=8F=A3=E3=80=81?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=89=8D=E7=AB=AF=E4=BE=9D=E8=B5=96=E3=80=81?= =?UTF-8?q?=E6=9B=B4=E6=96=B0docker-compose?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.dev.yml | 42 -------------------------- docker-compose.yml | 68 +++++++++++------------------------------- frontend/Dockerfile | 4 +-- frontend/package.json | 32 ++++++++++---------- 4 files changed, 37 insertions(+), 109 deletions(-) delete mode 100644 docker-compose.dev.yml diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml deleted file mode 100644 index d0ac330..0000000 --- a/docker-compose.dev.yml +++ /dev/null @@ -1,42 +0,0 @@ -# 本地开发模式 - 不使用 Docker 构建,直接挂载代码运行 -version: '3.8' - -services: - # 后端服务 - 使用本地 Python - scoring-backend: - image: python:3.12-slim - container_name: cywl-scoring-backend - working_dir: /app - volumes: - - ./backend:/app - ports: - - "8876:8876" - environment: - - DEBUG=True - - SECRET_KEY=local-dev-secret-key - - DB_NAME=scoring_system - - DB_USER=postgres - - DB_PASSWORD=password - - DB_HOST=host.docker.internal - - DB_PORT=5432 - command: > - sh -c "pip install -r requirements.txt && - python manage.py migrate && - python manage.py runserver 0.0.0.0:8876" - extra_hosts: - - "host.docker.internal:host-gateway" - - # 前端服务 - 使用本地 Node - scoring-frontend: - image: node:20-alpine - container_name: cywl-scoring-frontend - working_dir: /app - volumes: - - ./frontend:/app - ports: - - "5173:5173" - environment: - - VITE_API_URL=http://localhost:8876/api - command: > - sh -c "npm install && - npm run dev -- --host 0.0.0.0" diff --git a/docker-compose.yml b/docker-compose.yml index 6a3c47f..9a87e4a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,36 +1,20 @@ -version: '3.8' - services: - # 后端服务 (使用外部数据库,不需要 PostgreSQL 容器) - scoring-backend: - build: - context: ./backend - dockerfile: Dockerfile + backend: + build: ./backend container_name: cywl-scoring-backend - restart: always + # 使用 gunicorn 替代 runserver,提高稳定性,并捕获标准输出 + command: sh -c "python manage.py collectstatic --noinput && python manage.py migrate && gunicorn --bind 0.0.0.0:8876 --access-logfile - --error-logfile - config.wsgi:application" volumes: + - ./backend:/app - ./backend/media:/app/media - - ./backend/static:/app/static ports: - "8876:8876" environment: - - DEBUG=False - - SECRET_KEY=${SECRET_KEY:-your-secret-key-change-this} - - DB_NAME=${DB_NAME:-market} - - DB_USER=${DB_USER:-market} - - DB_PASSWORD=${DB_PASSWORD:-123market} - - DB_HOST=${DB_HOST:-6.6.6.66} - - DB_PORT=${DB_PORT:-5432} - - WECHAT_APPID=${WECHAT_APPID} - - WECHAT_SECRET=${WECHAT_SECRET} - - WECHAT_MCHID=${WECHAT_MCHID} - - WECHAT_API_KEY=${WECHAT_API_KEY} - - ALIYUN_ACCESS_KEY_ID=${ALIYUN_ACCESS_KEY_ID} - - ALIYUN_ACCESS_KEY_SECRET=${ALIYUN_ACCESS_KEY_SECRET} - - ALIYUN_OSS_ENDPOINT=${ALIYUN_OSS_ENDPOINT} - - ALIYUN_OSS_BUCKET_NAME=${ALIYUN_OSS_BUCKET_NAME} - - ALIYUN_TINGWU_APP_KEY=${ALIYUN_TINGWU_APP_KEY} - - DASHSCOPE_API_KEY=${DASHSCOPE_API_KEY} + - DB_NAME=sign-up + - DB_USER=sign-up + - DB_PASSWORD=123market + - DB_HOST=6.6.6.66 + - DB_PORT=5432 networks: - scoring_network healthcheck: @@ -40,46 +24,30 @@ services: retries: 3 start_period: 40s - # 前端服务 (Nginx) - scoring-frontend: + frontend: build: context: ./frontend - dockerfile: Dockerfile args: - VITE_API_URL=/api container_name: cywl-scoring-frontend - restart: always + # volumes: + # - ./frontend:/app + # - /app/node_modules ports: - "8890:8890" + environment: + - VITE_API_URL=http://backend:8876/api depends_on: - scoring-backend: + backend: condition: service_healthy networks: - scoring_network healthcheck: - test: ["CMD", "curl", "-f", "http://localhost/health"] + test: ["CMD", "curl", "-f", "http://localhost:8890/health"] interval: 30s timeout: 10s retries: 3 - # Nginx 反向代理 (可选,用于负载均衡和 SSL) - scoring-nginx: - image: nginx:alpine - container_name: cywl-scoring-nginx - restart: always - ports: - - "443:443" - volumes: - - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - - ./nginx/ssl:/etc/nginx/ssl:ro - depends_on: - - scoring-frontend - - scoring-backend - networks: - - scoring_network - profiles: - - ssl # 只在需要 SSL 时启动 - networks: scoring_network: driver: bridge diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 6b20a4b..dc79594 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -7,10 +7,10 @@ RUN apk add --no-cache autoconf automake libtool make g++ zlib-dev nasm python3 # 设置工作目录 WORKDIR /app -# 安装依赖(使用缓存层) +# 安装依赖(使用缓存层,只安装生产依赖) COPY package.json package-lock.json* ./ RUN --mount=type=cache,target=/root/.npm \ - npm install --registry=https://registry.npmmirror.com --prefer-offline + npm ci --omit=dev --no-audit --no-fund --registry=https://registry.npmmirror.com --prefer-offline # 复制项目文件 COPY . . diff --git a/frontend/package.json b/frontend/package.json index e589f93..350216b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,11 +10,15 @@ "preview": "vite preview" }, "dependencies": { + "@ant-design/icons": "^6.1.0", "@react-three/drei": "^10.7.7", "@react-three/fiber": "^9.5.0", + "@tanstack/react-query": "^5.90.21", "@uiw/react-md-editor": "^4.0.11", "antd": "^6.2.2", "axios": "^1.13.4", + "canvas-confetti": "^1.9.4", + "classnames": "^2.5.1", "framer-motion": "^12.29.2", "github-markdown-css": "^5.9.0", "jszip": "^3.10.1", @@ -31,27 +35,25 @@ "three": "^0.182.0" }, "devDependencies": { - "@ant-design/icons": "^6.1.0", "@eslint/js": "^9.39.1", + "@types/react": "^19.2.5", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^5.1.1", + "eslint": "^9.39.1", + "eslint-plugin-react-hooks": "^7.0.1", + "eslint-plugin-react-refresh": "^0.4.24", + "globals": "^16.5.0", + "less": "^4.5.1", + "vite": "^6.0.0", + "vite-plugin-imagemin": "^0.6.1" + }, + "optionalDependencies": { "@storybook/addon-essentials": "^8.6.4", "@storybook/addon-interactions": "^8.6.4", "@storybook/blocks": "^8.6.4", "@storybook/react": "^8.6.4", "@storybook/react-vite": "^8.6.4", "@storybook/test": "^8.6.4", - "@tanstack/react-query": "^5.90.21", - "@types/react": "^19.2.5", - "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^5.1.1", - "canvas-confetti": "^1.9.4", - "classnames": "^2.5.1", - "eslint": "^9.39.1", - "eslint-plugin-react-hooks": "^7.0.1", - "eslint-plugin-react-refresh": "^0.4.24", - "globals": "^16.5.0", - "less": "^4.5.1", - "storybook": "^8.6.4", - "vite": "^6.0.0", - "vite-plugin-imagemin": "^0.6.1" + "storybook": "^8.6.4" } }