Docker 筆記(2):Dockerfile

Dockerfile是由一系列命令和參數構成的腳本,這些命令應用於基礎鏡像並最終建立一個新的鏡像。node

經常使用的選項

例子:python

FROM node:latest
MAINTAINER my_name
ADD ./my_project /code
VOLUME ["/data1", "/data2"]
WORKDIR /code
RUN apt-get install mysql
EXPOSE 6777
ENV SRC_URL www.xxxxxxxxxxx.com/xxxxxxx
RUN wget $SRC_URL
CMD ["node","bin/www"]
  • FROM: 指定基礎鏡像,若是本地不存在基礎鏡像,會自動從遠程倉庫拉取。FROM必須是Dockerfile中除了註釋外的第一行語句。
  • MAINTAINER: 用於指定鏡像的構建者,當發現坑的時候能夠找他
  • ADD: 將本機的文件或目錄複製到鏡像的某個目錄下,在後續的構建命令和容器運行中能夠在容器中訪問該目錄
  • WORKDIR: 指定後續的構建命令的工做路徑
  • RUN: 在鏡像中運行某條命令,如安裝相關的依賴庫
  • CMD:用於指定鏡像運行時的第一條命令。CMD只能出現一次,若是出現屢次,前面的會被覆蓋
CMD ["executable","param1","param2"] 使用 exec 執行,推薦方式;

    CMD command param1 param2 在 /bin/sh 中執行,提供給須要交互的應用;

    CMD ["param1","param2"] 提供給 ENTRYPOINT 的默認參數;
  • EXPOSE:暴露容器的端口,其餘容器能夠經過該端口訪問本容器提供的服務,前提是這些容器在同一個網絡中,例子中暴露了6777端口
  • ENV: 設置環境變量。這些環境變量能夠在後續的構建命令中使用,當運行容器時,也能夠在容器中使用這些變量
  • COPY: 將本機的文件或目錄複製到鏡像的某個目錄下,在後續的構建命令和容器運行中能夠在容器中訪問該目錄。該命令做用同ADD,只是ADD更增強大,如:當拷貝的是壓縮包,ADD會自動解壓
  • ENTRYPOINT: 容器啓動後執行的命令。每一個 Dockerfile 中只能有一個ENTRYPOINT,當指定多個時,只有最後一個生效。(CMD指令指定的容器啓動時命令能夠被docker run指定的命令覆蓋;而ENTRYPOINT指令指定的命令不能被覆蓋,而是將docker run指定的參數當作ENTRYPOINT指定命令的參數。)
ENTRYPOINT ["executable", "param1", "param2"]

    ENTRYPOINT command param1 param2(shell中執行)
  • VOLUME: 容器卷是一個可供一個或多個容器使用的特殊目錄,它繞過 UFS,將主機目錄掛在到容器裏面,能夠提供不少有用的特性:mysql

    • 數據卷 能夠在容器之間共享和重用
    • 對 數據卷 的修改會立馬生效
    • 對 數據卷 的更新,不會影響鏡像
    • 數據卷 默認會一直存在,即便容器被刪除,除非在刪除容器的時候使用-v選項: docker rm -v container_id/container_name
    • 注意: 數據卷 的使用,相似於 Linux 下對目錄或文件進行 mount,鏡像中的被指定爲掛載點的目錄中的文件會隱藏掉,能顯示看的是掛載的 數據卷 。所以你的容器目錄dir有一個文件爲temp.data,若是你在dir掛載了一個數據卷
    • 在Dockerfile中,沒法指定主機上對應的目錄

,那麼你就不再能讀取temp.data,除非你移除該數據卷。git

其餘選項

USER

格式:github

USER <用戶名>

USER 指令和 WORKDIR 類似,都是改變環境狀態並影響之後的層。 WORKDIR 是改變工做目錄, USER 則是改變以後層的執行 RUN , CMD 以及 ENTRYPOINT 這類命令的身份。redis

固然,和 WORKDIR 同樣, USER 只是幫助你切換到指定用戶而已,這個用戶必須是事先創建好的,不然沒法切換。sql

RUN groupadd -r redis && useradd -r -g redis redis
USER redis
RUN [ "redis-server" ]

若是以 root 執行的腳本,在執行期間但願改變身份,好比但願以某個已經創建好的用戶來運行某個服務進程,不要使用 su 或者 sudo ,這些都須要比較麻煩的配置,並且在 TTY 缺失的環境下常常出錯。建議使用 gosu 。docker

# 創建 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" ]

ONBUILD

格式: ONBUILD <其它指令> 。shell

ONBUILD 是一個特殊的指令,它後面跟的是其它指令,好比 RUN , COPY 等,而這些指令,在當前鏡像構建時並不會被執行。只有當以當前鏡像爲基礎鏡像,去構建下一級鏡像的時候纔會被執行。npm

Dockerfile 中的其它指令都是爲了定製當前鏡像而準備的,惟有 ONBUILD 是爲了幫助別人定製本身而準備的。

fundamental/Dockerfile

FROM node:slim
RUN mkdir /app
WORKDIR /app
ONBUILD COPY ./package.json /app
ONBUILD RUN [ "npm", "install" ]
ONBUILD COPY . /app/
CMD [ "npm", "start" ]

project1/Dockerfile

FROM fundamental
do other thing

在構建 project1 的時候 ONBUILD的命令纔會生效。

例子

咱們將基於官方的python鏡像,搭建一個後端的環境鏡像(須要用的庫含redis、flask等)。

FROM python:3.6-alpine
# 複製代碼到鏡像
ADD the_path_of_project /code   
# 設置後面的命令的pwd
WORKDIR /code
# 安裝依賴
RUN pip install redis flask
# 運行服務的命令
CMD ["python", "app.py"]

例子中:

  • FROM:指定基礎鏡像爲python:3.6-alpine
  • ADD:項目代碼被複制到容器的code目錄下
  • WORKDIR:指定後續命令的pwd爲code
  • RUN:安裝依賴庫
  • CMD:指定啓動容器時須要運行的命令,即啓動咱們的項目

參考


相關文章
相關標籤/搜索