How to decreasing docker image build time in Laravel applications?

In the internet there are a lot of blog posts and tutorials that learn how to create docker image or how to dockerize a Laravel application, But in most cases they didn't mention about performance and how to build faster these kind of applications.

How to decreasing docker image build time in Laravel applications?
Photo by Agê Barros / Unsplash

In the internet there are a lot of blog posts and tutorials that learn how to create docker image or how to dockerize a Laravel application, But in most cases they didn't mention about performance and how to build faster these kind of applications.

Here I want to show you how to speed up your Laravel build times. for start I 'm sharing a normal Dockerfile from Digital Ocean blog.

FROM php:7.4-fpm

# Arguments defined in docker-compose.yml
ARG user
ARG uid

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    unzip

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd

# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Create system user to run Composer and Artisan Commands
RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer && \
    chown -R $user:$user /home/$user

# Set working directory
WORKDIR /var/www

USER $user

If every time you build your application with this docker file it takes 5 ~ 15 min depends on your system configuration and internet speed. Every time it uses original php image and installs php extensions on it that with increasing your needs on different extensions the time of builds grow up at the same time.

So what is the solution?

Solution is to use a feature of docker that you can use images in nested way. Here we create a customized image of php for our self like this:

FROM php:7.4-fpm

# Install dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
    curl \
    zip \
    mariadb-client \
    nano \
    nginx \
    supervisor


# Add php extention installer
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

# install extentions you need
RUN chmod +x /usr/local/bin/install-php-extensions && \
    install-php-extensions gd gmp imap zip;


# Install postgres
RUN apt-get clean ; \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*

We build this image and push it to a private or public registry like hub.docker.com or github registry. I personally use Gitlab.com for this purpose but your free to use any of them.

You have now a ready to use php images that you don't need to change any thing. So lets go to create your Laravel docker file. You just need to copy and paste your Laravel files and content inside docker image so your Laravel dockerfile should look like this:

# this the image we previously created
FROM registry.gitlab.com/promasoud/php/7.4:latest

# Copy composer.lock and composer.json
COPY composer.json /var/www/

# Set working directory
WORKDIR /var/www

# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www

COPY --chown=www:www . /var/www

RUN /usr/local/bin/composer install --ignore-platform-reqs --prefer-dist --no-ansi --no-interaction --no-progress --no-scripts

That's it. Now you can build your image under 1 min AMAZING!

Please let me know if you have any problem with creating your images.