為多個PHP-FPM容器量身打造單一Nginx鏡像的方法

來源:互聯網
上載者:User
這篇文章主要介紹了關於為多個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鏡像。


在這篇部落格文章中,我將概述我從上述方法1到方法2的過程,最後用介紹如何使用新定製Nginx Docker鏡像的解決方案來結束這篇部落格。
我已經將這個鏡像開源GitHub[2],所以如果這剛好是您經常遇到的問題,請隨時查看。

為什麼是Nginx?

PHP-FPM和Nginx一起使用可以產生更好的PHP應用程式效能[3],但缺點是PHP-FPM Docker鏡像預設沒有像PHP Apache鏡像那樣與Nginx捆綁在一起。
如果您想將Nginx容器串連到PHP-FPM後端,則需要將該後端的DNS記錄添加到您的Nginx配置中。
例如,如果PHP-FPM容器作為名為php-fpm-api的容器運行,那麼您的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

nginxserver {    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

接下來,我添加了app/空目錄,只包含一個vhost.conf檔案的conf/目錄。
vhost.conf

nginxserver {    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;    }}

這個跟我原始的設定檔差不多,只修改了一行:fastcgi_pass $ENV{"NGINX_HOST"}:9000;。現在當我想要啟動一個Nginx容器和一個叫php-fpm-api的PHP容器的時候,我可以先編譯一個新的鏡像,然後在它啟動並執行時候傳遞給它對應的環境變數:

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

成功了!但是,這個方法有兩個問題困擾著我:

  1. 基礎鏡像版本陳舊,兩年多沒更新了。這可能會造成安全和效能風險。

  2. 要求一個app的空目錄似乎沒啥必要,再加上我的檔案放在不同的目錄。

最終解決方案

我覺得Martin的鏡像是個不錯的自訂方案選擇。所以,我fork了他的倉庫並構建了一個新的並解決了以上兩個問題的Nginx基礎鏡像。現在,如果你想運行一個伴隨著nginx容器的動態命名後端應用,你只需要簡單地這麼做:

shell# Pull down the latest from Docker Hubdocker 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 containerdocker run --link php-fpm-api -e NGINX_HOST=php-fpm-api shiphp/nginx-env

如果你想自訂這個鏡像,添加你自己的檔案或者Nginx設定檔,只需要像下面這樣擴充你的Dockerfile:

FROM shiphp/nginx-envONBUILD ADD <PATH_TO_YOUR_CONFIGS> /etc/nginx/conf.d/

現在我所有的PHP-FPM容器都使用單個Nginx鏡像的執行個體,當我需要升級Nginx、修改許可權或者配置一些東西的時候,這讓我的生活變得簡單多了。

以上就是本文的全部內容,希望對大家的學習有所協助,更多相關內容請關注topic.alibabacloud.com!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.