超慢的Docker构建

33

我感觉我快要疯了。我在Stack、GitHub和其他地方搜索了很久,似乎找不到一个可行的解决方案。

在这个特定项目中,运行docker-compose build需要非常长的时间。这种情况过去并没有发生过,在其他使用Docker的项目中完全没有问题。我指的是大约需要10-15分钟来构建,而以前最多只需要2分钟。我有两个同事下载了相同的repo(一个是Ubuntu 18,另一个是macOS 14.x)。当他们运行build命令时,整个过程只用了约2分钟。这两个人之前都没有构建过这个项目,所以他们从头开始。

我已经卸载/重装了Docker,运行了完整的docker system prune -a,通过WiFi连接,通过以太网连接,尝试了另一个WiFi网络,修改了我的Compose文件,修改了我的Docker文件——但是一切都没用。

我的机器是一台2018年的MacBook Pro,配备有四核2.7GHz i7、运行macOS 10.14.6的16GB RAM和Docker Desktop 2.1.0.5。

我允许Docker Desktop使用高达12GB的RAM。在构建过程中,我的机器CPU使用率平均飙升至110%到270%,运行com.docker.hyperkit进程。

需要明确的是,在任何真正开始之前,它都会停滞在“构建php”(或“构建web”)状态消息上。之后,实际的构建过程运行顺畅且快速。

这是我的docker-compose.yaml文件:

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

这里是被引用的php.dockerfile文件:

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

以及被引用的nginx.dockerfile

FROM nginx:stable-alpine

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

WORKDIR /var/www/web

这让我感到非常恼火……我到底做错了什么?如果我漏掉了任何你们想要知道的内容,请告诉我,我会更新帖子。


更新

感谢@BMitch和所有已经评论的人。我将整个/docker构建目录移动到一个测试文件夹中,然后创建了空的/web、/moodle和/moodledata目录,然后运行build命令。它立即开始编译。

让我觉得很奇怪的是,其他同事下载了与我相同的Git存储库,却没有遇到任何相同的问题。哦……我想我知道问题出在哪里了。


docker -vdocker-compose version - k0pernikus
只是出于好奇,如果移除一些卷,它会变得更快吗?如果是的话,它们可能很大或包含大量文件吗? - Nico Haase
你能搭建我的 LAMP 堆栈吗?https://github.com/delboy1978uk/lamp - delboy1978uk
4
哦......想起来了......我敢打赌我知道问题出在哪里了。......那么,是什么问题? - ken
1
嗨,肯恩,我之前的想法完全错了。@BMitch下面的答案一直是问题所在。一旦我忽略了/db-data目录... 就好了。之后就像魔术般地运行了。 - Drew
显示剩余3条评论
1个回答

55

这是来自您的构建上下文(通常是您运行构建的目录,但可以根据您在compose文件中所做的方式进行覆盖)。您有大量的文件或大文件在上下文目录中,在执行构建之前发送这些文件。

您可以使用.dockerignore文件,其格式与.gitignore几乎相同,以排除在构建时发送的文件。并且对于使用BuildKit(在最近版本的docker中,如果您export DOCKER_BUILDKIT=1则启用),仅在显式复制文件并且这些文件与缓存中可用的内容不同时才会发送上下文。

有关构建上下文的更多信息,请参见:https://docs.docker.com/engine/reference/commandline/build/

还有一些最佳实践:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/


14
哇塞...那个方法完全起作用了。问题出在占据 9GB 空间的 /db-data/ 目录上。我一直在查看我的 /web 文件夹,从未想到问题出现在源文件夹之外。老实说,今天早上在其他地方读到这个方法后,我已经尝试过使用 .dockerignore 方法,但我认为我的语法略微有些错误。非常感谢你... 我将与我们的开发团队分享此信息,并将其整合到我们的整体构建流程中。 - Drew
2
我也遇到了这个问题。我的构建 => 上下文目录不正确,它需要5分钟才能开始构建。 - Tim Fletcher
2
非常有用的建议!确保使用项目的.dockerignore来忽略像包含数GB日志文件的日志文件夹,以避免不必要地将其拉入构建上下文(糟糕),从而减慢构建速度。您还可以通过传递--verbose标志给docker-compose来获得更多关于它正在执行的信息,例如调用docker-compose --verbose build,这可以帮助突出显示它“卡住”的步骤。 - bluebinary
为什么文件大小会影响构建时间呢?我在笔记本电脑上有2TB的数据,构建时间与我只有50GB时完全相同。顺便说一下,Docker上的数据传输步骤通常非常快。 - Oliver Dixon
@OliverDixon,对于1MB的构建上下文数据传输速度比20GB的构建上下文数据传输速度快得多。大约快20000倍。 - BMitch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接