我有以下 Dockerfile 對 Nginx 服務器進行了一些自定義。我使用docker build -t nginx-custom:1.21.1 .完成的命令構建影像,沒有錯誤。但是當我想用docker run -it -d nginx-custom:1.21.1 /bin/bash命令從這個影像創建一個容器時,也沒有出現任何錯誤。但是當我使用docker exec命令進入容器并檢查正在運行的行程時ps -ef,結果只包含 bash 行程。
FROM nginx:1.21.1 AS nginx-base
RUN set -x \
&& apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y man nano procps ca-certificates wget gnupg gnupg2 iputils-ping net-tools supervisor \
&& apt-get clean autoclean \
&& apt-get autoremove --yes \
&& rm -rf /var/lib/{apt,dpkg,cache,log}/
EXPOSE 80 443
WORKDIR /var/www
COPY config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
CMD ["service supervisor restart"]
FROM nginx-base AS nginx-config
# Replace the original Nginx config file
COPY config/nginx.conf /etc/nginx/nginx.conf
# Test HTML file
COPY scripts/index.html /var/www/html/index.html
在一些失敗之后,我創建了一個包含以下內容的撰寫檔案并運行了下一個命令:docker-compose up -d --build然后一切正常。所有必要的行程都在運行。
version: '3.8'
services:
nginx-custom:
tty: true
build:
context: .
dockerfile: Dockerfile
image: nginx-custom:1.21.1
container_name: nginx-custom
networks:
devnet:
ipv4_address: 172.18.0.4
restart: unless-stopped
networks:
devnet:
external: true
有誰知道為什么主管只能這樣作業?
uj5u.com熱心網友回復:
一個 Docker 容器只運行一個行程。如果您需要在單個容器中運行多個行程,則需要一些行程管理器,例如 supervisord,但這通常被認為是一種反模式。標準的 Docker Hub 鏡像大致分為三種:基礎 OS 鏡像(alpine, ubuntu);語言工具鏈和運行時 ( python, node, golang); 和運行一些實際程式的東西(postgresql,nginx)。在最后一種情況下,基本映像已配置為將程式作為單個主容器行程運行。
這意味著您可以將 Dockerfile 減少到僅
FROM nginx:1.21.1
COPY config/nginx.conf /etc/nginx/nginx.conf
COPY scripts/index.html /var/www/html/index.html
并且基本影像已經有一個正確的CMD. 您不需要文本編輯器、手冊頁或低級網路除錯工具,因為此容器唯一要做的就是提供 Web 頁面。
一個 Docker 容器只運行一個行程。有幾種方法可以指定它。DockerfileCMD是默認的,但它可以被 Compose 覆寫command:或通過在docker run影像名稱后放置命令來覆寫。這意味著,如果你docker run --rm -it your-image /bin/bash的互動shell中運行,而不是在CMD在Dockerfile。
這里最簡單的答案是不用擔心運行互動式 shell。 docker run沒有命令的影像。 docker exec有節制地;它是一個非常有用的除錯工具,但通常不是您與容器互動的主要方式。
# do not override the command at the end
docker run -d -p 8080:80 nginx-custom:1.21.1
一個 Docker 容器只運行一個行程。當該程序完成時,容器退出。這意味著主容器行程需要是一個長時間運行的前臺行程;它不能是啟動后臺行程然后完成的腳本,也不能是“服務”型別的命令。
基本nginx影像會說類似
CMD ["nginx", "-g", "daemon off;"]
它將 Nginx 服務器作為前臺行程啟動。
如果你真的需要運行 supervisord,那么 mainCMD需要運行supervisord而不是service命令,它需要一個-n選項來在前臺運行它。如果您使用 的 JSON 陣列形式,CMD則您有責任自己將命令分解為單詞。如果有嵌入的空格(如在daemon off;我的示例中,或CMD在問題中),它們將被視為包含空格的單個單詞,就像您在 shell 中參考它一樣。
CMD ["supervisord", "-n"]
通常像service這樣的命令在 Docker 中不起作用,原因有幾個。由于它們執行某些操作并立即回傳,因此它們不適合作為主容器命令。如果您在問題中說“重新啟動”,則該服務之前不會運行。如果環境依賴于某個 init 守護行程,它也不會運行,service或者systemctl不能與之對話。不要嘗試引入init系統,直接將命令作為單前臺主容器行程運行即可。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/315308.html
