Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Super Slow Docker Build

I think I'm going to go crazy. I've searched all over and can't seem to find a working solution both here on Stack, GitHub and other far reaches of the interwebs.

On this particular project, running docker-compose build is taking FOREVER. It didn't use to be this way, and on other projects that use Docker, it's not an issue at all. And by forever... I'm talking around 10-15 minute build times when it used to only take around 2 minutes tops. I had two separate coworkers DL the same repo (one on Ubuntu 18, and the other on macOS 14.x). When they ran the build command, the entire process took ~2 minutes. Both of these people had never built this project before, so they were starting from complete scratch.

I've uninstalled/reinstalled Docker, ran a complete docker system prune -a, connected via wifi, connected via Ethernet, tried a different wifi network, tweaked my compose file, tweaked my docker file -- nothing.

My machine is a 2018 MacBook Pro with a quad-core 2.7GHz i7, running macOS 10.14.6 with 16gb of installed RAM with Docker Desktop 2.1.0.5.

I've allowed Docker Desktop to have up to 12gb or RAM. During the build process, my machine cpu usage spikes on average from 110% up to 270% running the com.docker.hyperkit process.

To be clear, it's hanging on the "Building php" (or "Building web") status message(s) before anything really even starts. After that, the actual build process runs smoothly and quick.

Here is my docker-compose.yaml file:

version: '3.1'

services:
  db:
    container_name: clientsname.db
    hostname: db
    image: mariadb:10.4.1-bionic
    volumes:
      - ./db-data:/var/lib/mysql:delegated
    ports:
      - 3307:3306
    environment:
      MYSQL_DATABASE: my_database
      MYSQL_USER: my_user
      MYSQL_PASSWORD: my_pass
      MYSQL_ROOT_PASSWORD: my_pass

  php:
    container_name: clientsname.php
    hostname: php
    build:
      dockerfile: php/php.dockerfile
      context: ./
    environment:
      XDEBUG_CONFIG: remote_host=${REMOTE_HOST}

    volumes:
      - ../web:/var/www/web
      - ../moodle:/var/www/moodle
      - ../moodledata:/var/www/moodledata
      - ./php/custom.ini:/usr/local/etc/php/conf.d/zzz-custom.ini
      - ./php/z-errors.ini:/usr/local/etc/php/conf.d/z-errors.ini:delegated
      - ./php/z-upload.ini:/usr/local/etc/php/conf.d/z-upload.ini:delegated
      - ./php/z-xdebug.ini:/usr/local/etc/php/conf.d/z-xdebug.ini:delegated
    depends_on:
      - db

  web:
    container_name: clientsname.web
    hostname: web
    build:
      dockerfile: nginx/nginx.dockerfile
      context: ./
    volumes:
      - ../web:/var/www/web
      - ../moodle:/var/www/moodle
      - ../moodledata:/var/www/moodledata
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      - ./nginx/ssl:/etc/nginx/ssl
      - ./logs:/var/log/nginx
    ports:
      - 80:80
      - 443:443
    depends_on:
      - php
      - db

Here is the referenced php.dockerfile file:

FROM php:7.2.26-fpm
LABEL maintainer="My Clients Name"

# Environment variables
ENV DEBIAN_FRONTEND=noninteractive
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV COMPOSER_NO_INTERACTION=1
ENV COMPOSER_HOME=/usr/local/share/composer

# Working Directory
WORKDIR /var/www/web
WORKDIR /var/www/moodle
WORKDIR /var/www/moodledata


RUN rm /etc/apt/preferences.d/no-debian-php && apt-get update && apt-get install -y --no-install-recommends apt-utils \
        build-essential     \
        php-soap            \
        libzip-dev          \
        libmagickcore-dev   \
        libmagickwand-dev   \
        libmagic-dev        \
        libpng-dev          \
        libfreetype6-dev    \
        libjpeg62-turbo-dev \
        libmcrypt-dev       \
        libmemcached-dev    \
        zlib1g-dev          \
        nano                \
        sudo                \
        gnupg               \
        curl                \
        unzip &&            \
    docker-php-ext-install soap pdo_mysql mysqli && \
    docker-php-ext-install -j$(nproc) gd iconv && \
    docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ && \
    pecl install zip-1.15.2 imagick memcached-3.0.4 xdebug && \
    docker-php-ext-enable memcached imagick zip xdebug

# Install Composer, Node, Gulp, and SASS
RUN curl -s https://getcomposer.org/installer | php && mv composer.phar /usr/local/bin/composer

RUN curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash - && apt-get install -y nodejs && npm install npm@latest -g && npm install --global gulp-cli && npm config set unsafe-perm=true


# Export composer vendor path
RUN echo "" >> ~/.bashrc && echo 'export PATH="$HOME/.composer/vendor/bin:$PATH"' >> ~/.bashrc

And the referenced nginx.dockerfile

FROM nginx:stable-alpine

RUN apk add --update bash && rm -rf /var/cache/apk/*

WORKDIR /var/www/web

It's driving me batty... what in the bloody hell could I be doing wrong? If there is anything I've left out that you'd all like to know, please let me know and I'll update the post.


UPDATE

Thanks to @BMitch and you all who have commented thus far. I took my entire /docker build directory and moved it into a test folder, and then created empty /web, /moodle, and /moodledata directories before running the build command. It started to compile immediately.

What's curious to me is that the other coworkers DL'd the same Git repo that I have and did not have any of the same issues. Oooh... come to think of it... I bet I know what the issue is.

like image 446
Drew Avatar asked Jan 06 '20 16:01

Drew


People also ask

Why is my Docker build taking too long?

If your Docker image builds takes a long time downloading dependencies, it's a good idea to check whether you're installing more than you need to. First, check if you might be downloading development dependencies which are not needed in your image at all.

How do I speed up Docker build time?

The easiest way to increase the speed of your Docker image build is by specifying a cached image that can be used for subsequent builds. You can specify the cached image by adding the --cache-from argument in your build config file, which will instruct Docker to build using that image as a cache source.

How long should it take to build Docker image?

Building Docker images is the longest process on this list. For example, it took 14 minutes to build each non-optimized backend image.

What is Docker BuildKit?

BuildKit works on multiple export formats such as OCI or Docker along with the Support of Frontends (Dockerfile) and provides features such as efficient caching and running parallel build operations. BuildKit only needs container runtime for its execution and currently supported runtimes include containerd and runc.


1 Answers

This is from your build context (that's often the directory where you run your build, but can be overridden as you've done in the compose file). You have a large number of files, or large files, in the context directory that is sent before performing the build.

You can use .dockerignore which has a nearly identical format to .gitignore to exclude files from being sent on build. And with BuildKit (enabled if you export DOCKER_BUILDKIT=1 in recent versions of docker) it will only send context when you explicitly copy files and then only when those files have changed from what is available in the cache.

For more on the build context, see: https://docs.docker.com/engine/reference/commandline/build/

There's also the best practices: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

like image 148
BMitch Avatar answered Oct 04 '22 09:10

BMitch