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)'
CodePudding user response:
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 asbuild
, then Compose names the built image with thewebapp
and optionaltag
specified inimage
:build: ./dir image: webapp:tag
This results in an image named
webapp
and taggedtag
, built from./dir
.
From: https://docs.docker.com/compose/compose-file/compose-file-v3/#build
CodePudding user response:
When starting the containers, you will need to instruct docker-compose
to rebuilt the dockerfile.
Try this:
docker-compose up --build --force-recreate