這篇文章主要介紹了關於為多個PHP-FPM容器量身打造單一Nginx鏡像的方法,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下
最近我一直在努力部署一套使用Docker容器的PHP微服務。其中一個問題是我們的PHP應用程式被設定為與PHP-FPM和Nginx一起工作(而不是這裡所說的簡單的Apache/PHP[1]設定),因此每個PHP微服務需要兩個容器(也就是相當於兩個Docker映像):
PHP-FPM容器
Nginx容器
# #假設一個應用程式運行超過六個PHP微服務,算上你的dev和prod環境,那麼最終差不多會產生接近30個容器。我決定建立一個單獨的Nginx Docker映像,將PHP-FPM主機名稱作為環境變數映射到這個映像裡面獨特的配置檔案中,而不是為每個PHP-FPM微服務的映像建立獨特的Nginx映像。
我已經將這個鏡像開源GitHub[2],所以如果這剛好是您經常遇到的問題,請隨時查看。
為什麼是Nginx?
PHP-FPM和Nginx一起使用可以產生更好的PHP應用程式效能[3],但缺點是PHP-FPM Docker映像預設沒有像PHP Apache映像那樣與Nginx捆綁在一起。
如果您想將Nginx容器連接到PHP-FPM後端,則需要將該後端的DNS記錄新增到您的Nginx設定中。
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; }如果你只服務一個PHP-FPM容器應用,在你的Nginx容器的設定檔中硬編碼對應的名字是可以的。但是,如我上面提到的,每個PHP服務都需要一個對應的Nginx容器,我們就需要執行多個Nginx容器。創建一個新的Nginx鏡像(我們後面必須維護和升級)將是一件痛苦的事情,因為即使管理一堆不同的捲,對於更改單個變數名稱似乎也有很多工作要做。 第一個解決方案:使用Docker文件裡提到的方法envsubst #
##起初,我認為這很容易。在Docker文件中關於如何使用envsubst有一個很好的小章節[4],但不幸的是,這不適用於我的Nginx設定檔:
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; } }
我的vhost .conf檔案用到了好幾個Nginx內建的環境變量,結果當我執行Docker文件裡提到的如下命令列時,提示錯誤:$uri和fastcgi_script_name未定義。
shell /bin/bash -c "envsubst < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"這些變數通常由Nginx本身傳入[5],所以不容易搞清楚他們是什麼和怎麼進行參數傳遞的,而且這會影響容器的動態可配置性另一個差點成功的Docker映像
接下來,我開始搜尋不同的Nginx的基礎映像。找到了兩個,但這兩個都是兩年沒有更新了。我從martin/nginx[6]開始,試著看看能不能得到一個可以運作的原型。
Martin的映像有點不太一樣,因為它要求特定的檔案目錄結構。我先在Dockerfile中新增了:FROM martin/nginx
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; } }
shell docker build -t shiphp/nginx-env:test . docker run -it --rm -e NGINX_HOST=php-fpm-api shiphp/nginx-env:test
成功了!但是,這個方法有兩個問題困擾著我:
基礎鏡像版本陳舊,兩年多沒更新了。這可能會造成安全和性能風險。 ######要求一個app的空目錄似乎沒啥必要,再加上我的檔案放在不同的目錄。 ############最終解決方案###############我覺得Martin的鏡像是一個不錯的自訂方案選擇。所以,我fork了他的倉庫並建造了一個新的並解決了以上兩個問題的Nginx基礎鏡像。現在,如果你想執行一個伴隨著nginx容器的動態命名後端應用,你只需要簡單地這麼做:###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
如果你想自定义这个镜像,添加你自己的文件或者Nginx配置文件,只需要像下面这样扩展你的Dockerfile:
FROM shiphp/nginx-env ONBUILD ADD <PATH_TO_YOUR_CONFIGS> /etc/nginx/conf.d/
现在我所有的PHP-FPM容器都使用单个Nginx镜像的实例,当我需要升级Nginx、修改权限或者配置一些东西的时候,这让我的生活变得简单多了。
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
以上是為多個PHP-FPM容器量身打造單一Nginx鏡像的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!