I'm working with an app using docker (i'm not super familiar) and I need to add 2 new PHP extensions. I have changed the Dockerfile on an existing image as follows:
FROM php:7.2-fpm
RUN apt-get update
RUN apt-get install -y git unzip
RUN php -r "readfile('http://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer
RUN apt-get install -y git libpng-dev \
&& docker-php-ext-install gd
RUN apt-get install -y mysql-client \
&& docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd \
&& docker-php-ext-install pdo_mysql
RUN apt-get install -y libgmp-dev bcmath \
&& docker-php-ext-configure gmp \
&& docker-php-ext-install gmp \
&& docker-php-ext-install bcmath
RUN pecl install xdebug \
&& docker-php-ext-enable xdebug
ADD docker/templates/usr/local/etc/php/conf.d/uploads.ini /usr/local/etc/php/conf.d/uploads.ini
My new lines are:
RUN apt-get install -y libgmp-dev bcmath \
&& docker-php-ext-configure gmp \
&& docker-php-ext-install gmp \
&& docker-php-ext-install bcmath
I tried docker-compose restart, I tried docker-compose down followed by docker-compose up, I removed the container entirely and re-created with up. However hard I try, I always get this error when doing a composer require
the requested PHP extension bcmath is missing from your system.
I'm not sure why this is happening. Why won't the extension install, and how come if I completely delete the contents and write garbled text in the Dockerfile, it always runs successfully. Is it caching it?
Can somebody explain how I'd re-provision with the new changes I made?
Snippet of docker-compose.yml:
services:
web:
build:
context: ./
dockerfile: docker/web.docker
working_dir: /var/www
volumes:
- ./:/var/www
ports:
- 81:80
app:
build:
context: ./
dockerfile: docker/app.docker
working_dir: /var/www
volumes:
- ./:/var/www
environment:
- "LARAVEL_ENVIRONMENT=local"
You need to rebuild the image
docker-compose build
and next re-run containers
docker-compose up -d
Related
I keep getting this error every time I execute docker-compose up -d command in Windows CLI. Please help me solve this problem. Docker-compose.yml file which I'm using is part of Laminas skeleton application and was prewritten there.
Here is docker-compose.yml code:
laminas:
build: .
dockerfile: Dockerfile
ports:
- "8081:80"
volumes:
- .:/var/www
Here is Dockerfile code:
FROM php:7.3-apache
LABEL maintainer="getlaminas.org" \
org.label-schema.docker.dockerfile="/Dockerfile" \
org.label-schema.name="Laminas MVC Skeleton" \
org.label-schema.url="https://docs.getlaminas.org/mvc/" \
org.label-schema.vcs-url="https://github.com/laminas/laminas-mvc-skeleton"
## Update package information
RUN apt-get update
## Configure Apache
RUN a2enmod rewrite \
&& sed -i 's!/var/www/html!/var/www/public!g' /etc/apache2/sites-available/000-default.conf \
&& mv /var/www/html /var/www/public
## Install Composer
RUN curl -sS https://getcomposer.org/installer \
| php -- --install-dir=/usr/local/bin --filename=composer
###
## PHP Extensisons
###
## Install zip libraries and extension
RUN apt-get install --yes git zlib1g-dev libzip-dev \
&& docker-php-ext-install zip
## Install intl library and extension
RUN apt-get install --yes libicu-dev \
&& docker-php-ext-configure intl \
&& docker-php-ext-install intl
WORKDIR /var/www
After reinstall of Kubuntu 18 I run my docker project with command to run my first project:
docker-compose up -d --build
and got long output (it worked more 1 hour I suppose) and errors at end :
...
touch /var/www/html/node/out/Release/obj.host/tools/icu/icuuc.stamp
rm db5d6824c8b1d399378961ab1ba16292d5634a89.intermediate f918c1ef7e60ac5e25deb232838dc8c14a3b995e.intermediate 5402e94e215186eb33df16aff0cea7aca9a8f025.intermediate bda11aa586dd22c5cb705c71141e3087a79c526a.intermediate
if [ ! -r node -o ! -L node ]; then ln -fs out/Release/node node; fi
make: unrecognized option '--with-freetype-dir=/usr/include/'
make: unrecognized option '--with-webp-dir=/usr/include/'
make: unrecognized option '--with-jpeg-dir=/usr/include/'
Usage: make [options] [target] ...
Options:
-b, -m Ignored for compatibility.
-B, --always-make Unconditionally make all targets.
-C DIRECTORY, --directory=DIRECTORY
Change to DIRECTORY before doing anything.
-d Print lots of debugging information.
--debug[=FLAGS] Print various types of debugging information.
-e, --environment-overrides
Environment variables override makefiles.
--eval=STRING Evaluate STRING as a makefile statement.
-f FILE, --file=FILE, --makefile=FILE
Read FILE as a makefile.
-h, --help Print this message and exit.
-i, --ignore-errors Ignore errors from recipes.
-I DIRECTORY, --include-dir=DIRECTORY
Search DIRECTORY for included makefiles.
-j [N], --jobs[=N] Allow N jobs at once; infinite jobs with no arg.
-k, --keep-going Keep going when some targets can't be made.
-l [N], --load-average[=N], --max-load[=N]
Don't start multiple jobs unless load is below N.
-L, --check-symlink-times Use the latest mtime between symlinks and target.
-n, --just-print, --dry-run, --recon
Don't actually run any recipe; just print them.
-o FILE, --old-file=FILE, --assume-old=FILE
Consider FILE to be very old and don't remake it.
-O[TYPE], --output-sync[=TYPE]
Synchronize output of parallel jobs by TYPE.
-p, --print-data-base Print make's internal database.
-q, --question Run no recipe; exit status says if up to date.
-r, --no-builtin-rules Disable the built-in implicit rules.
-R, --no-builtin-variables Disable the built-in variable settings.
-s, --silent, --quiet Don't echo recipes.
-S, --no-keep-going, --stop
Turns off -k.
-t, --touch Touch targets instead of remaking them.
--trace Print tracing information.
-v, --version Print the version number of make and exit.
-w, --print-directory Print the current directory.
--no-print-directory Turn off -w, even if it was turned on implicitly.
-W FILE, --what-if=FILE, --new-file=FILE, --assume-new=FILE
Consider FILE to be infinitely new.
--warn-undefined-variables Warn when an undefined variable is referenced.
This program built for x86_64-pc-linux-gnu
Report bugs to <bug-make#gnu.org>
ERROR: Service 'web' failed to build: The command '/bin/sh -c apt-get update && apt-get install -y python libfreetype6-dev libwebp-dev libjpeg62-turbo-dev libpng-dev nano git-core curl build-essent
ial openssl libssl-dev libgmp-dev libldap2-dev netcat sqlite3 libsqlite3-dev && git clone https://github.com/nodejs/node.git && cd node && ./configure && make && make install docke
r-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-webp-dir=/usr/include/ --with-jpeg-dir=/usr/include/ && docker-php-ext-install gd pdo pdo_mysql pdo_sqlite zip gmp bcmath pcntl ldap sysvmsg exif && a2enmod rewrite' re
turned a non-zero code: 2
docker-compose.yml :
version: '3.1'
services:
web:
build:
context: ./web
dockerfile: Dockerfile.yml
environment:
- APACHE_RUN_USER=www-data
volumes:
- ${APP_PATH_HOST}:${APP_PTH_CONTAINER}
ports:
- 8081:80
working_dir: ${APP_PTH_CONTAINER}
db:
image: mysql:5.7.24
restart: always
environment:
MYSQL_ROOT_PASSWORD: 1
volumes:
- ${DB_PATH_HOST}:/var/lib/mysql
phpmyadmin:
depends_on:
- db
image: phpmyadmin/phpmyadmin
restart: always
ports:
- 8082:80
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: 1
composer:
image: composer:1.8
volumes:
- ${APP_PATH_HOST}:${APP_PTH_CONTAINER}
working_dir: ${APP_PTH_CONTAINER}
command: composer install --ignore-platform-reqs
web/Dockerfile.yml :
FROM php:7.2-apache
RUN apt-get update && \
apt-get install -y \
python \
libfreetype6-dev \
libwebp-dev \
libjpeg62-turbo-dev \
libpng-dev \
nano \
git-core \
curl \
build-essential \
openssl \
libssl-dev \
libgmp-dev \
libldap2-dev \
netcat \
sqlite3 \
libsqlite3-dev \
&& git clone https://github.com/nodejs/node.git \
&& cd node \
&& ./configure \
&& make \
&& make install \
docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-webp-dir=/usr/include/ --with-jpeg-dir=/usr/include/ && \
docker-php-ext-install gd pdo pdo_mysql pdo_sqlite zip gmp bcmath pcntl ldap sysvmsg exif \
&& a2enmod rewrite
COPY virtualhost.conf /etc/apache2/sites-enabled/000-default.conf
Why error? Is something is not installed on my hosting Kubuntu 18 ?
It seems to me that this project was working ok before reinstall of Kubuntu 18 ...
Old
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/
New
RUN docker-php-ext-configure gd --with-freetype=/usr/include/
N.B: You neet just to remove -dir
Charles Duffy, thanks!
That was misspelling from my side. I splitted web/Dockerfile.yml into 3 parts :
FROM php:7.2-apache
RUN apt-get update && \
apt-get install -y \
python \
libfreetype6-dev \
libwebp-dev \
libjpeg62-turbo-dev \
libpng-dev \
nano \
git-core \
curl \
build-essential \
openssl \
libssl-dev \
libgmp-dev \
libldap2-dev \
netcat \
sqlite3 \
libsqlite3-dev \
&& git clone https://github.com/nodejs/node.git \
&& cd node \
&& ./configure \
&& make \
&& make install
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-webp-dir=/usr/include/ --with-jpeg-dir=/usr/include/
RUN docker-php-ext-install gd pdo pdo_mysql pdo_sqlite zip gmp bcmath pcntl ldap sysvmsg exif \
&& a2enmod rewrite
COPY virtualhost.conf /etc/apache2/sites-enabled/000-default.conf
and it was complied ok !
I use docker-compose to build my containers and on a state I checkout private repository and I build the project inside container with composer.
I have the following structure
- docker-project
-- docker //here I keep the containers
--- apache
---- Dockerfile // the content what I posted
-- docker-compose.yml
-- src //this is the mounted folder where I can work on project
After build I would expect that the build project would show up in the mounted folder but instead I get empty folders here is my compose yml
apache:
container_name: apache2
build:
context: ./docker/apache
ports:
- 80:80
- 443:443
links:
- database
restart: always
volumes:
- ./src:/var/www/
- ./docker/logs/apache2/:/var/log/apache2/
- ~/.ssh/id_rsa:/root/.ssh/id_rsa
- ./docker/apache/sites/:/etc/apache2/sites-enabled
and here I have the docker file
FROM php:7.1-apache
ENV APACHE_DOCUMENT_ROOT /var/www
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
curl \
openssl \
openssh-server \
sendmail \
sendmail-bin \
mailutils \
libicu-dev \
libmemcached-dev \
libz-dev \
libpq-dev \
libjpeg-dev \
libfreetype6-dev \
libssl-dev \
libmcrypt-dev \
libxml2-dev \
libbz2-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
libjpeg62-turbo-dev \
zlib1g-dev \
libicu-dev \
g++ \
libxml2-dev \
git \
&& rm -rf /var/lib/apt/lists/*
# Install various PHP extensions which are required to build project
RUN docker-php-ext-configure bcmath --enable-bcmath \
&& docker-php-ext-configure pcntl --enable-pcntl \
&& docker-php-ext-configure pdo_mysql --with-pdo-mysql \
&& docker-php-ext-configure pdo_pgsql --with-pgsql \
&& docker-php-ext-configure mbstring --enable-mbstring \
&& docker-php-ext-configure soap --enable-soap \
&& docker-php-ext-install \
bcmath \
json \
intl \
mbstring \
mcrypt \
mysqli \
pcntl \
pdo_mysql \
pdo_pgsql \
soap \
sockets \
zip \
&& docker-php-ext-configure gd \
--enable-gd-native-ttf \
--with-jpeg-dir=/usr/lib \
--with-freetype-dir=/usr/include/freetype2 && \
docker-php-ext-install gd
##install xdebug and enable it. We need this for php unit coverage
RUN yes | pecl install xdebug \
&& docker-php-ext-enable xdebug
RUN yes | pecl install mongodb \
&& docker-php-ext-enable mongodb
RUN update-ca-certificates
# install composer to can install dependencies
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
&& php -r "unlink('composer-setup.php');"
RUN mkdir /root/.ssh
RUN rm -rf /var/www/project
WORKDIR /var/www/
RUN git checkout path/to/repo
RUN ls -l /var/www
WORKDIR /repo
RUN composer install
RUN ls -l
on docker-compose build I see that the project will be builded but on
docker-compose upthe folder is empty
What I'm missing in this case?
You are mounting a volume on /var/www when starting the container.
/var/www will be the same as ./src/www on the host machine, replacing anything that was added to /var/www during the build of the image.
Consider using the composer docker image or make sure to install the dependencies to another directory. Check out the vendor_dir key in composer.json
Example:
composer.json
{
"require": {
},
"config": {
"vendor-dir": "/var/www/vendor/"
}
}
Docker image build:
...
RUN mkdir -p /var/www/vendor/
COPY composer.json /var/www/vendor/
RUN cd /var/www/vendor/ && composer install
RUN mkidr -p /var/www/app
...
docker-compose.yml
volumes:
- ./src:/var/www/app
I could give a way of currently we are working. Rather cloning the repo like this what we do, we clone the repo in the local machine.
You have standard docker image that you have created from
php:7.1-apache with required softwares that you need to run the project.
Then you clone your project to you host machine.(think into src folder)
You run the composer install locally.
Then as you have defined the docker-compose.yml mount your src folder into /var/www/
TL;DR Using the same image, I get different results on running docker run and docker-compose up.
I am using the official php docker image and I want to install a set of extensions. Here is my Dockerfile:
FROM php:7.1.2-fpm
# Install software and dependencies (for extensions)
RUN apt-get update \
&& apt-get install -qy \
libcurl4-gnutls-dev \
libpng-dev \
libicu-dev \
mcrypt \
libmcrypt-dev \
libxml2-dev \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng12-dev \
git \
nodejs
# Install required PHP extensions
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd \
&& docker-php-ext-enable gd
# Install and setup composer
RUN curl -sS https://getcomposer.org/installer | php \
&& mv composer.phar /usr/local/bin/composer
# Cleanup tasks
RUN apt-get clean
As you see I am trying to install the gd library. This is actually taken from their example. On running docker build I see that it runs the configure and install steps (Step 3/5):
Step 1/5 : FROM php:7.1.2-fpm
---> 7191c638ed10
Step 2/5 : RUN apt-get update && apt-get install -qy libcurl4-gnutls-dev libpng-dev libicu-dev mcrypt libmcrypt-dev libxml2-dev libfreetype6-dev libjpeg62-turbo-dev libpng12-dev git nodejs
---> Using cache
---> 1f53f9211603
Step 3/5 : RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ && docker-php-ext-install -j$(nproc) gd && docker-php-ext-enable gd
---> Using cache
---> 4598a07d9fca
Step 4/5 : RUN curl -sS https://getcomposer.org/installer | php && mv composer.phar /usr/local/bin/composer
---> Running in 89c18c9ddf40
All settings correct for using Composer
Downloading...
Composer (version 1.4.0) successfully installed to: /var/www/html/composer.phar
Use it: php composer.phar
---> 059a1da3bb1a
Removing intermediate container 89c18c9ddf40
Step 5/5 : RUN apt-get clean
---> Running in 66c9cb68f684
---> f9543fa8b6e3
Removing intermediate container 66c9cb68f684
Successfully built f9543fa8b6e3
When I now do a plain docker run and ssh into the machine, the gd extension is available:
$ php -m
[PHP Modules]
Core
ctype
curl
date
dom
fileinfo
filter
ftp
gd
hash
iconv
json
libxml
mbstring
mysqlnd
openssl
pcre
PDO
pdo_sqlite
Phar
posix
readline
Reflection
session
SimpleXML
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
zlib
[Zend Modules]
Now, here is the interesting part: When I build (docker build) the image and then run the container with docker-compose up, the extension is not installed.
I narrowed it down to docker-compose up being the problem, as I did a lot of diffent things:
docker-compose build {servicename} + docker run {image-ID} --> extension availabe
removed all running containers and images, removed all docker-compose images (docker-compose down)
tried it with remote registry, using dockerfile, even building the image and then entering the local image in the docker-compose.yml --> same result
UPDATE
My docker-compose.yml:
version: '2'
services:
php:
# this is the variant with the registry
image: registry.example.com/devops/php:base-php-fpm
volumes:
- './src:/code'
- './config/php:/usr/local/etc/php'
links:
- mysql
depends_on:
- mysql
nginx:
image: nginx:1.10
ports:
- "80:80"
volumes:
- './src:/code'
- './config/nginx:/etc/nginx'
depends_on:
- php
links:
- php
mysql:
image: mysql
ports:
- "3306:3306"
Turns out it is the volume mount of the config file into the config folder of php - can only be found in my compose file. It overwrites the auto-generated config of PHP.
One of these things that keep you busy the whole day without delivering the tiniest piece of functionality...
Thanks for your help, guys!
I have a Dockerfile for PHP like this :
FROM php:7-fpm
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \
apt-get install -y git libicu-dev libmagickwand-dev libmcrypt-dev libcurl3-dev jpegoptim
RUN pecl install imagick && \
docker-php-ext-enable imagick
RUN docker-php-ext-install intl
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install opcache
RUN docker-php-ext-install mcrypt
RUN docker-php-ext-install curl
RUN docker-php-ext-install zip
And I'd like to create another Dockerfile, based on the first one, but with some PHP extensions added (for dev purpose) : Xdebug and other stuffs.
Can I create a "dev" Dockerfile that extends my main Dockerfile (without rewrite it) ?
Using multi-stage build is definitely one part of the answer here.
docker-compose v3.4 target being the second and last.
Here is a example to have 2 containers (1 normal & 1 w/ xdebug installed) living together :
Dockerfile
FROM php:7-fpm AS php_base
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \
apt-get install -y git libicu-dev libmagickwand-dev libmcrypt-dev libcurl3-dev jpegoptim
RUN pecl install imagick && \
docker-php-ext-enable imagick
RUN docker-php-ext-install intl
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install opcache
RUN docker-php-ext-install mcrypt
RUN docker-php-ext-install curl
RUN docker-php-ext-install zip
FROM php_base AS php_test
RUN pecl install xdebug
RUN docker-php-ext-enable xdebug
docker-compose.yml
version: '3.4'
services:
php:
build:
context: ./
target: php_base
php_test:
build:
context: ./
target: php_test
# ...
If you don't want to tag your first Dockerfile in order to use it in a FROM instruction in your next Dockerfile, and you are using Docker 20.10+, you can also do this:
# syntax = edrevo/dockerfile-plus
INCLUDE+ Dockerfile.base
RUN whatever
The INCLUDE+ instruction gets imported by the first line in the Dockerfile. You can read more about the dockerfile-plus at https://github.com/edrevo/dockerfile-plus
That is exactly what your FROM php:7-fpm is doing: extending the Dockerfile from the php image (with 7-fpm tag) with the contents of your Dockerfile.
So after building an image from your Dockerfile:
docker build -t my-php-base-image .
You can extend that by creating a new Dockerfile that starts with:
FROM my-php-base-image