This article mainly introduces the method of customizing single Nginx image for multiple PHP-FPM container, has certain reference value, now share to everybody, need friend can refer to
I've been trying to deploy a PHP micro-service that uses Docker containers recently. One of the problems is that our PHP application is set up to work with PHP-FPM and nginx (not the simple apache/php[1] setting here), so each PHP microservices requires two containers (that is, two Docker images):
PHP-FPM container
Nginx Container
Assuming that an application runs more than six PHP microservices, counting your dev and prod environments, it will eventually produce nearly 30 containers. I decided to build a separate nginx docker image, mapping the PHP-FPM hostname as an environment variable into a unique configuration file within the image, rather than building a unique nginx image for each PHP-FPM micro-service mirror.
In this blog post, I'll summarize my process from Method 1 to Method 2, and end this blog with a solution that describes how to use the new custom Nginx docker image.
I already have this image open source github[2], so if this happens to be a problem you often encounter, please feel free to check it.
Why is Nginx?
PHP-FPM with Nginx can produce better PHP application performance [3], but the downside is that the php-fpm Docker image is not bundled with Nginx as the PHP Apache image by default.
If you want to connect the Nginx container to the PHP-FPM backend, you will 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, your nginx configuration file should read like this:
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; }
If you only serve a PHP-FPM container application, it is possible to hardcode the corresponding name in the configuration file of your Nginx container. However, as I mentioned above, each PHP service needs a corresponding Nginx container, we need to run multiple nginx containers. Creating a new Nginx image (which we must maintain and upgrade later) will be a pain, because even if you manage a bunch of different volumes, there seems to be much work to do to change the individual variable names.
First Solution: Use the methods mentioned in the Docker documentation Envsubst
At first, I thought it was easy. There is a nice little chapter on how to use ENVSUBST in the Docker documentation [4], but unfortunately, this does not apply to my Nginx configuration file:
Vhost.conf
Nginxserver { listen; 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; }}
My vhost.conf file uses several Nginx built-in environment variables, resulting in an error when I run the following command line mentioned in the Docker document: $uri and fastcgi_script_name are undefined.
Shell/bin/bash-c "Envsubst </etc/nginx/conf.d/mysite.template >/etc/nginx/conf.d/default.conf && Nginx-g ' daemon off; ' "
These variables are usually passed into [5] by Nginx itself, so it is not easy to figure out what they are and how they are passed, and this can affect the dynamic configuration of the container.
Another almost-successful Docker image
Next, I started searching for a different nginx base image. Two were found, but both were not updated for two years. I start with martin/nginx[6] and try to see if I can get a working prototype.
Martin's image is a bit different because it requires a specific file directory structure. I first added the following in the Dockerfile:
From Martin/nginx
Next, I added the app/empty directory, which contains only a conf/directory of vhost.conf files.
Vhost.conf
Nginxserver { listen; 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; }}
This is the same as my original configuration file, only modified one line: Fastcgi_pass $ENV {"Nginx_host"}:9000;. Now when I want to start a nginx container and a PHP container called Php-fpm-api, I can compile a new image and pass it to its corresponding environment variable when it runs:
Shelldocker build-t shiphp/nginx-env:test. Docker run-it--rm-e Nginx_host=php-fpm-api shiphp/nginx-env:test
It worked! But there are two problems with this approach that plague me:
The base image version is obsolete and has not been updated for more than two years. This can pose a security and performance risk.
Asking for an empty directory for an app doesn't seem to be necessary, plus my files are placed in different directories.
Final Solution
I think Martin's image is a good choice for custom options. So, I fork out his warehouse and build a new Nginx base image that solves the above two issues. Now, if you want to run a dynamic named back-end app with Nginx containers, you just need to do it simply:
shell# pull off the latest from Docker Hubdocker pull shiphp/nginx-env:latest# Run a PHP container named "Php-fpm-api" Doc Ker Run--name php-fpm-api-v $ (PWD):/var/www php:fpm# Start This NGinx container linked to the php-fpm containerdocker ru n--link php-fpm-api-e Nginx_host=php-fpm-api shiphp/nginx-env
If you want to customize this image, add your own files or nginx config files, just expand your dockerfile as follows:
From Shiphp/nginx-envonbuild ADD <PATH_TO_YOUR_CONFIGS>/etc/nginx/conf.d/
Now all of my php-fpm containers use an instance of a single nginx image, which makes my life a lot easier when I need to upgrade Nginx, modify permissions, or configure something.
The above is the whole content of this article, I hope that everyone's learning has helped, more relevant content please pay attention to topic.alibabacloud.com!