我在 Nginx 設定方面遇到了一些概念上的問題。從nginx
SSL 終止器反向代理開始,我使用docker-compose.yml
具有幾個容器的設置,每個容器提供一個虛擬服務。這些服務是作為單一主機名稱下的子目錄提供:
net --443--> nginx
| | `--- ContainerA "https://example.com/serviceA/"
| `----- ContainerB "https://example.com/serviceB/"
`------- ContainerC "https://example.com/serviceC/"
進程列表的片段:
nginx:~$ ps fax
127285 ? Ss 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf -g daemon off;
127419 ? S 0:00 \_ nginx: worker process
127420 ? S 0:00 \_ nginx: worker process
127421 ? S 0:00 \_ nginx: worker process
ContainerA:~$ ps fax
127132 ? Ss 0:09 php-fpm: master process (/etc/php/7.0/fpm/php-fpm.conf)
234053 ? S 8:27 \_ php-fpm: pool www
236952 ? S 8:12 \_ php-fpm: pool www
259123 ? S 6:42 \_ php-fpm: pool www
我認為透過運行單一實例nginx
並php-fpm
在每個容器中使用可以提高效率。
我思考前提是php-fpm
容器不需要自己的nginx
流程;進程nginx
透過連接埠 9000 與每個容器通訊(網路部分有效)。但在實踐中,我遇到了麻煩,所以我需要驗證我的前提是否合理:
這種基本nginx
和php-fpm
架構的假設是否正確?或者,是否有一個適當的nginx
/php-fpm
基礎設施旨在php-fpm
直接使用(相同的主機和檔案系統),或者多主機/多檔案系統是否合理且有效率?
(我最近聯繫了一些幫助,他們的第一個反應是“你需要nginx
在每個容器中運行”,這對我的理解沒有意義php-fpm
。)
(這裡有很多問題提出了具體nginx.conf
問題,而不是關於這個公認的更高級別的架構。)
答案1
這是一個很弱的答案,但我相信:
是的,這通常是正確的哲學,但有一些警告。php-fpm
是用來處理.php
文件的,但我認為不是用來服務所有(非 php)文件的。為此,前端nginx
進程需要查看所有文件,即使它不執行實際的 PHP 處理。
為了使用 docker 巧妙地實現這一點,容器中的檔案php-fpm
需要與nginx
容器明確共用。在 docker 中執行此操作的首選方法是提供一個命名磁碟區並將其用於兩個容器。例如,一個docker-compose.yml
文件:
version: '2'
services:
serviceA:
image: ... # something served with php-fpm
volumes:
- tmpvolA:/path/to/serviceA
serviceB:
image: ... # something served with php-fpm
volumes:
- tmpvolB:/path/to/serviceB
nginx:
image: ...
volumes:
- tmpvolA:/var/www/serviceA
- tmpvolB:/var/www/serviceB
volumes:
tmpvolA:
tmpvolB:
(不包括許多字段...)最後列出的兩個卷是 docker 所說的“命名卷”,並且為空是有原因的:當您啟動腳本時,它們應該為空,並且將由容器之一填充。 (實際上,可能兩者都填,也可能都不填,這取決於幾個因素。)
這樣做的一個副作用是體積堅持。
- 對於效率來說“這很好”,因為它不會被不必要地重新創建。
- “這很糟糕”,因為擁有虛擬化服務的好處之一是您可以重新啟動它並保證從頭開始。對於持久命名卷,您不會(自動)獲得乾淨的狀態,因為將使用前一個實例中使用的文件,而不是較低 fs 層中的嚴格版本。
解決這個「壞問題」的方法是手動刷新磁碟區。這可以在關閉時完成docker-compose down -v
,根據幫助:
-v, --volumes Remove named volumes declared in the `volumes` section
of the Compose file and anonymous volumes
attached to containers.
docker volume rm <volume-id>
也可以使用或手動完成此操作docker volume prune
(刪除所有目前未使用的捲,無論是臨時卷還是命名卷或其他卷)。