[Note] Docker Getting Started
此篇為筆記之整理,非原創內容,資料來源主要來自:Docker and Kubernetes: The Complete Guide @ Udemy
重要概念
- Image(映像檔):有所有執行程式時所需要相依的內容、設定、指令和執行檔。當在執行 container 時,它會使用一個獨立的檔案系統,而這個檔案系統即是透過 image 來提供。
- Container(容器):image 的 instance,真正執行的程式,它是獨立於本機所有 process 以外的一個 process。Container 包含了 image 中的 FS snapshot 和 Startup Command。
- Docker Client(Docker CLI):輸入 docker 指令的地方,可以透過安裝 Docker Desktop 取得
- Docker Server(daemon):建立映像檔、執行容器的地方
Kernel 和 Container
Kernel 介於硬體和軟體的中間,當應用程式在執行時,會透過 system call 告知 kernel 要執行的項目(例如,寫檔),kernel 收到指令後會再對硬體進行操作:

- name spacing:可以 將單一 process(或 group of processes)使用到的資源加以隔離
- control groups(cgroups):可以限制每個 process 可以使用到的資源量多寡(例如,memory 的大小、CPU 的效能)

Container 的概念就如同下圖中紅色框線的位置:

Image 和 Container
- image 會在 container 中執行
- 當我們在講 image 的時候,實際上包含了一個「檔案系統的快照(FS Snapshot)」和「啟動他的指令(Startup Command)」
- 當一個 image 要在 container 中執行時,會把 image 中對應的 FS Snapshot 和 Startup Command 放一份到 container 中加以執行

Docker Life Cycle(Status of Container)
- created
- up(表示在執行中)
- exited
建立 Image
Dockerfile 建立的流程如下:
- 選定一個現有的 image 當作 base image
- 執行一些指令來安裝其他的程式
- 定義一些指令來啟動該 container
建立 Dockerfile
The Build Process in Detail @ Docker and Kubernetes: The Complete Guide @ Udemy
Dockerfile 的內容就像是告訴一台沒有內建 OS 的電腦,要如何重零開始把應用程式安裝進去。
# Dockerfile
# Use an existing docker image as a base
FROM alpine
# Download and install a dependency
RUN apk add --update redis
# Tell the image what to do when it starts as a container
CMD ["redis-server"]
- 我們之所以要安裝 OS,是因為它通常內建了我們所需要的程式,這裡使用
alpine是因為它有內建apk的指令,方便我們安裝所需的套件
docker build:建立 image
在建立好 Dockerfile 後,可以執行 docker build 指令:
# 建立好 Docker file 後
$ docker build . # 執行建立好的 Dockerfile 後,會得到 image 的 id
$ docker run b9124cbfdc30 # 透過 docker run 可以執行
docker build 會做以下行為:
- 每一個 Step 都會啟動一個 container 執行對應的行為,完成後會把它存成一個暫時的 image。
- 接著,在下一個 Step 開始時,會去使用上一個 Step 留下的 Image,並以此再次啟動一個 Container,執行該 Step 對應的指令,該指令執行完後,同樣的會再把最終完成的結果存在一個 Image,以這樣的流程重複完成每個 Step。
- 待所有 Step 都執行完後,最終會有一個 Image 可以讓使用者執行
docker run <image-id>
一般我們在使用別人的 image 時,是根據 image 來建立對應的 container,但當我們要透過 Dockerfile 來建立 image 時,則是根據 container 來產生出 image。也就是說,逐步執行這個 Dockerfile 的過程會像是下面這樣(通常不會這麼做,單純示範用):
# 從 container 建立一個 image
$ docker run -it alpine sh
$ / apk add --update redis
# 開啟另一個 Terminal
$ docker commit -c 'CMD ["redis-server"]' <container-id> # 會回傳 image-id
$ docker run <image-id>