I had a need to use phpLDAPadmin, so I set up Nginx and PHP with Docker Compose and ran it there.
This is a template memo for myself to prepare Nginx with PHP running on Docker Compose for the next time I want to use PHP on the web again.
Since we went to the trouble, we added MySQL to the LEMP environment for ease of use later on.
...but I'm not doing much, just creating a container with both Nginx and PHP installed as a web server.
configuration
Web
- Nginx and PHP running
- Install "phpinfo()" and "phpMyAdmin" for operation test
MySQL
- Data is stored externally with VOLUME
template
docker-compose.yaml
- Web server uses Dockerfile to create its own image
- I have an image of MySQL from the official version. The version is 8 (I later got into trouble because of this version...)
version: "3" services: web: build: "./web" ports: - 80:80 mysql: image: mysql command: --default-authentication-plugin=mysql_native_password volumes: - mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSOWRD: rootpassword # phpmyadmin: # image: phpmyadmin/phpmyadmin # environment: # PMA_HOST: mysql # ports: # - 8080:80 volumes: mysql-data:
Dockerfile
Dockerfile for the web server. /web/".
FROM php:fpm RUN apt-get update # install php extension RUN docker-php-ext-install mysqli && \ docker-php-ext-enable mysqli # install Nginx RUN apt-get -y install nginx COPY default /etc/nginx/sites-enabled/default # test contents COPY phpinfo.php /var/www/html/phpinfo.php COPY phpMyAdmin/ /var/www/html/phpMyAdmin/ # run Nginx & PHP COPY start.sh /start.sh RUN chmod 744 /start.sh EXPOSE 80 CMD ["/start.sh"]
default
Modify the Nginx configuration file so that PHP will run.
... location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass localhost:9000; } ...
start.sh
Scripts to be executed on the web server, starting PHP and Nginx.
#!/bin/bash
nginx
php-fpm
operation test
http://localhost
http://localhost/phpinfo.php
http://localhost/phpMyAdmin/index.php
supplementary explanation
Web: Nginx+PHP
I wanted to run Nginx and PHP in the same container, so I created an image using Dockerfile.
Either can be used as a base, but here, Nginx is installed based on the PHP image.
In order to run Nginx and PHP at the same time, a script "start.sh" is created to call them and is called by CMD.
The command nginx
is executed in the background and the command php-fpm
is executed in the foreground, so if you execute them in the order "nginx->php-fpm", the "start.sh" process will persist with both Nginx and PHP running.
If you want to reverse the order of execution, run php-fpm
in the background and use the deamon off
option to run nginx
in the foreground, as in the Nginx Dockerfile.
#!/bin/bash php-fpm & nginx -g deamon off
PHP Extension Modules
To install PHP extensions with Docker PHP images
RUN apt-get install php-xxx
does not mean that
RUN docker-php-ext-install xxx
and use a dedicated command.
Install with RUN docker-php-ext-install <extension_name>
and make available with RUN docker-php-ext-enable <extension_name>
.
When installing, even if there are dependencies, the library installation is not automatic, so you must install the related libraries yourself and then install the PHP extension module.
For example, "phpLDAPadmin" uses "php-ldap", "php-xml", and "php-gettext" PHP extension modules, but those PHP extension modules require "libldap2-dev" and "libxml2-dev", so the following description I had to describe them in the Dockerfile and install them.
# install php-ldap RUN apt-get install libldap2-dev -y && \ docker-php-ext-install ldap && \ docker-php-ext-enable ldap # install php-xml RUN apt-get install libxml2-dev -y && \ docker-php-ext-install xml && \ docker-php-ext-enable xml # install php-gettext RUN docker-php-ext-install gettext && \ docker-php-ext-enable gettext
MySQL
Starting with MySQL version 8, the default authentication plugin has changed from "mysql_native_password" in version 5 and earlier to "caching_sha2_password".
PHP's MySQL library does not yet support "caching_sha2_password" and I get the following error when I try to log in using phpMyAdmin.
The server requested authentication method unknown to the client
The default authentication plugin can be changed with the mysqld
option, which is changed with "command" in "docker-compose.yaml".
command: --default-authentication-plugin=mysql_native_password
However, the default authentication plugin setting by option is only valid when MySQL is built for the first time, and once built, it will not be reflected even if the option is changed later.
In particular, note that if you use Volume to store data externally and change the settings after the initial build, the container will exit with an error.
Since the authentication plugin settings can be configured on a per-user basis, it is possible to change the authentication plugin to "mysql_native_password" for users accessing with PHP after the initial MySQL build, instead of dealing with the default authentication plugin settings. (We omitted that method here.)
Impressions, etc.
Nginx+PHP
Essentially, it would be a Docker-like configuration to separate the Nginx and PHP containers.
However, if the containers are separated, PHP files need to be placed on the PHP container side, not on the Nginx side. On the other hand, html and image files other than PHP files are placed on the Nginx side, so in the case of an application like phpMyAdmin, which is distributed with PHP, HTML, images, etc. in one folder, you need to place copies in both Nginx and PHP containers.
However, it is tempting to put all the folders in one place and be done with it. In this case, we can use volume to share the content folder between the Nginx and PHP containers.
docker-compose.yamlSo, here's what it looks like.
version: "3" services: nginx: build: "./nginx" ports: - 80:80 volumes: - ./share/:/usr/share/nginx/html/ php: build: "./php" volumes: - ./share/:/var/www/html/
I first tried building it that way, but this time I did not want to separate the content from the container and make it persistent; rather, I wanted to package the content solidly within the container, so I ended up packing Nginx, PHP, and content into a single container.
When using a volume, when a problem occurs, the contents of the volume may not actually be the same, even though we thought we were doing things under the same conditions, and we may get stuck without realizing it.
phpMyAdmin
Here, we have tried running "phpMyAdmin" on the web server as a PHP sample, but since the image of phpMyAdmin is distributed, it is easier to use it directly. (For reference, I have included it in the commented-out section of the Dockerfile, so if you uncomment it, you will be able to access phpMyAdmin directly on port 8080)
Other
I was most addicted to the MySQL related stuff, which I thought I added as an extra....
I see that the WITH clause and window functions are now available in MySQL version 8! I learned something good!
Reference Articles
- https://dev.mysql.com/doc/refman/5.6/en/server-options.html#option_mysqld_default-authentication-plugin
- https://medium.com/@crmcmullen/how-to-run-mysql-8-0-with-native-password-authentication-502de5bac661
- https://stackoverflow.com/questions/52364415/php-with-mysql-8-0-error-the-server-requested-authentication-method-unknown-to
- https://qiita.com/ucan-lab/items/3ae911b7e13287a5b917
- https://www.s-style.co.jp/blog/2018/05/1807/
- https://employment.en-japan.com/engineerhub/entry/2018/09/18/110000
- https://qiita.com/bossunn24/items/85ca5c3bfbba07b4e0cc
- https://qiita.com/bzy/items/f251d47cba836a3a92df
- https://hub.docker.com/_/mysql
- https://hub.docker.com/_/php