diff --git a/README.md b/README.md index 177c5ba..8457d6b 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,8 @@ All being based on the official images we provide: - PHP cli - Compiled without php-fpm, a simple php binary image - PHP fpm - Specifically designed to share the php-fpm socket towards a fastcgi compliant web sever -- Nginx - Meant for PHP projects built on the PHP FPM image in this repository, since it looks for a php-fpm socket and doesn't have access to the PHP code +- Nginx - Meant for PHP projects built on the PHP FPM image in this repository, since [it looks for a php-fpm socket +and doesn't have access to the PHP code](docs/adr/0002-nginx-configuration-is-shaped-for-php-needs.md) The fpm/HTTP server relationship: @@ -70,13 +71,15 @@ All images are based on their official variants, being: ## Alpine Linux situation -Even though both of the images are based on the Alpine Linux, the PHP official repository gives us the option to choose between its versions, at this moment being `3.7` or `3.8`. +Even though both of the images are based on the Alpine Linux, the PHP official repository gives us the option to choose +between its versions, at this moment being `3.8` or `3.9`. -Meanwhile on the official Nginx images we have no control over which Alpine version we use, this explains the tagging strategy coming in the next section. +Meanwhile on the official Nginx images we have no control over which Alpine version we use, this explains the tagging +strategy coming in the next section. ## The available tags -The docker registry prefix is `usabillabv/php`, thus `usabillabv/php:OUR-TAGS` +The docker registry prefix is `usabillabv/php`, thus `usabillabv/php:OUR-TAGS`. In order to provide upgrade path we intend to keep one or more versions of PHP and Nginx. @@ -86,17 +89,21 @@ The tag naming strategy consists of (Read as a regex): - PHP: `(phpMajor).(phpMinor)-(cli|fpm)-(alpine|future supported OSes)(alpineMajor).(alpineMinor)(-dev)?` - Example: `7.2-fpm-alpine3.8`, `7.2-fpm-alpine3.8-dev` - - Note: The minor version might come followed by special versioning constraints in case of betas, etc. For instance: `7.3-rc-fpm-alpine3.8-dev` + - Note: The minor version might come followed by special versioning constraints in case of betas, etc. For instance + `7.3-rc-fpm-alpine3.8-dev` - Nginx: `nginx(major).(minor)(-dev)?` - Example: `nginx1.15`, `nginx1.15-dev` ## Adding more supported versions -The whole CI/CD pipeline is centralized in Makefile targets, the build of cli, fpm and http (for now only nginx) images have their targets named as `build-cli`, `build-fpm` and `build-http` +The whole CI/CD pipeline is centralized in Makefile targets, the build of cli, fpm and http (for now only nginx) images +have their targets named as `build-cli`, `build-fpm` and `build-http`. -With the help of building scripts the addition of new versions is as easy as updating the Makefile with the desired new version. +With the help of building scripts the addition of new versions is as easy as updating the Makefile with the desired new +version. -All the newly built versions are going to be automatically tagged and pushed upon CI/CD success, to see the output of your new changes you can see the `(BUILD).tags` file in the `tmp` directory +All the newly built versions are going to be automatically tagged and pushed upon CI/CD success, to see the output of +your new changes you can see the `(BUILD).tags` file in the `tmp` directory. ### PHP @@ -142,16 +149,19 @@ build-http: clean-tags ### Important -Removing a version from the build won't make it be removed from Docker registry, this has to be a manual operation if desired. +Removing a version from the build will not remove it from the Docker registry, this has to be done manually when desired. ## Using and extending ### PHP FPM healthcheck -This image ships with the [php-fpm-healthcheck](https://github.com/renatomefi/php-fpm-healthcheck) which allows you to healthcheck FPM apart from the Nginx setup, providing more compatibility with [the single process Docker container](https://cloud.google.com/solutions/best-practices-for-building-containers#package_a_single_app_per_container). +This image ships with the [php-fpm-healthcheck](https://github.com/renatomefi/php-fpm-healthcheck) which allows you to +healthcheck FPM independently of the Nginx setup, providing more compatibility with [the single process Docker +container](https://cloud.google.com/solutions/best-practices-for-building-containers#package_a_single_app_per_container). -This healthcheck provides diverse metrics to be watch and can be configured according to your needs. -More information on how to use it can be found in the [official documentation](https://github.com/renatomefi/php-fpm-healthcheck#a-php-fpm-health-check-script). +This healthcheck provides diverse metrics to watch and can be configured according to your needs. +More information on how to use it can be found in the +[official documentation](https://github.com/renatomefi/php-fpm-healthcheck#a-php-fpm-health-check-script). The healthcheck can be found in the container `$PATH` as an executable: @@ -171,7 +181,8 @@ Simply use the images as base of the application's `Dockerfile` and apply the ne FROM usabillabv/php:7.3-fpm-alpine3.9 ``` -In usual cases it might not be necessary to extend the nginx images, unless you desire to extend its behavior by for instance serving static files. +In usual cases it might not be necessary to extend the nginx images, unless you desire to extend its behavior, for +instance to serve static files. [Nginx customization](#for-nginx-customization) @@ -181,7 +192,9 @@ In usual cases it might not be necessary to extend the nginx images, unless you ### Document root configuration -Nginx is configured with only one virtual host, which is using `/opt/project/public` as document root. Ideally we should change this configuration to point to the `public` directory of our project, so that we expose only what's necessary. +Nginx is configured with only one virtual host, which is using `/opt/project/public` as the document root. Ideally we +should change this configuration to point to the `public` directory of our project, so that we expose only what's +necessary. In order to do this you should override `NGINX_DOCUMENT_ROOT` environment variable in the `Dockerfile`, e.g.: @@ -194,7 +207,8 @@ ENV NGINX_DOCUMENT_ROOT="/project/public" ### Server name configuration -The default server name is `localhost` and that can also be overridden using an environment variable (`NGINX_SERVER_NAME`) in the `Dockerfile`, e.g.: +The default server name is `localhost` and that can also be overridden using an environment variable +(`NGINX_SERVER_NAME`) in the `Dockerfile`, e.g.: ```Dockerfile ENV NGINX_SERVER_NAME="myawesomeservice myawesomeservice.usabilla.com" @@ -202,9 +216,11 @@ ENV NGINX_SERVER_NAME="myawesomeservice myawesomeservice.usabilla.com" ### Workers -To use the most of your server you can tweak the number of nginx workers and connections accepted by them, the default values are (respectively): `1` and `1024`. +To use the most of your server you can tweak the number of nginx workers and connections accepted by them, the default +values are (respectively): `1` and `1024`. -These values can be overridden using environment variables (`NGINX_WORKERS_PROCESSES` and `NGINX_WORKERS_CONNECTIONS`) in the `Dockerfile`, e.g.: +These values can be overridden using environment variables (`NGINX_WORKERS_PROCESSES` and `NGINX_WORKERS_CONNECTIONS`) +in the `Dockerfile`, e.g.: ```Dockerfile ENV NGINX_WORKERS_PROCESSES="4" @@ -212,27 +228,29 @@ ENV NGINX_WORKERS_CONNECTIONS="2048" ``` Documentation for [worker_processes](http://nginx.org/en/docs/ngx_core_module.html#worker_processes) -and [worker_connections](http://nginx.org/en/docs/ngx_core_module.html#worker_connections) +and [worker_connections](http://nginx.org/en/docs/ngx_core_module.html#worker_connections). ### Connection keep alive timeout -The default `keepalive_timeout` is `75` and that can also be overridden using an environment variable (`NGINX_KEEPALIVE_TIMEOUT`) in the `Dockerfile`, e.g.: +The default `keepalive_timeout` is `75` and that can also be overridden using an environment variable +(`NGINX_KEEPALIVE_TIMEOUT`) in the `Dockerfile`, e.g.: ```Dockerfile ENV NGINX_KEEPALIVE_TIMEOUT="30" ``` -More about it in the [Official documentation](http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout) +More about it in the [Official documentation](http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout). ### Client body buffer size -The default `client_body_buffer_size` is `8k|16k` (depending on architecture), having it configurable helps to not create disk body buffers in apps that don't splitting it, e.g.: +The default `client_body_buffer_size` is `8k|16k` (depending on architecture), having it configurable helps to not +create disk body buffers in apps that don't splitting it, e.g.: ```Dockerfile ENV NGINX_CLIENT_BODY_BUFFER_SIZE="64k" ``` -More about it in the [Official documentation](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) +More about it in the [Official documentation](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size). ### Client max body size @@ -243,7 +261,7 @@ larger payloads, e.g.: ENV NGINX_CLIENT_MAX_BODY_SIZE="8m" ``` -More about it in the [Official documentation](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size) +More about it in the [Official documentation](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size). ### Large client header buffers @@ -254,7 +272,7 @@ increase it in case of larger header payloads, e.g.: ENV NGINX_LARGE_CLIENT_HEADER_BUFFERS="8 128k" ``` -More about it in the [Official documentation](http://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers) +More about it in the [Official documentation](http://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers). ### Expose Nginx version @@ -270,13 +288,15 @@ ENV NGINX_EXPOSE_VERSION="on" ### Installing & enabling PHP extensions -This image bundles helper scripts to manage PHP extensions (`docker-php-ext-configure`, `docker-php-ext-install`, and `docker-php-ext-enable`), so it's quite simple to install core and PECL extensions. +This image bundles helper scripts to manage PHP extensions (`docker-php-ext-configure`, `docker-php-ext-install`, and +`docker-php-ext-enable`), so it's quite simple to install core and PECL extensions. -More about it in the [Official Documentation](https://github.com/docker-library/docs/blob/master/php/README.md#how-to-install-more-php-extensions) +More about it in the [Official Documentation](https://github.com/docker-library/docs/blob/master/php/README.md#how-to-install-more-php-extensions). #### PHP Core extensions -To install a core extension that doesn't require any change on the way PHP was compiled you only need to use `docker-php-ext-install`, which will compile the extra extension and enable it. +To install a core extension that doesn't require any change in the way PHP is compiled you only need to use +`docker-php-ext-install`, which will compile the extra extension and enable it. To do it should include something like this to your `Dockerfile`: @@ -311,9 +331,11 @@ RUN set -x \ #### PECL extensions -Some extensions are not provided with the PHP source, but are instead available through [PECL](https://pecl.php.net/), see a full list of them [here](https://pecl.php.net/packages.php). +Some extensions are not provided with the PHP source, but are instead available through [PECL](https://pecl.php.net/), +see a full list of them [here](https://pecl.php.net/packages.php). -To install a PECL extension, use `pecl install` to download and compile it, then use `docker-php-ext-enable` to enable it: +To install a PECL extension, use `pecl install` to download and compile it, then use `docker-php-ext-enable` to enable +it: ```Dockerfile # Installs ast extension (temporarily adding the necessary libraries): @@ -344,7 +366,9 @@ RUN set -x \ #### Common extension helper scripts -Some extensions are used across multiple projects but can have some complexities while installing so we ship helper scripts with the PHP images to install dependencies and enable the extension. The following helper scripts can be run inside projects' Dockerfile: +Some extensions are used across multiple projects but can have some complexities while installing so we ship helper +scripts with the PHP images to install dependencies and enable the extension. The following helper scripts can be run +inside projects' Dockerfile: - `docker-php-ext-rdkafka` for RD Kafka - `docker-php-ext-pdo-pgsql` for PDO Postgres @@ -355,9 +379,10 @@ Since [Xdebug](https://xdebug.org) is a common extension to be used we offer two ##### Dev image -Use the `dev` image by appending `-dev` to the end of the tag, like: `usabillabv/php:7.3-fpm-alpine3.9-dev` +Use the `dev` image by appending `-dev` to the end of the tag, like: `usabillabv/php:7.3-fpm-alpine3.9-dev`. -Not recommended if you're layering with your production images, using a different base image doesn't allow to you share cache among your Dockerfile targets. +Not recommended if you're layering with your production images, using a different base image doesn't allow to you share +cache among your Dockerfile targets. We ship the image with a dev mode helper, which can install Xdebug and configure it. @@ -369,9 +394,10 @@ Installing and enabling the extensions $ docker-php-dev-mode xdebug ``` -We also provide some default configuration to make it easier to start your debugging session, you can enable it also via the helper script. +We also provide some default configuration to make it easier to start your debugging session, you can enable it also via +the helper script. -The contents of the configuration can be found [here](src/php/conf/available/xdebug.ini) +The contents of the configuration can be found [here](src/php/conf/available/xdebug.ini). ```console $ docker-php-dev-mode config @@ -379,13 +405,17 @@ $ docker-php-dev-mode config ## Dockerfile example -The Dockerfile in the example below is meant to centralize the production and development images in a single Dockerfile, sharing cached layers among the build steps, cleaning unnecessary files like tests, docs and readme files from the final result via git archive. +The Dockerfile in the example below is meant to centralize the production and development images in a single Dockerfile, +sharing cached layers among the build steps, cleaning unnecessary files like tests, docs and readme files from the final +result via git archive. -Composer auth is done via a secret mount to avoid layering credentials and keeping the layers leans. +Composer auth is done via a secret mount to avoid layering credentials and keeping the layers lean. We also run the image with the `app` user since doing it as `root` is considered a bad practice. -To be able to build this image you need [Docker buildkit](https://github.com/moby/buildkit) enabled, this is what empowers the `RUN` mounts and more, check its documentation [here](https://docs.docker.com/develop/develop-images/build_enhancements/). +To be able to build this image you need [Docker buildkit](https://github.com/moby/buildkit) enabled, this is what +empowers the `RUN` mounts and more, check its documentation +[here](https://docs.docker.com/develop/develop-images/build_enhancements/). ```Dockerfile # syntax=docker/dockerfile:1.0.0-experimental @@ -456,7 +486,8 @@ $ DOCKER_BUILDKIT=1 docker build -t "my-project-dev:latest" \ ### Building this image as prod -You want to run this in your CI/CD environment, you can create the `composer.auth` file there, for this example let's get your computer's file and mount the secret. +You want to run this in your CI/CD environment, you can create the `composer.auth` file there, for this example let's +get your computer's file and mount the secret. ```console $ cp ~/.config/composer/auth.json .composer-auth.json