Absortio

Email → Summary → Bookmark → Email

How to Optimize Docker Images for Laravel Apps: A Simple Guide

Extracto

If you already used Docker with a Laravel app, you know the final image can get big and that affects...

Resumen

Resumen Principal

La optimización de imágenes Docker para aplicaciones Laravel es crucial para mitigar desafíos comunes como los tiempos de construcción prolongados, la velocidad de despliegue lenta y los costos de almacenamiento elevados asociados a imágenes excesivamente grandes. Este análisis detalla una estrategia avanzada basada en construcciones multi-etapa, el uso de imágenes base ligeras y la implementación de mejores prácticas para reducir drásticamente el tamaño de las imágenes finales. El enfoque se centra en segregar las fases de desarrollo y producción, garantizando que las herramientas de construcción como Composer y Node no persistan en la imagen final de despliegue. Al aplicar estas técnicas, se logra una reducción de tamaño excepcional, transformando imágenes que superan 1.2 GB en otras de menos de 200 MB, lo que no solo acelera el ciclo de vida del desarrollo y despliegue, sino que también mejora la seguridad y eficiencia operativa.

Elementos Clave

  • Construcciones Multi-Etapa (Multi-stage Builds): Esta metodología es la piedra angular de la optimización, dividiendo el Dockerfile en fases distintas. Por ejemplo, una primera etapa (vendor) se dedica a la instalación de dependencias PHP con Composer, mientras que una segunda etapa (frontend) maneja la compilación de activos con Node. La imagen final de producción, basada en php:8.3-fpm-alpine, copia únicamente los artefactos necesarios de las etapas anteriores, eliminando por completo las herramientas de desarrollo y sus dependencias de la imagen final.
  • Uso de Imágenes Alpine Ligeras: La adopción de imágenes base con el sufijo alpine (e.g., node:20-alpine, php:8.3-fpm-alpine) es fundamental para la reducción de tamaño. Estas variantes de imágenes son significativamente más pequeñas que sus contrapartes basadas en distribuciones más completas, lo que se traduce directamente en imágenes Docker finales mucho más compactas y eficientes para entornos de producción.
  • Exclusión de Herramientas de Desarrollo en la Imagen Final: Una práctica esencial es evitar la instalación de herramientas como Composer o Node en la imagen Docker de producción. Al confinar su uso a las etapas de construcción intermedias, se previene la inclusión innecesaria de binarios y bibliotecas voluminosas en la imagen de despliegue, lo que no solo reduce el tamaño, sino que también minimiza la superficie de ataque potencial y los riesgos de seguridad.
  • Estrategia de Copia Selectiva y Archivo .dockerignore: En lugar de realizar un COPY . . indiscriminado al final, se recomienda copiar solo los archivos y directorios estrictamente necesarios (/app desde la etapa vendor, /app/public/build desde la etapa frontend). Complementariamente, la creación de un archivo .dockerignore que excluya elementos como node_modules, vendor, .env, .git y tests es vital para asegurar que archivos voluminosos o sensibles no se transfieran al contexto de construcción ni se incluyan en la imagen final.

Análisis e Implicaciones

La implementación de estas optimizaciones tiene implicaciones profundas para los flujos de trabajo de CI/CD, reduciendo los tiempos de despliegue y los costos de infraestructura. Representa una evolución hacia prácticas de desarrollo más eficientes y seguras, crucial para la escalabilidad y sostenibilidad de aplicaciones Laravel modernas.

Contexto Adicional

Además de las optimizaciones de tamaño, se recomiendan medidas de seguridad complementarias como la definición explícita del usuario (USER www-data) para ejecutar la aplicación, lo que mitiga riesgos al evitar el uso de root en producción.

Contenido

If you already used Docker with a Laravel app, you know the final image can get big and that affects build time, deployment speed, and even storage cost.

In this post, I'll show you how to make you Docker image smaller and faster using multi-stage builds, lightweight images, and a few best practices.


Basic Structure

Here is a real example using PHP 8.3 + Laravel + Composer + Node for front assets:

# Stage 1: Build the app dependencies
FROM composer:2.7 as vendor

WORKDIR /app

COPY composer.json composer.lock ./
RUN composer install --no-dev --prefer-dist --optimize-autoloader

COPY . .

# Stage 2: Build frontend assets (optional)
FROM node:20-alpine as frontend

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

# Stage 3: Final production image (clean and light)
FROM php:8.3-fpm-alpine

RUN apk add --no-cache \
    bash curl libpng libjpeg-turbo-dev libzip-dev oniguruma-dev \
    && docker-php-ext-install pdo pdo_mysql zip mbstring

WORKDIR /var/www

COPY --from=vendor /app /var/www
COPY --from=frontend /app/public/build /var/www/public/build

RUN chown -R www-data:www-data /var/www

USER www-data

Enter fullscreen mode Exit fullscreen mode


Best Practices

  • Use Alpine Images they are much smaller and good for prod.
  • Split the build into stages This keeps dev tools out of the final image.
  • Do not install Composer or Node in the final Image this reduces the size and security risks.
  • Don't use COPY . . at the end copy only what you really need (no .env, .git, tests, etc).

Before And After

A non optimize image can be 1.2GB or more.
With multi-stage builds and Alpine, it can be under 200MB!


Extra Security Tips

  • Use USER www-data at the end
  • Add a .dockerignore file
node_modules
vendor
.env
.git
tests

Enter fullscreen mode Exit fullscreen mode


Final Thoughts

Optimized Docker images are faster, safer, and cheaper.
Have youy optimized you Laravel Setup ? Do you have other tips ?

Fuente: DEV Community