在docker中寫個Hello World

bookfree發表於2020-07-18

Hello World Docker

示例

  1. 準備hello.cpp
#include<stdio.h>

int main(){
  printf("Hello World Docker\n");
  return 0;
}
  1. 新建Dockerfile檔案(不區分大小寫,預設指令全大寫)
FROM gcc:9.3
# this is in docker filesystem, not host
WORKDIR /usr/src/app
COPY hello.cpp .
RUN g++ hello.cpp -o test
CMD [ "./test" ]

Dockerfile裡的指令是按序且相互獨立執行的,但第一個指令必須是FROM指令,該指令用於指定基礎image(比如示例基於gcc9.3 image)。

WORKDIR指定的是docker daemon處程式執行的位置,非客戶端處。

COPY將檔案拷貝到WORKDIR中。

RUN在daemon上執行指令。

CMD在daemon上執行cmd命令。

  1. 對docker的操作都是以docker命令開頭,在當前目錄構建docker並tag為hello:1.0
docker build -t hello:1.0 .

docker會在本目錄下搜尋Dockerfile檔案,使用者也可以通過-f選項指定Dockerfile檔案。

顯示的構建資訊:

Sending build context to Docker daemon  3.072kB
Step 1/5 : FROM gcc:9.3
 ---> e2a33649a4fc
Step 2/5 : WORKDIR /usr/src/app
 ---> Using cache
 ---> 6e517536c8a4
Step 3/5 : COPY hello.cpp .
 ---> Using cache
 ---> 94a4f0ecfe1b
Step 4/5 : RUN g++ hello.cpp -o test
 ---> Using cache
 ---> 92e3862f7e1e
Step 5/5 : CMD [ "./test" ]
 ---> Running in 1e7ffb943e31
Removing intermediate container 1e7ffb943e31
 ---> c0cef7d15884
Successfully built c0cef7d15884
Successfully tagged hello:1.0

構建完成。

  1. 以互動式方式(-i)執行hello:1.0 並別名(--name)為hello
docker run -it --name hello hello:1.0

docker開始執行./test程式,列印:

Hello World Docker
  1. 檢視docker當前狀態
docker ps -all

顯示:

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
03fb0b671849        hello:1.0           "./test"            8 seconds ago       Exited (0) 7 seconds ago                       hello

Exited的原因是hello程式執行太快,在ps前就已經退出。

  1. 停止docker執行
docker stop hello
  1. 最後刪除docker
docker rm --force hello

此時再ps會發現名為hello的docker已經消失不見。

docker build過程中發生的事

build命令

docker build [OPTIONS] PATH | URL | -
  1. docker build命令是由daemon而非客戶端執行的。

  2. docker會首先將PATH(本地目錄)下的所有目錄和檔案,或URL(git倉庫)下的所有模組遞迴的傳送到daemon中。

  3. 接著docker會在本目錄下搜尋·檔案,使用者也可以通過-f選項指定Dockerfile檔案。

  4. 在執行Dockerfile檔案裡的指令之前,docker會先驗證Dockerfile檔案是否有語法問題並報錯。

  5. 驗證正確後,docker將一個個執行Dockerfile裡的指令,每條指令相互獨立(也就是說上一條指令的結果不會影響下一條指令,比如cd /tmp並不會讓下一條指令在/tmp目錄下執行)。若指令執行成功,則將結果提交到一個新的image中(每條指令都將生成一個新的image)。

  6. 當然,docker會將可能重複利用中間生成的臨時image(cache)來加速build速度,是否用了cache可以通過(---> Using cache)資訊判斷。

  7. 在得到最終的imgae時,docker還會自動清理掉最初發過來的檔案。

  8. -t選項可以給構建成功後的image指定庫或tag(可以有多個)。

相關文章