Super Slow Docker Build

29,475

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/

Share:
29,475

Related videos on Youtube

Drew
Author by

Drew

A short-cut is supposed to be hard. If it was easy, it would just be called "the way".

Updated on January 07, 2020

Comments

  • Drew
    Drew over 4 years

    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.

    • k0pernikus
      k0pernikus over 4 years
      I can build your php.dockerfile on [email protected] using Docker version 19.03.3, build a872fc2f8 just fine. Which version of both docker and docker-compose are you running?
    • k0pernikus
      k0pernikus over 4 years
      docker -v and docker-compose version respectively
    • Jay Blanchard
      Jay Blanchard over 4 years
      Docker 19.03.5 and Docker-Compose 1.25.1-rc1 just built the image in under 2 minutes
    • Nico Haase
      Nico Haase over 4 years
      Just out of curiosity: will it get faster if you remove some of the volumes? If yes, are they maybe large or contain lots of files?
    • delboy1978uk
      delboy1978uk over 4 years
      Are you able to build my LAMP stack? github.com/delboy1978uk/lamp
    • Drew
      Drew over 4 years
      To answer @k0pernikus, I'm running docker 19.03.5 and compose 1.24.1
    • ken
      ken almost 4 years
      "Oooh... come to think of it... I bet I know what the issue is." ....well, what was it??
    • Drew
      Drew almost 4 years
      Hey Ken, what I thought it was, turned out to be completely wrong. The answer from @BMitch below was the problem all along. As soon as I ignored the /db-data directory... bam. That was it. Worked like a charm after that.
  • Drew
    Drew over 4 years
    Holy balls... that totally worked. The problem was with the /db-data/ directory that was 9gb in size. I had been looking in my /web folder and it never occurred to me that the problem was outside of the source folder. Honestly, I had tried the .dockerignore route this morning after reading about it elsewhere, but I think I had the syntax just slightly off. Thanks a million... I'll be sharing this info with the rest of our dev team and working it into our overall build process.
  • Tim Fletcher
    Tim Fletcher almost 4 years
    I had this issue too. My build => context directory was incorrect and it was taking 5 minutes before it would even start the build.
  • bluebinary
    bluebinary over 2 years
    Very helpful advice! Make sure you use your project's .dockerignore to ignore things like logging folders containing gigabytes worth of log files from getting pulled into the build context unnecessarily (oops), and slowing the build down to a crawl. You can also pass the --verbose flag to docker-compose to gain a little more insight into what it is doing, such as calling docker-compose --verbose build, which can help highlight which step it is "stuck" on.