Docker-Compose,Dockerfile和建立图像问题(php-fpm+ pecl+ xdebug)

发布于 2025-02-09 06:39:27 字数 2558 浏览 1 评论 0原文

我是Docker的新手,想自己构建图像(N​​GINX + PHP-FPM + MARIADB + PHPADMIN)。

我想拥有Xdebug,所以我有一个Dockerfile来自定义PHP-FPM图像。

然后我遇到了一个问题(与在这里/a>)当我执行

docker-compose --build

docker-compose up --build

第一次构建映像时,但是下次它会失败,因为PHP-FPM以某种方式最终以已安装的Xdebug结束:

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

就像该图像来自缓存,但Dockerfile仍然应用。

我已经使用了的解决方案>但是我显然缺少一些东西,应该不是那样。我在做什么错?

我的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:

还有我的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)'

I'm new to Docker and want to build the image myself (nginx + php-fpm + mariadb + phpadmin).

I want to have Xdebug so I've a Dockerfile to customize the php-fpm image.

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:

+ 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.

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:

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)'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

菩提树下叶撕阳。 2025-02-16 06:39:27

讨论/解释

我在做什么错?

也许这是对docker-compose.yml模板的误解,特别是在php服务的容器中(基于php:7.4-fpm < /code>)可能被错误引入。

当您指定image构建服务的属性时,构建时的图像将存储在image> image name下(请参阅另外,参考部分)。

当您将image命名为php:7.4-fpm,这些构建图像在本地存储(您运行Docker-Compose(1) 您在dockerfile中都有该构建上下文中的 相同 name php:7.4-fpm

FROM php:7.4-fpm
# ...

然后,当您为 first 时间构建时,图像php:7.4-fpm在本地不可用。然后是从 docker Hub提取php:7.4-fpm的构建,然后构建 result 覆盖 图像php:7.4-fpm在您使用相同名称(!)时本地。

这很可能是不是的意图。

这也可以解释为什么- 构建 - force-recreate也不起作用:dockerfile构建指令考虑php:7.4 -fpm是从中构建的的映像,但它已经是(第一个本地构建)的结果。

解决方案

删除图像服务关键字。您不需要它,因为您拥有构建关键字。 Docker Compose将自动(基于服务和项目名称)在您的项目中注意并命名图像。

services:

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

然后删除悬空/污​​染的php:7.4-fpm图像:

$ docker image rm php:7.4-fpm

这两个步骤应该已经解决了您的问题并将Docker组成毫无疑问。

此外,您可以卸下解决方法,并执行普通的pecl install xdebug&amp;&amp; docker-php-ext-enable xdebug,在这里具有更好的调试能力(set -ex -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 ;\
    :

您可以通过从中制作来进一步调整此功能图像构建参数,将其绑定在docker-composer.yml模板中(并在此处使用变量和默认值)。我会把它留给你的喜好。

参考

如果您指定图像以及构建,则使用webApp 和可选标签在图像中指定的代码>:

 构建:./dir
图像:WebApp:标签
 

这将产生名为WebApp和标记的标签的图像,由./ dir

来自: https://docs.docks.docker.com/compose.com/compose /撰写文件/撰写文件 - 文件-V3/#构建

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.

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).

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:

FROM php:7.4-fpm
# ...

Then when you build for the first time, the image php:7.4-fpm is not available locally. 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 (!).

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).

Solution

Remove the image service keyword. You don't need it as you have the build keyword. Docker Compose will take care and name the image within your project automatically (based on service- and project name).

services:

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

Then remove the dangling/tainted php:7.4-fpm image:

$ docker image rm php:7.4-fpm

These two steps should already solve your issue and get your docker composition up without errors.

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):

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). 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:

build: ./dir
image: webapp:tag

This results in an image named webapp and tagged tag, built from ./dir.

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

猫烠⑼条掵仅有一顆心 2025-02-16 06:39:27

启动容器时,您需要指示Docker-Compose重建Dockerfile。

尝试以下操作:

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

When starting the containers, you will need to instruct docker-compose to rebuilt the dockerfile.

Try this:

docker-compose up --build --force-recreate
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文