Home Backend Development PHP Tutorial How to tailor a single Nginx image for multiple PHP-FPM containers

How to tailor a single Nginx image for multiple PHP-FPM containers

Jul 09, 2018 am 09:28 AM

This article mainly introduces the method of tailoring a single Nginx image for multiple PHP-FPM containers. It has certain reference value. Now I share it with you. Friends in need can refer to it

Recently I've been working on deploying a set of PHP microservices using Docker containers. One of the issues is that our PHP application is set up to work with PHP-FPM and Nginx (rather than a simple Apache/PHP[1] setup as stated here), so two containers are required per PHP microservice (also It is equivalent to two Docker images):

  • PHP-FPM container

  • Nginx container

Assuming that an application runs more than six PHP microservices, including your dev and prod environments, there will eventually be close to 30 containers. Instead of building a unique Nginx image for each PHP-FPM microservice image, I decided to build a separate Nginx Docker image and map the PHP-FPM hostname as an environment variable to a unique configuration file in this image.

How to tailor a single Nginx image for multiple PHP-FPM containers


In this blog post, I will outline my process from method 1 to method 2 above, concluding with an introduction to how to use the new custom Nginx Docker image. Solution to end this blog.
I have made this image open source on GitHub[2], so if this happens to be a problem you often encounter, please feel free to check it out.

Why Nginx?

How to tailor a single Nginx image for multiple PHP-FPM containers

PHP-FPM and Nginx used together can produce better PHP application performance [3], but the disadvantage is that the PHP-FPM Docker image does not default to the PHP Apache image. Bundled with Nginx.
If you want to connect an Nginx container to a PHP-FPM backend, you need to add the DNS records for that backend to your Nginx configuration.
For example, if the PHP-FPM container is running as a container named php-fpm-api, then your Nginx configuration file should read:

nginx
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        # This line passes requests through www.dongfan178.com to the PHP-FPM container
        fastcgi_pass php-fpm-api:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param www.huayi1.cn/ www.dongfan178.com SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param www.00534.cn PATH_INFO $fastcgi_path_info;
    }
Copy after login

If you only serve one PHP-FPM container application, It is possible to hardcode the corresponding name in your Nginx container's configuration file. However, as I mentioned above, each PHP service requires a corresponding Nginx container, so we need to run multiple Nginx containers. Creating a new Nginx image (which we will have to maintain and upgrade later) will be a pain because even managing a bunch of different volumes seems like a lot of work to do to change a single variable name.

First solution: Use the method envsubst mentioned in the Docker documentation

How to tailor a single Nginx image for multiple PHP-FPM containers

At first, I thought it was easy. There is a nice little chapter in the Docker documentation on how to use envsubst[4], but unfortunately this does not work with my Nginx config file:
vhost.conf

nginx
server {
    listen 80;
    index index.php index.html;
    root /var/www/public;
    client_max_body_size 32M;
    location / {
        try_files $uri /index.php?$args;
    }
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass ${NGINX_HOST}:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
Copy after login

my vhost The .conf file uses several Nginx built-in environment variables. As a result, when I run the following command line mentioned in the Docker documentation, an error message appears: $uri and fastcgi_script_name are not defined.

shell
/bin/bash -c "envsubst < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g &#39;daemon off;&#39;"
Copy after login

These variables are usually passed in by Nginx itself [5], so it is not easy to figure out what they are and how to pass parameters, and this will affect the dynamic configurability of the container

Another Docker image that almost succeeded

How to tailor a single Nginx image for multiple PHP-FPM containers

Next, I started searching for different Nginx base images. I found two, but both of them have not been updated in two years. I started with martin/nginx[6] and tried to see if I could get a working prototype.
Martin's image is a little different because it requires a specific file directory structure. I first added to the Dockerfile:

FROM martin/nginx
Copy after login

Next, I added the app/ empty directory and the conf/ directory containing only a vhost.conf file.
vhost.conf

nginx
server {
    listen 80;
    index index.php index.html;
    root /var/www/public;
    client_max_body_size 32M;
    location / {
        try_files $uri /index.php?$args;
    }
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass $ENV{"NGINX_HOST"}:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
Copy after login

This is similar to my original configuration file, with only one line modified: fastcgi_pass $ENV{"NGINX_HOST"}:9000;. Now when I want to start an Nginx container and a PHP container called php-fpm-api, I can first compile a new image and then pass it the corresponding environment variable when it runs:

shell
docker build -t shiphp/nginx-env:test .
docker run -it --rm -e NGINX_HOST=php-fpm-api shiphp/nginx-env:test
Copy after login

Success! However, there are two problems that bother me with this method:

  1. The base image version is old and has not been updated in more than two years. This can create security and performance risks.

  2. It seems unnecessary to require an empty directory for an app, plus my files are placed in different directories.

Final solution

How to tailor a single Nginx image for multiple PHP-FPM containers

I think Martin's mirror is a good custom solution choice. So, I forked his repository and built a new Nginx base image that solved the above two problems. Now, if you want to run a dynamically named backend application with an nginx container, you simply do this:

shell
# Pull down the latest from Docker Hub
docker pull shiphp/nginx-env:latest
# Run a PHP container named "php-fpm-api"
docker run --name php-fpm-api -v $(pwd):/var/www php:fpm
# Start this NGinx container linked to the PHP-FPM container
docker run --link php-fpm-api -e NGINX_HOST=php-fpm-api shiphp/nginx-env
Copy after login

如果你想自定义这个镜像,添加你自己的文件或者Nginx配置文件,只需要像下面这样扩展你的Dockerfile:

FROM shiphp/nginx-env
ONBUILD ADD <PATH_TO_YOUR_CONFIGS> /etc/nginx/conf.d/
Copy after login

现在我所有的PHP-FPM容器都使用单个Nginx镜像的实例,当我需要升级Nginx、修改权限或者配置一些东西的时候,这让我的生活变得简单多了。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

PHP缓存区ob的介绍

如何配置php客户端(phpredis)并连接Redis

使用PHPstudy在Windows服务器下部署PHP系统

The above is the detailed content of How to tailor a single Nginx image for multiple PHP-FPM containers. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

How does session hijacking work and how can you mitigate it in PHP? How does session hijacking work and how can you mitigate it in PHP? Apr 06, 2025 am 12:02 AM

Session hijacking can be achieved through the following steps: 1. Obtain the session ID, 2. Use the session ID, 3. Keep the session active. The methods to prevent session hijacking in PHP include: 1. Use the session_regenerate_id() function to regenerate the session ID, 2. Store session data through the database, 3. Ensure that all session data is transmitted through HTTPS.

How to debug CLI mode in PHPStorm? How to debug CLI mode in PHPStorm? Apr 01, 2025 pm 02:57 PM

How to debug CLI mode in PHPStorm? When developing with PHPStorm, sometimes we need to debug PHP in command line interface (CLI) mode...

Describe the SOLID principles and how they apply to PHP development. Describe the SOLID principles and how they apply to PHP development. Apr 03, 2025 am 12:04 AM

The application of SOLID principle in PHP development includes: 1. Single responsibility principle (SRP): Each class is responsible for only one function. 2. Open and close principle (OCP): Changes are achieved through extension rather than modification. 3. Lisch's Substitution Principle (LSP): Subclasses can replace base classes without affecting program accuracy. 4. Interface isolation principle (ISP): Use fine-grained interfaces to avoid dependencies and unused methods. 5. Dependency inversion principle (DIP): High and low-level modules rely on abstraction and are implemented through dependency injection.

How to automatically set permissions of unixsocket after system restart? How to automatically set permissions of unixsocket after system restart? Mar 31, 2025 pm 11:54 PM

How to automatically set the permissions of unixsocket after the system restarts. Every time the system restarts, we need to execute the following command to modify the permissions of unixsocket: sudo...

Explain late static binding in PHP (static::). Explain late static binding in PHP (static::). Apr 03, 2025 am 12:04 AM

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

How to send a POST request containing JSON data using PHP's cURL library? How to send a POST request containing JSON data using PHP's cURL library? Apr 01, 2025 pm 03:12 PM

Sending JSON data using PHP's cURL library In PHP development, it is often necessary to interact with external APIs. One of the common ways is to use cURL library to send POST�...

See all articles