Thiết lập Docker
Chạy Artisan trong Docker yêu cầu binary Chrome hoặc Chromium trong container. Hướng dẫn này bao gồm pattern Dockerfile sẵn sàng production, cấu hình Compose, cân nhắc bảo mật và hỗ trợ font.
Dockerfile
Tối thiểu (dựa trên Debian)
FROM php:8.3-cli
# Cài Chromium và thư viện cần thiết
RUN apt-get update && apt-get install -y --no-install-recommends \
chromium \
fonts-liberation \
libappindicator3-1 \
libasound2 \
libatk-bridge2.0-0 \
libatk1.0-0 \
libcups2 \
libdbus-1-3 \
libdrm2 \
libgbm1 \
libnspr4 \
libnss3 \
libx11-xcb1 \
libxcomposite1 \
libxdamage1 \
libxrandr2 \
xdg-utils \
&& rm -rf /var/lib/apt/lists/*
# Đặt đường dẫn Chrome cho Artisan tự phát hiện
ENV CHROME_PATH=/usr/bin/chromium
# Cài dependency Composer
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader
COPY . .Dựa trên Alpine (Image nhỏ hơn)
FROM php:8.3-cli-alpine
RUN apk add --no-cache \
chromium \
nss \
freetype \
harfbuzz \
ca-certificates \
ttf-freefont \
font-noto-cjk
ENV CHROME_PATH=/usr/bin/chromium-browser
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader
COPY . .Docker Compose
services:
app:
build: .
volumes:
- ./output:/app/output
environment:
CHROME_PATH: /usr/bin/chromium
deploy:
resources:
limits:
memory: 1G
reservations:
memory: 512M
# Cần thiết cho Chrome sandboxing trong Docker
security_opt:
- seccomp=unconfined
cap_add:
- SYS_ADMINChrome Flag cho Docker
Chrome trong container cần flag cụ thể để chạy ổn định. Truyền chúng khi tạo renderer.
use Yeeefang\TcpdfNext\Artisan\HtmlRenderer;
$renderer = HtmlRenderer::create(
chromeFlags: [
'--no-sandbox', // bắt buộc trừ khi bạn cấu hình seccomp
'--disable-setuid-sandbox', // bỏ qua sandbox phụ
'--disable-gpu', // không GPU trong container
'--disable-dev-shm-usage', // ghi vào /tmp thay vì /dev/shm
'--disable-software-rasterizer',
'--single-process', // giảm bộ nhớ cho render đơn giản
],
);WARNING
Flag --no-sandbox tắt process sandbox của Chrome. Trong production, ưu tiên giữ sandbox bật và cấp quyền SYS_ADMIN cho container hoặc dùng seccomp profile tùy chỉnh.
Cân nhắc bảo mật
Tùy chọn A: Giữ Sandbox (Khuyên dùng)
Thêm SYS_ADMIN vào container và bỏ --no-sandbox.
services:
app:
cap_add:
- SYS_ADMIN
security_opt:
- seccomp=chrome-seccomp.jsonBạn có thể tìm seccomp profile tối thiểu cho Chrome trong tài liệu dự án Chromium.
Tùy chọn B: User Non-Root
Chạy Chrome dạng user không đặc quyền bên trong container.
RUN groupadd -r artisan && useradd -r -g artisan -G audio,video artisan \
&& mkdir -p /home/artisan/Downloads \
&& chown -R artisan:artisan /home/artisan
USER artisanTùy chọn C: Filesystem Read-Only
Mount root filesystem dạng read-only và cung cấp tmpfs ghi được cho Chrome.
services:
app:
read_only: true
tmpfs:
- /tmp
- /home/artisan/.configGiới hạn bộ nhớ
Chrome có thể tiêu thụ bộ nhớ đáng kể, đặc biệt khi render trang phức tạp. Đặt giới hạn container và giám sát sử dụng.
| Độ phức tạp trang | Bộ nhớ khuyên dùng |
|---|---|
| Text đơn giản (1--5 trang) | 256 MB |
| Bảng và hình ảnh (5--20 trang) | 512 MB |
| Layout phức tạp, biểu đồ, JS (20+ trang) | 1 GB+ |
Nếu Chrome hết bộ nhớ, nó thoát với code 137 (OOM killed). RenderException của Artisan bọc lỗi này với thông báo mô tả.
// Fail nhanh với timeout chặt để tránh tốn bộ nhớ
$options = RenderOptions::create()->setTimeout(15000);Cài font
Docker image đi kèm font tối thiểu. Cài thêm font để render đúng chữ viết phi Latin và typography thương hiệu.
Font hệ thống
# Font CJK (Trung, Nhật, Hàn)
RUN apt-get update && apt-get install -y \
fonts-noto-cjk \
fonts-noto-cjk-extra
# Arabic, Hebrew, Devanagari
RUN apt-get install -y \
fonts-noto-core \
fonts-noto-extra
# Google Font (vd: Inter, Roboto)
RUN apt-get install -y fonts-interFont tùy chỉnh
Sao chép file font vào container và đăng ký với fontconfig.
COPY ./fonts/*.ttf /usr/share/fonts/custom/
RUN fc-cache -fvWeb Font
Chrome trong Artisan có thể tải @font-face web font tại thời điểm render, giống trình duyệt thường. Không cần cấu hình thêm, nhưng đảm bảo container có quyền truy cập mạng đến font CDN.
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
body {
font-family: 'Inter', sans-serif;
}Health Check
Thêm health check xác minh Chrome hoạt động.
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD chromium --headless=new --disable-gpu --no-sandbox \
--dump-dom about:blank > /dev/null 2>&1 || exit 1Ví dụ Production đầy đủ
FROM php:8.3-cli-bookworm AS base
# System dependency + Chromium
RUN apt-get update && apt-get install -y --no-install-recommends \
chromium \
fonts-liberation \
fonts-noto-cjk \
libnss3 libgbm1 libatk-bridge2.0-0 \
&& rm -rf /var/lib/apt/lists/*
ENV CHROME_PATH=/usr/bin/chromium
# User non-root
RUN groupadd -r artisan && useradd -r -g artisan artisan \
&& mkdir -p /home/artisan && chown artisan:artisan /home/artisan
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader
COPY --chown=artisan:artisan . .
USER artisan
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD chromium --headless=new --no-sandbox --dump-dom about:blank > /dev/null 2>&1
CMD ["php", "artisan", "render:process"]Bước tiếp theo
- Tính năng nâng cao -- Cấu hình Chrome, connection pooling, xử lý lỗi.
- Tổng quan -- Tóm tắt package và cài đặt.