简体   繁体   English

Docker-Compose、Dockerfile 和构建映像问题 (php-fpm + pecl + xdebug)

[英]Docker-Compose, Dockerfile and Build Image Problems (php-fpm + pecl + xdebug)

I'm new to Docker and want to build the image myself (nginx + php-fpm + mariadb + phpadmin).我是 Docker 新手,想自己构建映像(nginx + php-fpm + mariadb + phpadmin)。

I want to have Xdebug so I've a Dockerfile to customize the php-fpm image.我想要 Xdebug,所以我有一个 Dockerfile 来自定义 php-fpm 图像。

And then I run into a problem (same as here ) when I execute然后我在执行时遇到问题(与此处相同)

docker-compose --build

or或者

docker-compose up --build

The image was built ok first time, but for next times it fails because the php-fpm somehow ended up with already installed xdebug:图像第一次构建得很好,但下一次它失败了,因为 php-fpm 以某种方式结束了已经安装的 xdebug:

+ pecl install xdebug
pecl/xdebug is already installed and is the same as the released version 3.1.5
install failed

It is like the image comes from cache but Dockerfile is still applied.就像图像来自缓存,但仍然应用 Dockerfile。

I've used the solution from that post but I am clearly missing something, it should not be like that.我已经使用了该帖子中的解决方案,但我显然遗漏了一些东西,它不应该是那样的。 What am I doing wrong?我究竟做错了什么?

My docker-compose:我的码头工人撰写:

version: "3.7"

services:

  web:
    image: nginx:1.17
    ports:
      - 8080:80
    volumes:
      - ../logs:/var/log/nginx/  
      - ../wordpress:/var/www/myapp
      - type: bind
        source: ./site.conf
        target: /etc/nginx/conf.d/default.conf  
    depends_on:
      - php
      - mariadb

  php:
    image: php:7.4-fpm
    build: 
      context: ./php
    volumes:
      - ../wordpress:/var/www/myapp
      - type: bind
        source: ./php/conf.d/xdebug.ini
        target: /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini 
      - type: bind
        source: ./php/conf.d/error_reporting.ini
        target: /usr/local/etc/php/conf.d/error_reporting.ini 
    depends_on:
      - mariadb

  mariadb:
    image: mariadb:10.4
    restart: always
    ports:
      - 127.0.0.1:3308:3306
    environment:
      - MYSQL_ROOT_PASSWORD=4321
      - MYSQL_DATABASE=wordpress
      - MYSQL_USER=wordpress
      - MYSQL_PASSWORD=1234
    volumes:
      - mariadb-data:/var/lib/mysql

  phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    ports:
      - 8900:80
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=mariadb
    depends_on:
      - mariadb

volumes:
  mariadb-data:

and my php-fpm dockerfile:和我的 php-fpm dockerfile:

FROM php:7.4-fpm

RUN apt-get update && apt-get install -y \
    libicu-dev\
    openssl \
    git \
    unzip\
    nano\
    && docker-php-ext-install \
    intl pdo pdo_mysql mysqli\
    && docker-php-ext-enable \
    intl pdo pdo_mysql
RUN bash -c '[[ -n "$(pecl list | grep xdebug)" ]]\
 || (pecl install xdebug && docker-php-ext-enable xdebug)'

When starting the containers, you will need to instruct docker-compose to rebuilt the dockerfile.启动容器时,您需要指示 docker docker-compose重建 dockerfile。

Try this:尝试这个:

docker-compose up --build --force-recreate

Discussion/Explanation讨论/解释

What am i doing wrong?我究竟做错了什么?

Perhaps it is a misunderstanding of the docker-compose.yml template, specifically in regards of the container for the php service (based on php:7.4-fpm ) which might have been introduced in error.也许这是对docker-compose.yml模板的误解,特别是关于php服务的容器(基于php:7.4-fpm ),这可能是错误引入的。

When you specify both the image and the build attribute of a service, the image as you build it will be stored under the image name (see also later References section).当您同时指定服务的imagebuild属性时,构建时的映像将存储在image名称下(另请参见后面的参考部分)。

As you name the image as php:7.4-fpm and those build images are stored locally (there where you run docker-compose(1) ) and you have in your Dockerfile within that build context that image same name php:7.4-fpm :当您将image命名为php:7.4-fpm并且这些构建图像存储在本地(运行docker-compose(1)的位置)并且您在该构建上下文中的Dockerfile中具有相同名称的图像php:7.4-fpm

FROM php:7.4-fpm
# ...

Then when you build for the first time, the image php:7.4-fpm is not available locally.那么当你一次构建的时候,镜像php:7.4-fpm在本地是不可用的。 Then it is build from Docker Hub fetched php:7.4-fpm and the build result is then overwriting the image php:7.4-fpm locally as you are using the same name (!).然后它是Docker Hub 获取php:7.4-fpm构建的,然后构建结果会在本地覆盖图像php:7.4-fpm ,因为您使用的是相同的名称 (!)。

This is most likely not intended.这很可能不是故意的。

This can also explain why --build --force-recreate does not work either: The Dockerfile build instructions consider php:7.4-fpm to be the image to be built from but it is already the result (of the first local build).这也可以解释为什么--build --force-recreate也不起作用: Dockerfile构建指令认为php:7.4-fpm是要构建映像,但它已经是(第一个本地构建的)结果。

Solution解决方案

Remove the image service keyword.删除image服务关键字。 You don't need it as you have the build keyword.你不需要它,因为你有build关键字。 Docker Compose will take care and name the image within your project automatically (based on service- and project name). Docker Compose 会自动为您的项目中的镜像命名(基于服务和项目名称)。

services:

  php:
    build:
      context: ./php
    volumes:
      - ../.:/var/www/myapp:ro

Then remove the dangling/tainted php:7.4-fpm image:然后删除悬空/受污染的php:7.4-fpm图像:

$ docker image rm php:7.4-fpm

These two steps should already solve your issue and get your docker composition up without errors.这两个步骤应该已经解决了您的问题,并使您的 docker 组合没有错误。

Additionally you can remove the workaround and do a plain pecl install xdebug && docker-php-ext-enable xdebug , here with better debugging abilities for the build ( set -ex ):此外,您可以删除解决方法并执行简单的pecl install xdebug && docker-php-ext-enable xdebug ,这里具有更好的构建调试能力( set -ex ):

FROM php:7.4-fpm

RUN set -ex ;\
    apt-get update ;\
    apt-get install -y \
      libicu-dev\
      openssl \
      git \
      unzip \
      nano \
    ;\
    docker-php-ext-install intl pdo pdo_mysql mysqli ;\
    docker-php-ext-enable intl pdo pdo_mysql ;\
    :

RUN set -ex ;\
    pecl install xdebug ;\
    docker-php-ext-enable xdebug ;\
    :

You could further tweak this by making the FROM image a build argument, bind it in the docker-composer.yml template (and use variables and defaults there-in, too).您可以通过将FROM映像作为构建参数来进一步调整它,将其绑定到docker-composer.yml模板中(并在其中使用变量和默认值)。 I'll leave that to your liking.我会让你喜欢的。

References参考

If you specify image as well as build , then Compose names the built image with the webapp and optional tag specified in image :如果您指定imagebuild ,则 Compose 使用webapp和 image 中指定的可选tag命名构建的image

 build: ./dir image: webapp:tag

This results in an image named webapp and tagged tag , built from ./dir .这会生成一个名为webapptag的图像,从./dir

From: https://docs.docker.com/compose/compose-file/compose-file-v3/#build来自: https ://docs.docker.com/compose/compose-file/compose-file-v3/#build

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM