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!
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
I'm quite new to Docker. I have a Laravel project I did using Laragon. I would like to create a Docker Compose project out of it. My problem is, when I install composer, even if the terminal is showing me no error, I can't see anything inside of the container.
What I have:
I have a docker-compose.yml with PHP and NGINX services
I have a Dockerfile for the laravel app
Here is the Dockerfile:
FROM php:7.3.19-fpm-stretch
ENV ACCEPT_EULA=Y
# Set working directory
WORKDIR /var/www
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpng-dev \
gnupg \
libjpeg62-turbo-dev \
libfreetype6-dev \
locales \
zip \
libzip-dev \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl
# Microsoft SQL Server Prerequisites
RUN apt-get update \
&& curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \
&& curl https://packages.microsoft.com/config/debian/9/prod.list \
> /etc/apt/sources.list.d/mssql-release.list \
&& apt-get install -y --no-install-recommends \
locales \
apt-transport-https \
&& echo "en_US.UTF-8 UTF-8" > /etc/locale.gen \
&& locale-gen \
&& apt-get update \
&& apt-get -y --no-install-recommends install \
unixodbc-dev \
msodbcsql17
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl
RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
RUN docker-php-ext-install gd
RUN pecl install sqlsrv pdo_sqlsrv xdebug \
&& docker-php-ext-enable sqlsrv pdo_sqlsrv xdebug
# Install composer
RUN curl -sS https://getcomposer.org/installer | \
php -- --install-dir=/usr/bin/ --filename=composer
# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/
# Run composer install
RUN composer install --no-scripts --no-autoloader
# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
# Copy existing application directory contents
COPY . /var/www
RUN composer dump-autoload --optimize
# Copy existing application directory permissions
COPY --chown=www:www . /var/www
# Change current user to www
USER www
# Expose port 9000 and
EXPOSE 9000
# Start php-fpm server
CMD ["php-fpm"]
What I get when I run docker-compose build:
[...]
Step 11/21 : RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer
---> Running in 9ee162ed2895
All settings correct for using Composer
Downloading...
Composer (version 1.10.8) successfully installed to: /usr/bin/composer
Use it: php /usr/bin/composer
Removing intermediate container 9ee162ed2895
---> dc1df86b9a7b
Step 12/21 : COPY composer.lock composer.json /var/www/
---> 7bcf92a0a647
Step 13/21 : RUN composer install --no-scripts --no-autoloader
---> Running in f1695442d1db
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Package operations: 113 installs, 0 updates, 0 removals
- Installing doctrine/inflector (2.0.3): Downloading (100%)
[...] (all composer packages seem to be installed correctly)
Step 17/21 : RUN composer dump-autoload --optimize
---> Running in 18b8c992ace9
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> #php artisan package:discover --ansi
Discovered Package: facade/ignition
Discovered Package: fideloper/proxy
Discovered Package: fruitcake/laravel-cors
Discovered Package: laravel/socialite
Discovered Package: laravel/tinker
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Discovered Package: socialiteproviders/manager
Package manifest generated successfully.
Generated optimized autoload files containing 4925 classes
Removing intermediate container 18b8c992ace9
---> d5075486971d
Step 18/21 : COPY --chown=www:www . /var/www
---> 15fcdde49457
Step 19/21 : USER www
---> Running in be9ab541543c
Removing intermediate container be9ab541543c
---> e17d1ae7a052
Step 20/21 : EXPOSE 9000
---> Running in 3e09f6279930
Removing intermediate container 3e09f6279930
---> 7a3649b9df62
Step 21/21 : CMD ["php-fpm"]
---> Running in 0db51df5de3c
Removing intermediate container 0db51df5de3c
---> fbb8e77bb8d1
Successfully built fbb8e77bb8d1
Successfully tagged digitalocean.com/php:latest
The docker-compose build sounds like it's working.
When I run docker-composer up -d and I go to http://localhost, I have a PHP error :
Fatal error: require(): Failed opening required '/var/www/public/../vendor/autoload.php' (include_path='.:/usr/local/lib/php') in /var/www/public/index.php on line 24
What I did so far:
Delete all the containers/images, rebuild
Edit the Dockerfile according to some tutorials I found on the internet
Verified that there's a vendor directory in www. Result : no.
Tried to execute composer install directly into the container (within docker exec -it <container-name> /bin/sh) : Result : /bin/sh: composer: not found.
I can't see where I'm wrong, and I don't understand where exactly does composer had installed its packages, and how to run my project...
Thanks forehand.
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
When running laravel-dusk on in a docker container on gitlab I get an error saying it cannot connect to port 9515 on localhost.
Failed to connect to localhost port 9515: Connection refused
My docker file looks as following:
# Set the base image for subsequent instructions
FROM php:7.1
# Replace shell with bash so we can source files
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
# Install packages
RUN apt-get update -yqq && apt-get install -y git wget curl libcurl4-gnutls-dev libicu-dev libmcrypt-dev libvpx-dev libjpeg-dev libpng-dev libxpm-dev zlib1g-dev libfreetype6-dev libxml2-dev libexpat1-dev libbz2-dev libgmp3-dev libldap2-dev unixodbc-dev libpq-dev libsqlite3-dev libaspell-dev libsnmp-dev libpcre3-dev libtidy-dev -yqq bzip2 libfontconfig xvfb chromium libmagickwand-dev
# Add chrome repo and install google-chrome-stable
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
RUN apt-get update
RUN apt-get install -y google-chrome-stable
# Install php environment
RUN docker-php-ext-install mbstring mcrypt pdo_mysql curl json intl gd xml zip bz2 opcache bcmath
# Install imagick
RUN pecl install imagick && docker-php-ext-enable imagick
# check installed modules
RUN php -m
# Install NVM
ENV NVM_DIR /usr/local/nvm
ENV NODE_VERSION 8.1.4
RUN curl --silent -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
# install node and npm
RUN source $NVM_DIR/nvm.sh \
&& nvm install $NODE_VERSION \
&& nvm alias default $NODE_VERSION \
&& nvm use default
# add node and npm to path so the commands are available
ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
# Install Composer Package manager
ENV COMPOSER_ALLOW_SUPERUSER 1
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && php composer-setup.php \
php -r "unlink('composer-setup.php');" && mv composer.phar /usr/local/bin/composer
# Update packages
RUN apt-get update
# Xdebug
RUN pecl install -o -f xdebug \
&& rm -rf /tmp/* \ && docker-php-ext-enable xdebug
# Clear out the local repository of retrieved package files
RUN apt-get clean
# Install Laravel Envoy
RUN composer global require "laravel/envoy=~1.0"
# confirm installed versions
RUN node -v
RUN npm -v
RUN php -v
RUN google-chrome-stable --version
RUN composer --version
RUN php -m
EXPOSE 9515
Then my gitlab-ci file looks like the following:
image: registry.gitlab.com/path-to-repo/repo-name:latest
# Select what we should cache
cache:
paths:
- vendor/
services:
- mysql:5.7
variables:
# Configure mysql service (https://hub.docker.com/_/mysql/)
MYSQL_DATABASE: database-name
MYSQL_ROOT_PASSWORD: database-password
DB_HOST: mysql
DB_USERNAME: root
stages:
- test
unit_test:
stage: test
script:
- cp .env.runnable .env
- composer install
- php artisan config:clear
- php artisan key:generate
- php artisan migrate --seed
- php artisan db:seed --class=TestSeeder
- vendor/bin/phpunit --coverage-text --colors=never
- php artisan env
- php artisan dusk
At first I thought it was because I was not exposing port 9515, but I have exposed this in the Dockerfile. However, now I have no idea what the problem could be. Is there an issues that this port is used for another process? Could it be that the Chromedriver is running on a different port?
In your gitlab-ci file try to replace php artisan dusk with:
php artisan serve & php artisan dusk
I was getting the 9515 connection refused error and then I found this GitHub issue and added these dependencies to my dockerfile (granted Im using custom ubuntu image). I didn't need to add anything else that the GitHub comment mentions (no script etc).
FROM ubuntu:18.04
# ... my other previous dependencies (PHP, etc.)
RUN apt-get update && \
apt-get -y install libxpm4 libxrender1 libgtk2.0-0 libnss3 libgconf-2-4 && \
apt-get -y install chromium-browser && \
apt-get -y install xvfb gtk2-engines-pixbuf && \
apt-get -y install xfonts-cyrillic xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable && \
apt-get -y install imagemagick x11-apps && \
apt-get upgrade -y && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
Also, for local development I needed to update my .env (or use .env.dusk.local) APP_URL: to point to my docker host.
APP_URL=host.docker.internal:8000
For GitLab, you can try and update your .env APP_URL with the docker host by adding an additional setup in a before_script (after copying .env.example to .env). (host.docker.internal is not available in docker for linux). Also, Note your container will need net-tools for the netstat command.
before_script:
# ...
- docker_host=$(netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}') && sed -i "s|APP_URL=http://0.0.0.0|APP_URL=http://${docker_host}|" .env
Where APP_URL=http://0.0.0.0 is the value of what is already in your existing .env file.
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