nginx -g "daemon off;" 你學廢了嗎?


去年的時候寫了一篇原創《前后端分離,如何在前端項目中動態插入后端API基地址?(in docker)》, 我自認為這篇生產實踐是對大前端、 容器化、CI/CD的得意之作。

對於前后端分離的web項目,在容器啟動的瞬間,通過腳本替換待部署環境的特定變量,形成了一個鏡像,多環境部署的效果。

Dockerfile CMD指示容器運行過程:

  • 用真實值替換前端chunk files中插入的API_BASE_URL字符
  • 使用nginx承載替換后的chunk files
# FILE: Dockerfile
...
EXPOSE 80
COPY --from=builder /react-frontend/replace_api_url.sh /
CMD ["sh", "replace_api_url.sh"]

下面是replace_api_url.sh的內容

#!/usr/bin/env sh
find '/usr/share/nginx/html' -name '*.js' -exec sed -i -e 's,API_BASE_URL,'"$API_BASE_URL"',g' {} \;
nginx -g "daemon off;"

為什么要加 nginx -g "daemon off;"

這句話是什么意思?

在常規的虛機上,nginx默認是以守護進程來運行的(daemon on),在后台默默提供服務,同時部署多個ngxin服務也不會相互干擾。

nginx -g directives: set global directives out of configuration file.

在容器環境,one container == one process,容器要能持續運行,必須有且僅有一個前台進程,所以對nginx進程容器化,需要將nginx轉為前后進程( daemon off)。

我們能順利執行docker run nginx,啟動容器並不退出,是因為nginx的官方鏡像Dockerfile 已經指定 nginx -g "daemon off;"

再回到上文,為什么此處腳本中要加"nginx -g "daemon off;" 呢?

If you add a custom CMD in the Dockerfile, be sure to include -g daemon off; in the CMD in order for nginx to stay in the foreground, so that Docker can track the process properly (otherwise your container will stop immediately after starting)!

CMD在執行的shell腳本["sh", "replace_api_url.sh"],實際上是啟動shell進程來執行,腳本執行完,進程就會退出(此時nginx還是一攤死的物理文件),所以我們要在腳本內再添加nginx -g "daemon off;" 將整個shell進程轉為前台能持續運行的進程。

Last

  • 容器= 進程, 有且僅有一個前台能持續運行的進程
  • nginx 默認是后台守護進程的形式運行, nginx -g "daemon off;" 以前台形式持續運行。

2022/06/14 ---

有個誤區,我一直以為一個容器只能有一個進程, 其實是推薦作法。
在某些時候,兩個program結合的很緊密的時候,也可以做成單容器內多進程

** 無論如何,保持一個前台進程 **
https://docs.docker.com/config/containers/multi-service_container/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM