Docker踩坑指南2:Dockerfile和Docker Compose

一、Dockerfile

Dockerfile 用途

Dockerfile是用來干嘛的?之前我們介紹了Docker的主要用途,用來節(jié)省配置運行環(huán)境的開銷,接著講了一大堆docker命令,但還沒講到具體該如何生成一個鏡像文件。

上次我們是講過一條命令,docker container commit,它可以將正在運行的容器保存成鏡像。然后官方提供了很多已經(jīng)配置好運行環(huán)境的鏡像諸如TomcatNodeJs、MySQL等等都有,所以只需要運行這些鏡像,再把把自己的項目文件放進去,然后用commit命令生成鏡像文件,接著在服務器上下載這個鏡像文件并運行就可以了。

這個方法理論上雖然可行,但每修改一次項目文件,就需要手動運行鏡像然后再復制文件,這實在很不方便;再加上很多時候官方提供的鏡像并不一定完全滿足我們的要求,我們需要做很多自定義的配置,每次都要手動進行配置,然后再coomit保存,費時間不說還容易出錯。而Dockerfile就是這樣產(chǎn)生的,它將手動的配置運行環(huán)境轉(zhuǎn)換成了一條條的特殊指令,每次修改完工程之后,只需要輸入docker built命令便可以自動執(zhí)行這些指令并生成鏡像文件,方便又快捷。除此之外,Dockerfile 在生成鏡像文件的過程中會生成很多層的緩存,重新執(zhí)行docker built時如果中間某些指令執(zhí)行的時候文件系統(tǒng)沒有發(fā)生變化,這些指令就不會重復運行,從而節(jié)省了很多時間。

Dockerfile 指令舉例

在明白了它的用途之后我們就來學習最關(guān)鍵的部分,它有哪些指令。

首先就用我個人的一個Django(Python的一個web后端框架)項目來作為范例展示:

FROM nginx
WORKDIR /usr/src/app

COPY resources/sources.list /etc/apt/sources.list
COPY resources/pip.conf /root/.pip/pip.conf
RUN apt update && apt -y install python3 python3-pip
RUN pip3 install uwsgi

COPY resources/requirements.txt requirements.txt
RUN pip3 install -r requirements.txt

RUN mkdir -p /var/www/
COPY static /var/www/static
COPY code .
COPY resources/start.sh .
RUN chmod +x ./start.sh
ENTRYPOINT ["./start.sh"]
  • 首先開頭的FROM nginx表示根據(jù)哪個鏡像進行修改制作,雖然官方也有Django的鏡像,但無法滿足我的要求,于是直接根據(jù)官方nginx鏡像進行制作。

  • 接下來的WORKDIR /usr/src/app,是設置工作目錄,就和命令行的cd差不多,后面運行的所有命令都會基于這個工作目錄進行,不過如果運行這條指令的時候右邊的目錄不存在則會自動創(chuàng)建這個目錄。

  • 后面是配置運行環(huán)境的主要過程,主要是 COPY 和 RUN 命令。COPY xxx yyy:就是將文件從本地復制到鏡像內(nèi)部,xxx 是源文件在本機上的目錄;yyy 是目的文件在鏡像內(nèi)部的路徑,由于之前設置了工作目錄,所以實際的目的文件路徑就是 /usr/src/app/requirements.txt,例如我這里復制了 Django的Python依賴(requirements.txt)、debian 的國內(nèi)下載源(sources.list)、pip 的配置文件以及整個項目工程到鏡像里。

    RUN 命令也很簡單,就是在生成鏡像文件過程中需要運行的命令,例如我這里運行的命令有安裝Python依賴、創(chuàng)建文件夾、設置文件權(quán)限等等。

  • 最后就是 ENTRYPOINT 命令,設置了運行鏡像時要執(zhí)行的命令,我這里因為要同時運行多個命令,所以把它寫成了shell腳本文件。

還有其他很多諸如設置環(huán)境變量、標簽、暴露端口號什么的還有很多,我覺得沒必要詳細介紹了,直接看官網(wǎng)的文檔或CSDN博客就都可以理解了,這里就只重點介紹一下 ENTRYPOINTCMD 的異同。

ENTRYPOINT 和 CMD 的區(qū)別

剛剛我們的示例中用的是ENTRYPOINT,而CMD的作用也差不多,都是設置在容器運行以后執(zhí)行的命令,在沒有設置ENTRYPOINT的情況下,才會使用CMD后面的指令。

兩者的基本語法如下:

ENTRYPOINT <command> 或
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]

第二種是官方推薦的使用方法,將命令分成幾段,寫成數(shù)組的形式;也可以像RUN一樣寫成shell的形式。

CMD <command> 或
CMD ["<executeable>","<param1>","<param2>",...] 
CMD ["<param1>","<param2>",...]

這里的第二種也是官方推薦的寫法,而第三種用法則是和 ENTRYPOINT 一起使用的,可以實現(xiàn)在 ENTRYPOINT 中設置執(zhí)行的程序,而在 CMD 中設置對應的參數(shù),例如下面的示例則會執(zhí)行top -b -c。

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

還有一點重要的就是,docker run命令后面可以接一個默認運行的命令,它會替換掉 CMD 后面的命令,而 ENTRYPOINT 后面的命令則不會被替換掉。



二、Docker Compose

Docker Compose 是官方用 Python 寫的一個小工具,因為有時候需要同時運行多個Docker服務,例如一個簡單的網(wǎng)站就需要用到至少兩個服務——網(wǎng)頁前后端、MySQL服務,而采用手工管理多個服務(包括創(chuàng)建鏡像,開始、停止、刪除容器等等)并不是很方便,于是 Docker Compose 應運而生,它可以方便的管理多個Docker服務,同時它將 docker run 的運行參數(shù)改成了文本文件的配置方式,方便臨時修改參數(shù)。

Compose file 簡述

Docker Compose 主要就是一個docker-compose.yml文件,里面設置的每個service就相當于一條docker run命令,下面我也用同一個項目的文件范例來介紹:

version: '3'

services:
  database:
    image: mysql
    environment:
      - MYSQL_ROOT_PASSWORD=XXXXXXXXX
      - MYSQL_DATABASE=bxnb_db

  web:
    image: registry.cn-hangzhou.aliyuncs.com/tommy0607/bxnb-website:v1.5
    ports:
      - "80:80"
      - "443:443"
    environment:
      - ENV=production
  • 開頭第一行是Compose file的版本,現(xiàn)在基本上用版本3就可以了
  • 后面的services里面是不同的服務,我這里定義了數(shù)據(jù)庫和網(wǎng)頁前后端這兩個服務,database和web是自定義的服務名
  • image指定了服務所使用的鏡像名
  • environment設置了容器所用的環(huán)境變量,與-e xxxx=yyy的作用一致
  • ports設置了向外部映射的端口,與-p 80:80的作用一致

總之就是docker run后面的每一個參數(shù)都可以對應一個相關(guān)屬性,除此之外還可以設置不同服務間的依賴關(guān)系等等,這些屬性就直接看官方文檔就好了,這里不再詳述。

Docker Compose 命令介紹

Docker Compose里的命令都和docker里的命令相對應,實現(xiàn)一條命令來開始、停止、刪除容器等等的操作

Commands:
  build              Build or rebuild services
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  ps                 List containers
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers

主要有上面一些命令,其他的我就不介紹了,就介紹兩個up和down:

  • up命令就是一鍵創(chuàng)建鏡像、運行容器,要記得加上-d參數(shù)表示在后臺運行。
  • down命令就是一鍵停止容器、刪除容器、刪除鏡像。

這些命令后面都可以加上針對的服務名列表,如果不加服務名的話表示對所有服務執(zhí)行這些命令

舉個例子:docker-compose up -d database就是創(chuàng)建并后臺運行數(shù)據(jù)庫服務。


本次學習就到這里結(jié)束了,基本上掌握了Docker中需要用到的各種東西了,收獲挺大的!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容