DEV Community

Titas Gailius
Titas Gailius

Posted on

Multi-stage Docker Builds for Laravel

Most applications have a build step to download all the dependencies and/or compile your frontend assets.

Usually, it takes most of the deployment time.

Not to mention that the final image may be bigger because of the unnecessary dependencies that were used to download dependencies and compile the frontend assets.

Docker multi-stage builds

One of the easiest ways to make your deployments faster and images slimmer is to use multi-stage docker builds.

Docker caches a specific stage and only re-runs it if any of the dependent files have been changed.

Composer Step

  1. Use Composer 2.0 image.
  2. Copy files required for "composer install".
  3. Run "composer install".
  4. Copy the rest of the files.
  5. Run "composer dump-autoload".
#
# PHP Dependencies
#
FROM composer:2.0 as vendor

WORKDIR /app

COPY database/ database/
COPY composer.json composer.json
COPY composer.lock composer.lock

RUN composer install \
    --no-interaction \
    --no-plugins \
    --no-scripts \
    --no-dev \
    --prefer-dist

COPY . .
RUN composer dump-autoload

NPM Step

  1. Use NodeJS image.
  2. Cop files required for the "npm install".
  3. Run "npm install".
  4. Copy files required to build your frontend assets.
  5. Build your frontend assets.
#
# Frontend
#
FROM node:14.9 as frontend

WORKDIR /app

COPY artisan package.json webpack.mix.js yarn.lock tailwind.js ./

RUN npm install

COPY resources/js ./resources/js
COPY resources/sass ./resources/sass

RUN npm run production

Application Step

  1. Use your desired image.
  2. Copy built files from the previous stages.
  3. Enjoy fast deployments.
#
# Application
#
FROM php:7.4-fpm

WORKDIR /app

# Install PHP dependencies
RUN apt-get update -y && apt-get install -y libxml2-dev
RUN docker-php-ext-install pdo pdo_mysql mbstring opcache tokenizer xml ctype json bcmath pcntl

# Copy Frontend build
COPY --from=frontend /app/node_modules/ ./node_modules/
COPY --from=frontend /app/public/js/ ./public/js/
COPY --from=frontend /app/public/css/ ./public/css/
COPY --from=frontend /app/public/mix-manifest.json ./public/mix-manifest.json

# Copy Composer dependencies
COPY --from=vendor /app/vendor/ ./vendor/
COPY . .

RUN php artisan config:cache
RUN php artisan route:cache

You may find the full Dockerfile used in this article here.

Enjoy!

Top comments (0)