Browse Source

feat: docker-compose 部署

大侠咬超人 4 days ago
parent
commit
f1a9410d97
5 changed files with 86 additions and 14 deletions
  1. 13 0
      Dockerfile
  2. 3 0
      app/Jobs/GenerateExamPdfJob.php
  3. 4 3
      app/Services/ExamPdfExportService.php
  4. 29 0
      docker-compose-back.yml
  5. 37 11
      docker-compose.yml

+ 13 - 0
Dockerfile

@@ -44,8 +44,21 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
         icu-dev \
         icu-dev \
         libzip-dev \
         libzip-dev \
         sqlite-dev \
         sqlite-dev \
+        # Chrome/Chromium 依赖(PDF 生成必须)
+        chromium \
+        nss \
+        freetype \
+        harfbuzz \
+        ttf-freefont \
+        font-noto-cjk \
         && rm -rf /var/cache/apk/*
         && rm -rf /var/cache/apk/*
 
 
+# 设置 Chrome 环境变量
+ENV CHROME_BIN=/usr/bin/chromium-browser \
+    CHROME_PATH=/usr/lib/chromium/ \
+    PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
+    PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
+
 # 安装 PHP 扩展
 # 安装 PHP 扩展
 RUN docker-php-ext-configure gd --with-freetype --with-jpeg && \
 RUN docker-php-ext-configure gd --with-freetype --with-jpeg && \
     docker-php-ext-install -j$(nproc) pdo pdo_mysql pdo_sqlite gd zip intl
     docker-php-ext-install -j$(nproc) pdo pdo_mysql pdo_sqlite gd zip intl

+ 3 - 0
app/Jobs/GenerateExamPdfJob.php

@@ -26,6 +26,9 @@ class GenerateExamPdfJob implements ShouldQueue
     {
     {
         $this->taskId = $taskId;
         $this->taskId = $taskId;
         $this->paperId = $paperId;
         $this->paperId = $paperId;
+
+        // 指定使用 pdf 队列,由独立的 pdf-worker 容器处理
+        $this->onQueue('pdf');
     }
     }
 
 
     public function handle(
     public function handle(

+ 4 - 3
app/Services/ExamPdfExportService.php

@@ -1185,11 +1185,12 @@ class ExamPdfExportService
     {
     {
         $candidates = [
         $candidates = [
             env('PDF_CHROME_BINARY'),
             env('PDF_CHROME_BINARY'),
-            '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
+            env('CHROME_BIN'),  // Docker Alpine 环境变量
+            '/usr/bin/chromium-browser',  // Alpine Linux
+            '/usr/bin/chromium',
             '/usr/bin/google-chrome-stable',
             '/usr/bin/google-chrome-stable',
             '/usr/bin/google-chrome',
             '/usr/bin/google-chrome',
-            '/usr/bin/chromium-browser',
-            '/usr/bin/chromium',
+            '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',  // macOS
         ];
         ];
 
 
         foreach ($candidates as $path) {
         foreach ($candidates as $path) {

+ 29 - 0
docker-compose-back.yml

@@ -0,0 +1,29 @@
+services:
+  filament_admin:
+    build: .
+    container_name: filament_admin
+    command: php artisan serve --host=0.0.0.0 --port=8000
+    ports:
+      - "5019:8000"
+    env_file:
+      - .env
+    volumes:
+      # 持久化存储
+      - ./storage:/app/storage
+      - ./database:/app/database
+    networks:
+      - default
+      - laradock_backend
+    restart: unless-stopped
+    healthcheck:
+      test: ["CMD-SHELL", "php artisan --version || exit 1"]
+      interval: 30s
+      timeout: 10s
+      retries: 3
+      start_period: 40s
+
+networks:
+  default:
+    driver: bridge
+  laradock_backend:
+    external: true

+ 37 - 11
docker-compose.yml

@@ -1,29 +1,55 @@
 services:
 services:
-  filament_admin:
+  # 主应用(Web API 服务)
+  app:
     build: .
     build: .
-    container_name: filament_admin
+    container_name: math_cms_app
     command: php artisan serve --host=0.0.0.0 --port=8000
     command: php artisan serve --host=0.0.0.0 --port=8000
     ports:
     ports:
       - "5019:8000"
       - "5019:8000"
     env_file:
     env_file:
       - .env
       - .env
     volumes:
     volumes:
-      # 持久化存储
-      - ./storage:/app/storage
-      - ./database:/app/database
-    networks:
-      - default
-      - laradock_backend
+      - ./storage:/app/storage  # 日志 + 临时文件 + OCR上传
     restart: unless-stopped
     restart: unless-stopped
     healthcheck:
     healthcheck:
-      test: ["CMD-SHELL", "php artisan --version || exit 1"]
+      test: ["CMD-SHELL", "curl -f http://localhost:8000/health || exit 1"]
       interval: 30s
       interval: 30s
       timeout: 10s
       timeout: 10s
       retries: 3
       retries: 3
       start_period: 40s
       start_period: 40s
 
 
+  # 队列 Worker(通用任务队列)
+  queue:
+    build: .
+    container_name: math_cms_queue
+    command: php artisan queue:work --sleep=3 --tries=3 --max-time=3600
+    env_file:
+      - .env
+    volumes:
+      - ./storage:/app/storage
+    restart: unless-stopped
+    deploy:
+      resources:
+        limits:
+          cpus: '1'
+          memory: 512M
+
+  # PDF 生成专用 Worker(资源隔离,防止 Chrome 吃满 CPU)
+  pdf-worker:
+    build: .
+    container_name: math_cms_pdf
+    command: php artisan queue:work --queue=pdf --sleep=3 --tries=2 --max-time=300 --max-jobs=10
+    env_file:
+      - .env
+    volumes:
+      - ./storage:/app/storage
+    restart: unless-stopped
+    deploy:
+      resources:
+        limits:
+          cpus: '2'
+          memory: 2G
+
 networks:
 networks:
   default:
   default:
     driver: bridge
     driver: bridge
-  laradock_backend:
-    external: true