Dockerfile中的CMD和ENTRYPOINT

Shell格式和Exec格式

Dockerfile中,RUNCMDENTRYPOINT指令都可以使用兩種格式:Shell格式Exec格式

  • exec 格式INSTRUCTION ["executable","param1","param2"]
  • shell 格式INSTRUCTION command param1 param2

exec格式使得避免使用shell字符串處理成為可能,并且可以使用特定的命令shell或任何其他可執行文件來調用命令。它使用JSON數組語法,數組中的每個元素都是一個命令、標志或參數。

shell格式更加靈活,強調易用性、靈活性和可讀性。

在使用shell格式時系統會自動選擇一個命令shell來執行指令,而在使用exec格式時,需要明確指定使用哪個命令shell或其他可執行文件來執行命令。換句話說,shell格式會自動選擇執行環境,而exec格式需要手動指定執行環境。

Exec 格式

Exec格式被解析為一個JSON數組,這意味著你必須使用雙引號(")而不是單引號(')來包圍單詞。

ENTRYPOINT ["/bin/bash", "-c", "echo hello"]

Exec格式最適合用于指定ENTRYPOINT指令,并結合CMD來設置可以在運行時覆蓋的默認參數。

變量替換

使用Exec格式不會自動調用命令shell。這意味著不會發生常規的shell處理,例如變量替換。例如,RUN [ "echo", "$HOME" ]不會處理$HOME的變量替換。

如果你想進行shell處理,可以使用Shell格式,或者直接在Exec格式中執行shell,例如:RUN [ "sh", "-c", "echo $HOME" ]。當使用Exec格式并直接執行shell時,就像Shell格式一樣,是由shell進行環境變量替換,而不是構建器。

反斜杠

在Exec格式中,你必須對反斜杠進行轉義。這在Windows上特別重要,因為在Windows中反斜杠是路徑分隔符。以下行將因未被視為有效的JSON而被視為Shell格式,并以意外的方式失敗:

RUN ["c:\windows\system32\tasklist.exe"]

正確的語法示例是:

RUN ["c:\\windows\\system32\\tasklist.exe"]

Shell 格式

與Exec格式不同,使用Shell格式的指令總是使用命令shell。Shell格式不使用JSON數組格式,而是一個常規的字符串。Shell格式字符串允許你使用轉義字符(默認是反斜杠)來換行,將單個指令延續到下一行。這使得它更容易用于更長的命令,因為它允許你將它們分割成多行。例如,考慮以下兩行:

RUN source $HOME/.bashrc && \
echo $HOME

它們等同于以下單行:

RUN source $HOME/.bashrc && echo $HOME

你可以使用heredocs與Shell格式來拆分命令:

RUN <<EOF
source $HOME/.bashrc && \
echo $HOME
EOF

使用不同的shell

你可以使用SHELL命令更改默認shell。例如:

SHELL ["/bin/bash", "-c"]
RUN echo hello

CMD

CMD指令設置了在從鏡像運行容器時要執行的命令。

你可以使用shell格式或exec格式來指定CMD指令:

  • CMD ["executable","param1","param2"](exec格式)
  • CMD ["param1","param2"](exec格式,作為ENTRYPOINT的默認參數)
  • CMD command param1 param2(shell格式)
    Dockerfile中只能有一個CMD指令。如果列出多個CMD,只有最后一個會生效。

CMD的目的是為正在執行的容器提供默認值。這些默認值可以包括一個可執行文件,也可以省略可執行文件,此時你必須同時指定ENTRYPOINT指令。

如果你希望容器每次運行時都執行相同的可執行文件,那么你應該考慮結合使用ENTRYPOINTCMD。如果用戶在docker run中指定了參數,它們將覆蓋在CMD中指定的默認值,但仍會使用默認的ENTRYPOINT

如果CMD用于為ENTRYPOINT指令提供默認參數,則應該以exec格式指定CMDENTRYPOINT指令。

注意 不要將RUN與CMD混淆。RUN實際上運行一個命令并提交結果;CMD不會在構建時執行任何操作,而是為鏡像指定預期的命令。

ENTRYPOINT

ENTRYPOINT 允許您配置一個將作為可執行文件運行的容器。

ENTRYPOINT 有兩種可能的格式:

  • 首選的 exec 格式:
ENTRYPOINT ["executable", "param1", "param2"]
  • shell 格式:
ENTRYPOINT command param1 param2

以下命令從帶有默認內容、監聽端口 80 的 nginx 啟動容器:

docker run -i -t --rm -p 80:80 nginx

對于 docker run <image> 的命令行參數將附加在 exec 格式的 ENTRYPOINT 中的所有元素之后,并將覆蓋使用 CMD 指定的所有元素。這允許將參數傳遞給入口點,即 docker run <image> -d 將向入口點傳遞 -d 參數。您可以使用 docker run --entrypoint 標志覆蓋 ENTRYPOINT 指令。

ENTRYPOINT 的 shell 格式阻止使用任何 CMD 命令行參數。它還將您的 ENTRYPOINT 作為 /bin/sh -c 的子命令啟動,不會傳遞信號。這意味著可執行文件不會成為容器的 PID 1,并且不會接收 Unix 信號。在這種情況下,您的可執行文件不會從 docker stop <container> 接收 SIGTERM 信號。

Dockerfile 中的最后一個 ENTRYPOINT 指令將生效。

Exec 格式的 ENTRYPOINT 示例

您可以使用 exec 格式的 ENTRYPOINT 來設置相對穩定的默認命令和參數,然后使用 CMD 的任一格式來設置更有可能被更改的其他默認值。

FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]

當您運行容器時,您可以看到top是唯一的進程:

docker run -it --rm --name test  top -Htop - 08:25:00 up  7:27,  0 users,  load average: 0.00, 0.01, 0.05
Threads:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.1 us,  0.1 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   2056668 total,  1616832 used,   439836 free,    99352 buffers
KiB Swap:  1441840 total,        0 used,  1441840 free.  1324440 cached MemPID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND1 root      20   0   19744   2336   2080 R  0.0  0.1   0:00.04 top

要進一步檢查結果,您可以使用docker exec:

docker exec -it test ps auxUSER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  2.6  0.1  19752  2352 ?        Ss+  08:24   0:00 top -b -H
root         7  0.0  0.1  15572  2164 ?        R+   08:25   0:00 ps aux

您可以使用docker stop test優雅地請求top關閉。

以下Dockerfile顯示使用ENTRYPOINT在前臺運行Apache(即作為PID 1):

FROM debian:stable
RUN apt-get update && apt-get install -y --force-yes apache2
EXPOSE 80 443
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

如果您需要為單個可執行文件編寫啟動腳本,您可以使用execgosu命令確保最終可執行文件接收Unix信號:

#!/usr/bin/env bash
set -eif [ "$1" = 'postgres' ]; thenchown -R postgres "$PGDATA"if [ -z "$(ls -A "$PGDATA")" ]; thengosu postgres initdbfiexec gosu postgres "$@"
fiexec "$@"

最后,如果您需要在關閉時進行一些額外的清理(或與其他容器通信),或者協調多個可執行文件,您可能需要確保ENTRYPOINT腳本接收Unix信號,傳遞它們,然后執行更多工作:

#!/bin/sh
# Note: I've written this using sh so it works in the busybox container too# USE the trap if you need to also do manual cleanup after the service is stopped,
#     or need to start multiple services in the one container
trap "echo TRAPed signal" HUP INT QUIT TERM# start service in background here
/usr/sbin/apachectl startecho "[hit enter key to exit] or run 'docker stop <container>'"
read# stop service and clean up here
echo "stopping apache"
/usr/sbin/apachectl stopecho "exited $0"

如果您使用docker run -it --rm -p 80:80 --name test apache運行此映像,則可以使用docker execdocker top檢查容器的進程,然后要求腳本停止Apache:

docker exec -it test ps auxUSER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.1  0.0   4448   692 ?        Ss+  00:42   0:00 /bin/sh /run.sh 123 cmd cmd2
root        19  0.0  0.2  71304  4440 ?        Ss   00:42   0:00 /usr/sbin/apache2 -k start
www-data    20  0.2  0.2 360468  6004 ?        Sl   00:42   0:00 /usr/sbin/apache2 -k start
www-data    21  0.2  0.2 360468  6000 ?        Sl   00:42   0:00 /usr/sbin/apache2 -k start
root        81  0.0  0.1  15572  2140 ?        R+   00:44   0:00 ps auxdocker top testPID                 USER                COMMAND
10035               root                {run.sh} /bin/sh /run.sh 123 cmd cmd2
10054               root                /usr/sbin/apache2 -k start
10055               33                  /usr/sbin/apache2 -k start
10056               33                  /usr/sbin/apache2 -k start/usr/bin/time docker stop testtest
real	0m 0.27s
user	0m 0.03s
sys	0m 0.03s

Shell 格式 ENTRYPOINT 示例

您可以為ENTRYPOINT指定一個純字符串,它將在 /bin/sh-c中執行。此表單將使用shell處理來替換shell環境變量,并將忽略任何CMDdocker run命令行參數。為了確保docker stop將正確地發出任何長時間運行的ENTRYPOINT可執行文件的信號,您需要記住以exec開頭:

FROM ubuntu
ENTRYPOINT exec top -b

當您運行此映像時,您將看到單個PID 1進程:

docker run -it --rm --name test topMem: 1704520K used, 352148K free, 0K shrd, 0K buff, 140368121167873K cached
CPU:   5% usr   0% sys   0% nic  94% idle   0% io   0% irq   0% sirq
Load average: 0.08 0.03 0.05 2/98 6PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND1     0 root     R     3164   0%   0% top -b

在docker stop上干凈地退出:

/usr/bin/time docker stop testtest
real	0m 0.20s
user	0m 0.02s
sys	0m 0.04s

如果您忘記將exec添加到ENTRYPOINT的開頭:

FROM ubuntu
ENTRYPOINT top -b
CMD -- --ignored-param1

然后,您可以運行它(為下一步命名):

docker run -it --name test top --ignored-param2top - 13:58:24 up 17 min,  0 users,  load average: 0.00, 0.00, 0.00
Tasks:   2 total,   1 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s): 16.7 us, 33.3 sy,  0.0 ni, 50.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   1990.8 total,   1354.6 free,    231.4 used,    404.7 buff/cache
MiB Swap:   1024.0 total,   1024.0 free,      0.0 used.   1639.8 avail MemPID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND1 root      20   0    2612    604    536 S   0.0   0.0   0:00.02 sh6 root      20   0    5956   3188   2768 R   0.0   0.2   0:00.00 top

您可以從top的輸出中看到指定的ENTRYPOINT不是PID 1

如果您隨后運行docker stop test,容器將不會干凈地退出-stop命令將在超時后強制發送SIGKILL

docker exec -it test ps wauxUSER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.4  0.0   2612   604 pts/0    Ss+  13:58   0:00 /bin/sh -c top -b --ignored-param2
root         6  0.0  0.1   5956  3188 pts/0    S+   13:58   0:00 top -b
root         7  0.0  0.1   5884  2816 pts/1    Rs+  13:58   0:00 ps waux/usr/bin/time docker stop testtest
real	0m 10.19s
user	0m 0.04s
sys	0m 0.03s

了解CMD和ENTRYPOINT如何交互

CMDENTRYPOINT指令都定義了在運行容器時執行的命令。描述它們合作的規則很少。

  1. Dockerfile應至少指定一個CMDENTRYPOINT命令。
  2. 將容器用作可執行文件時應定義ENTRYPOINT
  3. CMD應該用作定義ENTRYPOINT命令或在容器中執行 ad-hoc 命令的默認參數的一種方式。
  4. 使用替代參數運行容器時,CMD將被覆蓋。

下表顯示了對不同的ENTRYPOINT/CMD組合執行的命令:

No ENTRYPOINTENTRYPOINT exec_entry p1_entryENTRYPOINT [“exec_entry”, “p1_entry”]
No CMDerror, not allowed/bin/sh -c exec_entry p1_entryexec_entry p1_entry
CMD [“exec_cmd”, “p1_cmd”]exec_cmd p1_cmd/bin/sh -c exec_entry p1_entryexec_entry p1_entry exec_cmd p1_cmd
CMD exec_cmd p1_cmd/bin/sh -c exec_cmd p1_cmd/bin/sh -c exec_entry p1_entryexec_entry p1_entry /bin/sh -c exec_cmd p1_cmd

Note: 如果從基本圖像定義了CMD,則設置ENTRYPOINT會將CMD重置為空值。在這種情況下,必須在當前圖像中定義CMD才能具有值。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/10629.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/10629.shtml
英文地址,請注明出處:http://en.pswp.cn/web/10629.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【深耕 Python】Quantum Computing 量子計算機(5)量子物理概念(二)

寫在前面 往期量子計算機博客&#xff1a; 【深耕 Python】Quantum Computing 量子計算機&#xff08;1&#xff09;圖像繪制基礎 【深耕 Python】Quantum Computing 量子計算機&#xff08;2&#xff09;繪制電子運動平面波 【深耕 Python】Quantum Computing 量子計算機&…

ios 開發如何給項目安裝第三方庫,以websocket庫 SocketRocket 為例

1.brew 安裝 cococapods $ brew install cocoapods 2、找到xcode項目 的根目錄&#xff0c;如圖&#xff0c;在根目錄下創建Podfile 文件 3、在Podfile文件中寫入 platform :ios, 13.0 use_frameworks! target chat_app do pod SocketRocket end project ../chat_app.x…

Python實戰開發及案例分析(18)—— 邏輯回歸

邏輯回歸是一種廣泛用于分類任務的統計模型&#xff0c;尤其是用于二分類問題。在邏輯回歸中&#xff0c;我們預測的是觀測值屬于某個類別的概率&#xff0c;這通過邏輯函數&#xff08;或稱sigmoid函數&#xff09;來實現&#xff0c;該函數能將任意值壓縮到0和1之間。 邏輯回…

Leetcode 572:另一顆樹的子樹

給你兩棵二叉樹 root 和 subRoot 。檢驗 root 中是否包含和 subRoot 具有相同結構和節點值的子樹。如果存在&#xff0c;返回 true &#xff1b;否則&#xff0c;返回 false 。 二叉樹 tree 的一棵子樹包括 tree 的某個節點和這個節點的所有后代節點。tree 也可以看做它自身的…

【linux】詳解linux基本指令

目錄 cat more less head tail 時間 cal find grep zip/unzip tar bc uname –r 關機 小編一共寫了兩篇linux基本指令&#xff0c;這兩篇涵蓋了大部分初學者的必備指令&#xff0c;這是第二篇&#xff0c;第一篇詳見http://t.csdnimg.cn/HRlVt cat 適合查看小文…

網站localhost和127.0.0.1可以訪問,本地ip不可訪問解決方案

部署了一個網站, 使用localhost和127.0.0.1加端口號可以訪問, 但是使用本機的ip地址加端口號卻不行. 原因可能有多種. 可能的原因: 1 首先要確認是否localhost對應的端口是通的(直接網址訪問), 以及你無法訪問的那個本機ip是否正確(使用ping測試)&#xff1b; 2 檢查本機的防火…

從頭理解transformer,注意力機制(下)

交叉注意力 交叉注意力里面q和KV生成的數據不一樣 自注意力機制就是悶頭自學 解碼器里面的每一層都會拿著編碼器結果進行參考&#xff0c;然后比較相互之間的差異。每做一次注意力計算都需要校準一次 編碼器和解碼器是可以并行進行訓練的 訓練過程 好久不見輸入到編碼器&…

docker部署springboot+Vue項目

項目介紹&#xff1a;后臺springboot項目&#xff0c;該項目環境mysql、redis 。前臺Vue&#xff1a;使用nginx反向代理 方法一&#xff1a;docker run 手動逐個啟動容器 1.docker配置nginx代理 將vue項目打包上傳到服務器上。創建文件夾存儲數據卷&#xff0c;html存放打包…

計算機網絡實驗1:交換機基本配置管理

實驗目的和要求 安裝Packer Tracer&#xff0c;了解Packer Tracer的基本操作掌握交換機基本命令集實驗項目內容 認識Packet Tracer軟件 交換機的基本配置與管理 交換機的端口配置與管理 交換機的端口聚合配置 交換機劃分Vlan配置 實驗環境 硬件&#xff1a;PC機&#x…

Redisson分布式鎖原理

Redisson是基于Redis實現的客戶端庫&#xff0c;提供了多種Java并發API映射到Redis中&#xff0c;也實現了各種分布式服務&#xff0c;其中就有各種分布式鎖的實現。 Redisson鎖彌補了SETNX鎖的的局限性&#xff0c;實現了可重入、可重試和超時續約的功能。 可重入&#xff1a…

解決NVM 下載node.js慢問題->最新鏡像

一、NVM 介紹 nvm是node版本管理工具&#xff0c;可以運行在多種操作系統上。這里主要記錄一下在windows系統的安裝和使用。 在使用過程中&#xff0c;下載其他版本時會出現下載慢或卡住或下載失敗的情況&#xff0c;是因為服務器在國外&#xff0c;網絡原因導致&#xff0c;…

代碼隨想錄Day 41|Leetcode|Python|198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III

198.打家劫舍 你是一個專業的小偷&#xff0c;計劃偷竊沿街的房屋。每間房內都藏有一定的現金&#xff0c;影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統&#xff0c;如果兩間相鄰的房屋在同一晚上被小偷闖入&#xff0c;系統會自動報警。 給定一個代表每個…

在統計上城鄉是如何劃分的

城鄉二元結構&#xff0c;是長期以來我國經濟社會發展的顯著特點之一&#xff0c;黨和政府高度重視統籌城鄉發展&#xff0c;縮小城鄉差距。為了對城鄉發展予以準確反映和動態監測&#xff0c;提高在統計上劃分城鄉工作的一致性&#xff0c;國家統計局開展了統一的統計用區劃代…

【Docker學習】docker run的端口映射-p和-P選項

docker run的端口映射選項分為-p&#xff08;小寫&#xff0c;全稱--publish&#xff09;&#xff0c;-P&#xff08;大寫&#xff0c;全稱--publish-all&#xff09;&#xff0c;之前認為只有改變容器發布給宿主機的默認端口號才會進行-p的設置&#xff0c;而不改變默認端口號…

面試經典算法系列之數組/字符串6 -- 輪轉數組

面試經典算法題38-輪轉數組 LeetCode.189 公眾號&#xff1a;阿Q技術站 問題描述 給定一個整數數組 nums&#xff0c;將數組中的元素向右輪轉 k 個位置&#xff0c;其中 k 是非負數。 示例 1: 輸入: nums [1,2,3,4,5,6,7], k 3 輸出: [5,6,7,1,2,3,4] 解釋: 向右輪轉 1 …

YOLOv8訓練流程-原理解析[目標檢測理論篇]

關于YOLOv8的主干網絡在YOLOv8網絡結構介紹-CSDN博客介紹了&#xff0c;為了更好地學習本章內容&#xff0c;建議先去看預測流程的原理分析YOLOv8原理解析[目標檢測理論篇]-CSDN博客&#xff0c;再次把YOLOv8網絡結構圖放在這里&#xff0c;方便隨時查看。 ? 1.前言 YOLOv8訓練…

Map中KEY去除下劃線并首字母轉換為大寫工具類

在運維舊項目時候&#xff0c;碰上sql查詢結果只能返回List<Map>&#xff0c;key為表單字段名&#xff0c;value為獲取到的結果數據。 懶得一個一個敲出來&#xff0c;就直接寫個方法轉換&#xff0c;并賦值到相應實體對象里去。 Map中KEY去除下劃線并首字母轉換為大寫&…

算法提高之矩陣距離

算法提高之矩陣距離 核心思想&#xff1a;多源bfs 從多個源頭做bfs&#xff0c;求距離 先把所有1的坐標存入隊列 再把所有1連接的位置存入 一層一層求 #include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N 1…

Kafka 面試題(八)

1. Kafka&#xff1a;硬件配置選擇和調優的建議 &#xff1f; Kafka的硬件配置選擇和調優是確保Kafka集群高效穩定運行的關鍵環節。以下是一些建議&#xff1a; 硬件配置選擇&#xff1a; 內存&#xff08;RAM&#xff09;&#xff1a;建議至少使用32GB內存的服務器。為Kafk…

Web3Tools - 助記詞生成

Web3Tools - 助記詞生成工具 本文介紹了一個簡單的助記詞生成工具&#xff0c;使用 React 和 Material-UI 構建。用戶可以選擇助記詞的語言和長度&#xff0c;然后生成隨機的助記詞并顯示在頁面上 功能介紹 選擇語言和長度&#xff1a; 用戶可以在下拉菜單中選擇助記詞的語言&…