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

部落格猿馬甲哥發表於2021-12-31

去年的時候寫了一篇原創《前後端分離,如何在前端專案中動態插入後端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服務也不會相互干擾。

在容器環境,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;" 以前臺形式持續執行。

相關文章