Docker images/nginx-php: Difference between revisions
Line 62: | Line 62: | ||
== Deprecation == | == Deprecation == | ||
=== PHP 5 === | |||
We provide a nginx-php-fpm PHP 5 image, but it's still running under Debian Jessie while PHP 7 and 8 images use recent Debian distro, for example Debian Bullseye as of February 2022. | |||
=== runsvdir-init === | === runsvdir-init === | ||
Revision as of 15:05, 13 February 2022
The nasqueron/nginx-php-fpm and nasqueron/nginx-php7-fpm images provide a solution to run PHP applications as a standalone container.
Project goals
While Java, Ruby, Go and Python applications ship with their own server, PHP applications generally needs a webserver to call a FastCGI process, and handle static data. This make harder to adhere to the twelve-factor app methodology.
Meanwhile Docker encourages to run each process in their own container. As such we want to provide 3 options:
- Easy deployment of a unique container for the application listening to the port 80: runit, nginx, php-fpm [DONE, IN PROD]
- Deployment of a service composed of two containers, one per process: the same image can be used for both nginx and php-fpm containers. [DONE, READY FOR TESTING]
- Deployment of only php-fpm, and a standard to publish metadata so a front-end can pick configuration. [UNDER INVESTIGATION]
The PHP offers a fairly comprehensive distribution, providing standard extensions like MySQL and PostgreSQL drivers, XML and internalization ones. We also provide widely used composer and APCu.
Howto
Serve a PHP application located inside a container
Write a Dockerfile deploying your application to /var/wwwroot/default,
and start with FROM nginx-php7-fpm:novolume
to use our image.
Your files should be readable by the user 'app', with uid 431.
You can find an example for a generic Laravel application at https://github.com/nasqueron/docker-pixelfed.
Serve a PHP application living in a host directory
On your machine, you've a Docker engine, a directory with your PHP application, and you want to quickly run it in a container.
$ docker run -d -it -v '/path/to/your/application:/var/wwwroot/default' -p 8080:80 nasqueron/nginx-php7-fpm
Your application is now ready to http://localhost:8080.
If you need to test a specific nginx configuration, you can also mount a volume with a complete nginx configuration folder as /etc/nginx.
Run standalone nginx and php-fpm containers
If you use docker-compose, Docker Swarm or Kubernetes, you can maintain the application as a set of containers:
- a container
app-backend
to host the php-fpm FastCGI process - a container
app-nginx
for nginx to serve static content and call php-fpm - the same image for both, to provide them a consistent set of files for your application
To make your image compatible with this method, there are a few preparations to do.
First, your nginx configuration MUST define a hostname to call app-phpfpm: fastcgi_pass app-backend:9000
. If you use localhost, for example with fastcgi_pass 127.0.0.1:9000;
, it will try to find your php-fpm process in the same container.
Then, your application interacts with user-writable content, your application SHOULD have a separate volume for the content directories, volume shared by both containers. For example if you allow to upload images, this volume could be used by PHP to handle the actual upload and a thumbnail creation, and by nginx to serve the images.
Your containers can then be run with the following commands:
- app-backend: a bootstrapping script calling
/usr/local/sbin/php-fpm --nodaemonize
- app-nginx:
/usr/sbin/nginx
We're interested to document this method ease of use in production and identify pitfalls. You can reach Dereckson for assistance in such a deployment.
Run only php-fpm
If your infrastructure uses configuration as code, you can avoid front-end > nginx > php-fpm, especially if your front-end proxy server is also nginx, or because haproxy added FastCGI support.
As such, you can focus to run the php-fpm process, and delegate configuration to your front-end proxy.
A difficulty of this method is your front-end container needs access to the volume containing static assets like JS or CSS pages, and such assets are often inside a container. The application code should make a clear separation between PHP code and JS/CSS/images/other static assets part, and you need to have a specific volume mounted in your proxy with that content.
Deprecation
PHP 5
We provide a nginx-php-fpm PHP 5 image, but it's still running under Debian Jessie while PHP 7 and 8 images use recent Debian distro, for example Debian Bullseye as of February 2022.
runsvdir-init
The Debian package runit
offered a runsvdir-init
to call runit with a standard service directory, /etc/service
. It also cleaned up the environment.
Several PHP applications images depend of it, calling it at the end of their initialization script. To maintain backwards compatibility of those scripts, the docker-php7-fpm image provides an equivalent script, with a deprecation notice.
You can replace your runsvdir-init line by:
/usr/bin/runsvdir -P /etc/service
If you've specified it as entrypoint, CMD ['/usr/bin/runsvdir', '-P', '/etc/service']
could be used, but that's the default entrypoint of the image and as such isn't needed.