I have this container that I ran with a docker-compose.yml file.
version: '3'
services:
db:
<...>
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
I need to enable LDAP on PHP but I really can't find out how to complete the steps explained in the tutorial.
You will need to use the --with-ldap[=DIR] configuration option when
compiling PHP to enable LDAP support.
How am I supposed to do this on a running container ? Should this be done before running docker-compose up if so, which environment configuration am I supposed to use ?
You just have to use a different image as it's not easily configurable using the original image.
Have a look at dalareo/docker-wordpress-ldap-support on GitHub. You might use this Dockerfile by downloading it to the directory your project would be stored in and make a small change to your docker-compose.yml like here:
version: '3'
services:
db:
<...>
wordpress:
depends_on:
- db
# remove: image: wordpress:latest and put this instead:
build: .
# and place the rest of the definitions you normally have there
The Dockerfile copied from the repo:
FROM wordpress
RUN set -x \
&& apt-get update \
&& apt-get install -y libldap2-dev \
&& rm -rf /var/lib/apt/lists/* \
&& docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ \
&& docker-php-ext-install ldap \
&& apt-get purge -y --auto-remove libldap2-dev
edit
I've found a public registry image build from this Dockerfile
Now you don't actually have to make any changes to your original docker-compose.yml file except for changing the image your wordpress is expected to run from. From wordpress:latest to dalareo/wordpress-ldap
Related
I am trying to automate the development of a project I am currently working on by creating a container on Docker that is composed of mysql, php and nginx to run a Symfony project. Here is my docker-compose.yml
services:
database:
container_name: database
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: rapidhcm
MYSQL_USER: admin
MYSQL_PASSWORD: password
ports:
- '4306:3306'
volumes:
- ./docker/mysql:/var/lib/mysql
php:
container_name: php
build:
context: .
ports:
- '9000:9000'
volumes:
- ./rapid-backend:/var/www/public
depends_on:
- database
nginx:
container_name: nginx
image: nginx:stable-alpine
ports:
- '8080:80'
volumes:
- ./rapid-backend:/var/www/public
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
- database
And here is my Dockerfile:
FROM php:8.0-fpm
RUN apt update \
&& apt install -y zlib1g-dev g++ git libicu-dev zip libzip-dev zip \
&& docker-php-ext-install intl opcache pdo pdo_mysql \
&& pecl install apcu \
&& docker-php-ext-enable apcu \
&& docker-php-ext-configure zip \
&& docker-php-ext-install zip
WORKDIR /var/www/html
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN curl -sS https://get.symfony.com/cli/installer | bash
RUN mv /root/.symfony5/bin/symfony /usr/local/bin/symfony
RUN git config --global user.email "email#email.com" \
&& git config --global user.name "Damian Kowalski"
The Dockerfile and docker-compose.yml files are in the root folder of the project, however the Symfony index.php file is situated in ./rapid-backend/public/index.php. How can I indicate that I want to serve that php file?
You would typically use only two containers: one for the database and one for the php-enabled web server.
You start from an php+apache image or an nginx image with php installed. Then you can bind-mount the web server's configuration files just as you did in your docker-compose.yaml for the nginx container.
You'd have something like this in your Dockerfile:
FROM php:8.2-apache AS production
ADD default.conf /etc/apache2/sites-available/default.conf
RUN # <...>
# Install tools and PHP dependencies
# apt-get update && \
# apt-get install -y <...> && \
# Configure docker php extensions, see image documenation on dockerhub
# docker-php-ext-configure <...> && \
# docker-php-ext-install <...> && \
# Maybe you want xdebug? In that case you'll also want to copy a .ini file
# pecl install xdebug && \
# Cleanup
# docker-php-source delete && \
# Install latest composer 2
# curl https://getcomposer.org/composer-2.phar > /usr/local/bin/composer && \
# chmod +x /usr/local/bin/composer && \
# Enable some apache mods if needed
# a2enmod rewrite headers expires xsend && \
# Some more cleanup if needed
# apt-get remove -y <...> && \
# apt-get clean
# If this image is to be used in a development environment, here you may want to create a user that you'll tell Apache to use with APACHE_RUN_USER, using the same UID as your own user on your host, so that you can bind-mount your sources in your docker-compose.yaml file without having permission issues.
# If however this is a deployment image, here you will probably want to "COPY" your source code in the image and to "RUN composer install".
with the appropriate apache configuration file default.conf that exposes your index.php (see the Symfony documentation at https://symfony.com/doc/current/setup/web_server_configuration.html for example configuration files).
Then your web server service in docker-compose.yaml could look like:
web-server:
build:
context: .
ports:
- '8080:80'
# If this is a dev environment, bind mount your source code, maybe also
# have a "user: ..." option here if you created one in the Dockerfile
volumes:
- ./rapid-backend:/var/www/public
It's a pretty open question but I hope this is a push in the right direction. Starting from here you can use docker-compose exec to run a bash shell inside your web server, and use composer to install Symfony and initialize your project.
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)'
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
When starting the containers, you will need to instruct docker-compose to rebuilt the dockerfile.
Try this:
docker-compose up --build --force-recreate
I need to call composer install and unsure from which Dockerfile to call it from - Dockerfile-apache or Dockerfile-php-fpm?
Should I install composer in Dockerfile-apache (and PHP CLI?) and run it from there?
Running composer install from Dockerfile-php-fpm gives me this: Composer could not find a composer.json file in /var/www/html
Docker-php-fpm
# Do we target a specific version? ie. 7.4.25?
FROM php:7.4-fpm
# Need to add zip and other extensions
RUN buildDeps=" \
libonig-dev \
libzip-dev \
libxml2-dev \
" \
&& apt-get -y update \
&& apt-get install -y $buildDeps zip libicu-dev \
&& docker-php-ext-configure intl \
&& docker-php-ext-install intl mbstring json mysqli opcache pdo pdo_mysql xml \
&& apt-get purge -y --auto-remove $buildDeps \
&& rm -r /var/lib/apt/lists/*
# Copying of base conf files
COPY docker/php-fpm/conf/php-fpm.conf /usr/local/etc
COPY docker/php-fpm/conf/php.ini-development /usr/local/etc/php/php.ini
COPY docker/php-fpm/conf/www.conf /usr/local/etc/php-fpm.d
# Install Composer.
RUN curl -sS https://getcomposer.org/installer | php \
&& mv composer.phar /usr/local/bin/ \
&& ln -s /usr/local/bin/composer.phar /usr/local/bin/composer
EXPOSE 9000
Docker-apache:
FROM httpd:2.4
# Copy config files
COPY docker/apache/conf/httpd.conf /usr/local/apache2/conf
COPY docker/apache/conf/httpd-vhosts.conf /usr/local/apache2/conf/extra
# Do something about log rotate?
# Create vhost directory
WORKDIR /var/www/html
#Set our application folder as an environment variable
ENV APP_HOME /var/www/html
#copy files
COPY bin ${APP_HOME}/bin
COPY config ${APP_HOME}/config
COPY plugins ${APP_HOME}/plugins
COPY src ${APP_HOME}/src
COPY webroot ${APP_HOME}/webroot
COPY .htaccess ${APP_HOME}
COPY index.php ${APP_HOME}
COPY composer.json ${APP_HOME}
COPY composer.lock ${APP_HOME}
Edit #1
docker-compose.yml
version: "3.2"
services:
php-fpm:
container_name: php-fpm
build:
context: .
dockerfile: Dockerfile-php-fpm
networks:
- backend
ports:
- "9000:9000"
apache:
container_name: httpd
build:
context: .
dockerfile: Dockerfile-apache
depends_on:
- php
networks:
- frontend
- backend
ports:
- "80:80"
- "443:443"
networks:
frontend:
backend:
Edit #2
This docker-compose file enables the communication via a common volume. I just need to compile, build and copy the files in Apache at this point.
version: "3.9"
services:
php-fpm:
container_name: php-fpm
build:
context: .
dockerfile: Dockerfile-php-fpm
volumes:
- mydata:/var/www/html:rw
networks:
- backend
ports:
- "9000:9000"
apache:
container_name: httpd
build:
context: .
dockerfile: Dockerfile-apache
depends_on:
- php
volumes:
- mydata:/var/www/html:rw
networks:
- frontend
- backend
ports:
- "80:80"
- "443:443"
networks:
frontend:
backend:
volumes:
mydata:
I would go with neither of the above; instead, run composer install locally and copy the resulting vendor directory as part of your application.
Fetching dependencies is fundamentally part of building an application, not part of running it, so Composer shouldn't even be installed on a production host or container. If you were writing a C application which needed to be compiled with gcc, you would run that as an earlier step, and then copy the binary into the container; composer install can be treated the same way.
So for instance, you might have a build script (to run manually, or in a CI server like Jenkins, Github Actions, Azure DevOps, etc) that went through the following steps:
Clone the repo from a git repository
Check out the latest tag
Run composer install
Run a script to minify the client-side JS
Run docker-composer, copying the source code, minified JS, and vendor directory
The software inside the Docker container therefore only needs to be able to run the application, not build it.
docker-compose.yml
version: '3.7'
services:
php:
build:
context: .
dockerfile: Dockerfile
image: php:7.3-rc-fpm
container_name: php_7.3-rc-fpm
volumes:
- .:/var/www/app
restart: unless-stopped
working_dir: /var/www
stdin_open: true
tty: true
Dockerfile
FROM php:7.3-rc-fpm
RUN apt-get update && apt-get install -y \
build-essential \
mysql-client \
locales \
zip \
vim \
unzip \
git \
curl
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring zip pcntl
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Copy existing application directory permissions
COPY --chown=www:www . /var/www
# Change current user to www
USER www
Started containers with
docker-compose up -d
and when I execute
docker-compose exec php bash
followed by
mysql --version
result in
bash: mysql: command not found
the mysql-client is missing and the others RUNs installation as well...
Any idea what is going on?
....and stackoverflow need more details to approve my edit when I don't have any ............
image: php:7.3-rc-fpm should be dropped.
It tells docker-compose to build from the "php_7.3-rc-fpm" image and not from the image build with your Dockerfile (it's a question of precedence). So it's normal that nothing you ask to install in the Dockerfile is available...
I tested to be sure and indeed, if you drop this line, the commands docker-compose exec php bash followed by mysql --version gives you what you expected.
You are misusing container image name. In your docker-compose.yml you tell:
services:
php:
build:
context: .
dockerfile: Dockerfile
image: php:7.3-rc-fpm
That you want to build your own image and name it php:7.3-rc-fpm! But this is not your image' name - it is the name of a well-known php docker container! And in your Dockerfile you inherits from it:
FROM php:7.3-rc-fpm
So, you are overwriting public image but your own. And I can only guess, what will be the new image like..
Solution - remove image from your docker-compose file. It is not the image to be used, it is the name you want to give your image after being built, upon used in conjunction with build properties.
I am a beginner with docker and docker-compose and i need your help.
I'm making PHP-NGINX-PostgresSQL symfony developement environment using docker-compose.
Here it is :
web:
image: nginx:1.13.5
ports:
- "80:80"
volumes:
- ./html:/html
- ./site.conf:/etc/nginx/conf.d/default.conf
links:
- php
php:
image: php:7-fpm
volumes:
- ./html:/html
links:
- postgres
postgres:
image: postgres:9.6.5
ports:
- "5432:5432"
environment:
POSTGRES_PASSWORD: postgres
Now, i would like to install php7.2-intl into my php container. So i would like to execute something like :
$ sudo LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php
$ sudo apt-get update
$ sudo apt-get install php7.2-intl
Could you help me? I'm really stuck and also I dont have a Dockerfile file, just a docker-compose.yml file.
To get a PHP docker container with the intl extension, you need to extend the official PHP image.
To do so, declare the use of your own Dockerfile for your PHP image in docker-compose.yml:
services:
php:
# Remove this line
# image: php:7-fpm
# Add this one instead
build: './docker/php'
# ...
Then, add the following Dockerfile file to the docker/php folder:
FROM php:7.1-fpm
RUN apt-get update && apt-get install -y \
libicu-dev \
&& docker-php-ext-install \
intl \
&& docker-php-ext-enable \
intl
You can now run docker-compose build to get your PHP container built with the Intl extension.
A few notes:
I prefer to explicitly tell which PHP version I use (here "7.1.x") rather than the more generic "7.x" you defined with php:7-fpm.
I preferred to use the docker-php-ext-install and docker-php-ext-enable command utilities provided by the PHP official image (see "How to install more PHP extensions" section in the PHP image documentation).