Skip to content

Docker 设置

在容器化环境中执行 Artisan 需要正确安装 Chromium,并配置适当的安全与资源参数。本页提供经过生产环境验证的 Dockerfile 与 docker-compose 配置。

Dockerfile

以下 Dockerfile 基于 PHP 官方镜像,安装 Chromium 与所需的中文字体:

dockerfile
FROM php:8.5-fpm-alpine

# 安装 Chromium 与系统依赖
RUN apk add --no-cache \
    chromium \
    nss \
    freetype \
    harfbuzz \
    ca-certificates \
    ttf-freefont

# 安装中文字体(繁体中文支持)
RUN apk add --no-cache font-noto-cjk

# 设置 Chrome 环境变量
ENV CHROME_BIN=/usr/bin/chromium-browser \
    CHROME_PATH=/usr/lib/chromium/ \
    PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true

# 安装 PHP 扩展
RUN docker-php-ext-install opcache

# 复制应用程序
COPY . /var/www/html
WORKDIR /var/www/html

RUN composer install --no-dev --optimize-autoloader

docker-compose.yml

yaml
services:
  app:
    build: .
    volumes:
      - ./storage:/var/www/html/storage
    environment:
      - TCPDF_CHROME_PATH=/usr/bin/chromium-browser
    # Chrome 需要的内核能力
    cap_add:
      - SYS_ADMIN
    # 或者使用 --no-sandbox(见下方安全性说明)
    tmpfs:
      - /tmp:size=512M
    deploy:
      resources:
        limits:
          memory: 1G

Chrome 无头模式启动参数

在容器中执行 Chrome 时,建议使用以下参数:

php
HtmlRenderer::create(chromePath: '/usr/bin/chromium-browser')
    ->chromeArgs([
        '--headless=new',
        '--no-sandbox',
        '--disable-dev-shm-usage',
        '--disable-gpu',
        '--disable-software-rasterizer',
        '--disable-extensions',
        '--disable-background-networking',
        '--single-process',
        '--font-render-hinting=none',
    ]);

参数说明

参数用途
--headless=new使用新版无头模式(Chrome 112+)
--no-sandbox容器内无法使用沙箱,需搭配其他安全措施
--disable-dev-shm-usage避免 /dev/shm 空间不足导致崩溃
--disable-gpu容器通常没有 GPU,停用以减少错误
--single-process减少内存使用,适合单次渲染
--font-render-hinting=none确保跨平台字体渲染一致性

安全性考量

WARNING

--no-sandbox 会停用 Chrome 的沙箱保护。在生产环境中,请搭配以下措施:

  1. 以非 root 用户执行 Chrome — 在 Dockerfile 中创建专用用户:
dockerfile
RUN addgroup -S chrome && adduser -S chrome -G chrome
USER chrome
  1. 使用 SYS_ADMIN 能力代替 --no-sandbox — 如果你的部署环境允许:
yaml
cap_add:
  - SYS_ADMIN
# 此时可移除 --no-sandbox 参数
  1. 限制网络访问 — 如果不需要从外部 URL 加载内容,限制 Chrome 只能访问本地资源。

内存管理

Chrome 渲染会消耗大量内存,特别是渲染复杂页面时。建议:

  • 容器内存限制: 至少 512MB,建议 1GB 以上。
  • tmpfs 挂载:/tmp 挂载为 tmpfs,提升临时文件的读写速度。
  • --disable-dev-shm-usage Docker 默认的 /dev/shm 只有 64MB,此参数让 Chrome 改用 /tmp
yaml
deploy:
  resources:
    limits:
      memory: 1G
    reservations:
      memory: 512M
tmpfs:
  - /tmp:size=512M

字体安装

PDF 的中文显示取决于容器中是否安装了对应的字体:

dockerfile
# Alpine — Noto CJK 字体(涵盖繁体中文、简体中文、日文、韩文)
RUN apk add --no-cache font-noto-cjk

# Debian/Ubuntu — 同上
RUN apt-get update && apt-get install -y fonts-noto-cjk && rm -rf /var/lib/apt/lists/*

如果需要使用自定义字体,将字体文件复制到容器中并更新字体缓存:

dockerfile
COPY ./fonts/*.ttf /usr/share/fonts/custom/
RUN fc-cache -f -v

生产环境检查清单

部署前请确认以下各项:

  • [ ] Chromium 可正常执行 — chromium-browser --version
  • [ ] 中文字体已安装 — fc-list :lang=zh
  • [ ] 内存限制已设置 — 建议至少 1GB
  • [ ] 非 root 用户执行
  • [ ] tmpfs 已挂载于 /tmp
  • [ ] 健康检查已设置
  • [ ] 渲染超时已配置

以 LGPL-3.0-or-later 许可证发布。