Configuración Docker
Ejecutar Artisan dentro de Docker requiere un binario de Chrome o Chromium en el contenedor. Esta guía cubre patrones de Dockerfile listos para producción, configuración de Compose, consideraciones de seguridad y soporte de fuentes.
Dockerfile
Mínimo (basado en Debian)
FROM php:8.3-cli
# Install Chromium and required libraries
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 Chrome path for Artisan auto-detection
ENV CHROME_PATH=/usr/bin/chromium
# Install Composer dependencies
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader
COPY . .Basado en Alpine (imagen más pequeña)
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
# Required for Chrome sandboxing in Docker
security_opt:
- seccomp=unconfined
cap_add:
- SYS_ADMINFlags de Chrome para Docker
Chrome en un contenedor necesita flags específicos para ejecutarse de forma confiable. Pásalos al crear el renderer.
use Yeeefang\TcpdfNext\Artisan\HtmlRenderer;
$renderer = HtmlRenderer::create(
chromeFlags: [
'--no-sandbox', // required unless you configure seccomp
'--disable-setuid-sandbox', // secondary sandbox bypass
'--disable-gpu', // no GPU in containers
'--disable-dev-shm-usage', // write to /tmp instead of /dev/shm
'--disable-software-rasterizer',
'--single-process', // reduce memory for simple renders
],
);WARNING
El flag --no-sandbox deshabilita el sandbox de procesos de Chrome. En producción, prefiere mantener el sandbox habilitado y otorgar al contenedor la capacidad SYS_ADMIN o usar un perfil seccomp personalizado en su lugar.
Consideraciones de seguridad
Opción A: Mantener el sandbox (recomendado)
Agrega SYS_ADMIN al contenedor y omite --no-sandbox.
services:
app:
cap_add:
- SYS_ADMIN
security_opt:
- seccomp=chrome-seccomp.jsonPuedes encontrar el perfil seccomp mínimo para Chrome en la documentación del proyecto Chromium.
Opción B: Usuario no-root
Ejecuta Chrome como un usuario dedicado sin privilegios dentro del contenedor.
RUN groupadd -r artisan && useradd -r -g artisan -G audio,video artisan \
&& mkdir -p /home/artisan/Downloads \
&& chown -R artisan:artisan /home/artisan
USER artisanOpción C: Sistema de archivos de solo lectura
Monta el sistema de archivos raíz como solo lectura y proporciona tmpfs escribible para Chrome.
services:
app:
read_only: true
tmpfs:
- /tmp
- /home/artisan/.configLímites de memoria
Chrome puede consumir memoria significativa, especialmente al renderizar páginas complejas. Establece límites de contenedor y monitorea el uso.
| Complejidad de página | Memoria recomendada |
|---|---|
| Texto simple (1--5 páginas) | 256 MB |
| Tablas e imágenes (5--20 páginas) | 512 MB |
| Diseños complejos, gráficos, JS (20+ páginas) | 1 GB+ |
Si Chrome se queda sin memoria, termina con código 137 (OOM killed). La RenderException de Artisan envuelve esto con un mensaje descriptivo.
// Fail fast with a tight timeout to avoid memory runaway
$options = RenderOptions::create()->setTimeout(15000);Instalación de fuentes
Las imágenes Docker vienen con fuentes mínimas. Instala fuentes adicionales para el renderizado correcto de scripts no latinos y tipografía de marca.
Fuentes del sistema
# CJK fonts (Chinese, Japanese, Korean)
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 Fonts (e.g., Inter, Roboto)
RUN apt-get install -y fonts-interFuentes personalizadas
Copia archivos de fuente al contenedor y regístralos con fontconfig.
COPY ./fonts/*.ttf /usr/share/fonts/custom/
RUN fc-cache -fvWeb fonts
Chrome en Artisan puede obtener web fonts @font-face al momento del renderizado, igual que un navegador regular. No se necesita configuración adicional, pero asegúrate de que el contenedor tenga acceso de red al CDN de fuentes.
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
body {
font-family: 'Inter', sans-serif;
}Health check
Agrega un health check que verifique que Chrome está operativo.
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD chromium --headless=new --disable-gpu --no-sandbox \
--dump-dom about:blank > /dev/null 2>&1 || exit 1Ejemplo completo de producción
FROM php:8.3-cli-bookworm AS base
# System dependencies + 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
# Non-root user
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"]Próximos pasos
- Funciones avanzadas -- Configuración de Chrome, connection pooling, manejo de errores.
- Resumen -- Resumen del paquete e instalación.