1. 程式人生 > >dockerfile WORKDIR 指定工作目錄與USER 指定當前使用者

dockerfile WORKDIR 指定工作目錄與USER 指定當前使用者

WORKDIR 指定工作目錄

格式為 WORKDIR <工作目錄路徑> 。

使用 WORKDIR 指令可以來指定工作目錄(或者稱為當前目錄),以後各層的當前目錄就被改
為指定的目錄,如該目錄不存在, WORKDIR 會幫你建立目錄。
之前提到一些初學者常犯的錯誤是把 Dockerfile 等同於 Shell 指令碼來書寫,這種錯誤的理解
還可能會導致出現下面這樣的錯誤:
RUN cd /app
RUN echo "hello" > world.txt
如果將這個 Dockerfile 進行構建映象執行後,會發現找不到 /app/world.txt 檔案,或者其
內容不是 hello 。原因其實很簡單,在 Shell 中,連續兩行是同一個程序執行環境,因此前
一個命令修改的記憶體狀態,會直接影響後一個命令;而在 Dockerfile 中,這兩行 RUN 命令
的執行環境根本不同,是兩個完全不同的容器。這就是對 Dockerfile 構建分層儲存的概念
不瞭解所導致的錯誤。

之前說過每一個 RUN 都是啟動一個容器、執行命令、然後提交儲存層檔案變更。第一層 RUN
cd /app 的執行僅僅是當前程序的工作目錄變更,一個記憶體上的變化而已,其結果不會造成任
何檔案變更。
而到第二層的時候,啟動的是一個全新的容器,跟第一層的容器更完全沒關
系,自然不可能繼承前一層構建過程中的記憶體變化。

因此如果需要改變以後各層的工作目錄的位置,那麼應該使用 WORKDIR 指令。

USER 指定當前使用者
格式: USER <使用者名稱>
USER 指令和 WORKDIR 相似,都是改變環境狀態並影響以後的層。 WORKDIR 是改變工作目
錄, USER 則是改變之後層的執行 RUN

, CMD 以及 ENTRYPOINT 這類命令的身份。
當然,和 WORKDIR 一樣, USER 只是幫助你切換到指定使用者而已,這個使用者必須是事先建立
好的,否則無法切換。
RUN groupadd -r redis && useradd -r -g redis redis
USER redis
RUN [ "redis-server" ]
如果以 root 執行的指令碼,在執行期間希望改變身份,比如希望以某個已經建立好的使用者來
執行某個服務程序,不要使用 su 或者 sudo ,這些都需要比較麻煩的配置,而且在 TTY 缺
失的環境下經常出錯。建議使用 gosu 。
# 建立 redis 使用者,並使用 gosu 換另一個使用者執行命令

RUN groupadd -r redis && useradd -r -g redis redis
# 下載 gosu
RUN wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.7/
gosu-amd64" \
&& chmod +x /usr/local/bin/gosu \
&& gosu nobody true
# 設定 CMD,並以另外的使用者執行
CMD [ "exec", "gosu", "redis", "redis-server" ]