Skip to content

Setup Docker

Menjalankan Artisan di dalam Docker memerlukan binary Chrome atau Chromium di container. Panduan ini membahas pola Dockerfile siap produksi, konfigurasi Compose, pertimbangan keamanan, dan dukungan font.

Dockerfile

Minimal (Berbasis Debian)

dockerfile
FROM php:8.3-cli

# Instal Chromium dan library yang diperlukan
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/*

# Set path Chrome untuk auto-detection Artisan
ENV CHROME_PATH=/usr/bin/chromium

# Instal dependency Composer
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader

COPY . .

Berbasis Alpine (Image Lebih Kecil)

dockerfile
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

yaml
services:
  app:
    build: .
    volumes:
      - ./output:/app/output
    environment:
      CHROME_PATH: /usr/bin/chromium
    deploy:
      resources:
        limits:
          memory: 1G
        reservations:
          memory: 512M
    # Diperlukan untuk Chrome sandboxing di Docker
    security_opt:
      - seccomp=unconfined
    cap_add:
      - SYS_ADMIN

Flag Chrome untuk Docker

Chrome di container memerlukan flag tertentu untuk berjalan dengan reliable. Berikan saat membuat renderer.

php
use Yeeefang\TcpdfNext\Artisan\HtmlRenderer;

$renderer = HtmlRenderer::create(
    chromeFlags: [
        '--no-sandbox',              // diperlukan kecuali Anda mengonfigurasi seccomp
        '--disable-setuid-sandbox',  // bypass sandbox sekunder
        '--disable-gpu',             // tidak ada GPU di container
        '--disable-dev-shm-usage',   // tulis ke /tmp alih-alih /dev/shm
        '--disable-software-rasterizer',
        '--single-process',          // kurangi memori untuk render sederhana
    ],
);

WARNING

Flag --no-sandbox menonaktifkan process sandbox Chrome. Di produksi, lebih baik pertahankan sandbox dan berikan capability SYS_ADMIN ke container atau gunakan profil seccomp kustom.

Pertimbangan Keamanan

Opsi A: Pertahankan Sandbox (Direkomendasikan)

Tambahkan SYS_ADMIN ke container dan hilangkan --no-sandbox.

yaml
services:
  app:
    cap_add:
      - SYS_ADMIN
    security_opt:
      - seccomp=chrome-seccomp.json

Anda bisa menemukan profil seccomp minimal untuk Chrome di dokumentasi proyek Chromium.

Opsi B: User Non-Root

Jalankan Chrome sebagai user unprivileged khusus di dalam container.

dockerfile
RUN groupadd -r artisan && useradd -r -g artisan -G audio,video artisan \
    && mkdir -p /home/artisan/Downloads \
    && chown -R artisan:artisan /home/artisan

USER artisan

Opsi C: Filesystem Read-Only

Mount root filesystem sebagai read-only dan sediakan tmpfs yang writable untuk Chrome.

yaml
services:
  app:
    read_only: true
    tmpfs:
      - /tmp
      - /home/artisan/.config

Batas Memori

Chrome bisa mengonsumsi memori signifikan, terutama saat me-render halaman kompleks. Set batas container dan monitor penggunaan.

Kompleksitas HalamanMemori yang Direkomendasikan
Teks sederhana (1--5 halaman)256 MB
Tabel dan gambar (5--20 halaman)512 MB
Layout kompleks, chart, JS (20+ halaman)1 GB+

Jika Chrome kehabisan memori, ia keluar dengan kode 137 (OOM killed). RenderException Artisan membungkus ini dengan pesan deskriptif.

php
// Gagal cepat dengan timeout ketat untuk menghindari penggunaan memori berlebih
$options = RenderOptions::create()->setTimeout(15000);

Instalasi Font

Image Docker dikirim dengan font minimal. Instal font tambahan untuk rendering yang benar dari script non-Latin dan tipografi branded.

Font Sistem

dockerfile
# Font CJK (Chinese, Japanese, Korean)
RUN apt-get update && apt-get install -y \
    fonts-noto-cjk \
    fonts-noto-cjk-extra

# Arab, Ibrani, Devanagari
RUN apt-get install -y \
    fonts-noto-core \
    fonts-noto-extra

# Google Fonts (misalnya Inter, Roboto)
RUN apt-get install -y fonts-inter

Font Kustom

Salin file font ke container dan daftarkan dengan fontconfig.

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

Web Font

Chrome di Artisan bisa mengambil web font @font-face saat render, sama seperti browser biasa. Tidak perlu konfigurasi ekstra, tapi pastikan container memiliki akses jaringan ke CDN font.

css
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');

body {
    font-family: 'Inter', sans-serif;
}

Health Check

Tambahkan health check yang memverifikasi Chrome beroperasi.

dockerfile
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
    CMD chromium --headless=new --disable-gpu --no-sandbox \
        --dump-dom about:blank > /dev/null 2>&1 || exit 1

Contoh Produksi Lengkap

dockerfile
FROM php:8.3-cli-bookworm AS base

# Dependency sistem + 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"]

Langkah Selanjutnya

  • Fitur Lanjutan -- Konfigurasi Chrome, connection pooling, penanganan error.
  • Ringkasan -- Ringkasan paket dan instalasi.

Didistribusikan di bawah lisensi LGPL-3.0-or-later.