Docker 是一種輕量的虛擬化技術,允許您將應用程式及其相依環境打包成一個被稱為容器的可執行單位。 每個容器都包含了應用程式程式碼、執行環境、系統工具、依賴庫檔案等,使得應用程式能夠在任何支援 Docker 的環境中運行,不受系統和底層環境影響。 在軟體開發及部署中,容器技術正逐漸成為不可或缺的一部分,而 Docker 作為最常見的容器平台之一,為開發者提供了一種輕量且可移植的部署方式。

簡單來說,Docker 可以讓您將辛苦開發完成的應用程式跨平台執行,當您將程式從 Linux 搬移到 Windows,或者搬移到任何其它伺服器上,您無需擔心這些新設備的執行環境,就能直接透過 Docker 執行您的程式。

Docker 的基本概念

Docker 最基本的三個東西,分別是 Dockerfile、映像檔 (Image) 及容器 (Container)。

Dockerfile
Dockerfile 是用來建立 Image 的文本檔案,可以把它視為建立 Image 的腳本。 通過 Dockerfile,開發者可以定義 Image 的內容、環境和運行方式,實現自動化的 Image 建立過程。
映像檔 (Image)
Image 是一個包含應用程式及其相依環境的模板,可以用來建立 Container。 Image 是不可變的,如果您要更改 Image 的內容,就只能重新生成一個新的 Image。
容器 (Container)
Container 是使用 Image 建立的運行實例,您的程式實際上是在 Container 中運行。 Container 是一個隔離的執行環境,包括應用程式及相依套件,可以快速部署、複製和遷移,確保應用程式在不同環境中的一致運行。

根據上述說明,在流程上,您需要先撰寫 Dockerfile,再透過 Dockerfile 建立 Image,最後由 Image 建立 Container。 當 Container 建立後,Docker 允許您使用終端機進入 Container 中,並像 Linux 一樣使用指令進行操作,但實務上不建議您用這種方式更改 Container 中的內容,因為當未來打包程式碼時,您不一定會記得您曾經做過哪些操作。 進入 Container 通常是為了 Debug 使用,當您建立的 Container 有問題時,您可以透過這種方式尋找原因,當您確定造成錯誤的原因時,您應該果斷的把 Container 刪除,並且重新調整參數或 Dockerfile 來重新建立 Container。

安裝 Docker

以下安裝以 Ubuntu 22.04 為例,先設定 Docker 的 apt 安裝來源。

            
                # Add Docker's official GPG key:
                sudo apt-get update
                sudo apt-get install ca-certificates curl gnupg
                sudo install -m 0755 -d /etc/apt/keyrings
                curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
                sudo chmod a+r /etc/apt/keyrings/docker.gpg

                # Add the repository to Apt sources:
                echo \
                  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
                  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
                  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
                sudo apt-get update
            
        

安裝 Docker。

            
                sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
            
        

安裝方法也蠻簡單的,就是用 apt-get 安裝即可,其他作業系統的安裝方式,可以參考官網說明。

建立第一個 Docker 容器

建立 Docker 容器需要先有 Image,而 Image 可以透過 Dockerfile 建立,也可以直接使用網路上的 Image。 絕大部分的應用您都可以在 Docker Hub 網站上找到相關 Image,而無需自己撰寫 Dockerfile。 不過您還是應該學習撰寫 Dockerfile,這在實務上真的很常使用,當您要將程式打包給其他人時,只要把 Dockerfile 一起提供給對方,他就能用這個 Dockerfile 建立 Container 並執行您的程式,而無需一直跟您詢問要怎麼安裝。

使用 Dockerfile 建立容器

                
                    # 切換到 Dockerfile 檔案所在目錄,假設為 test 目錄
                    cd test

                    # 使用 docker build 建立 image
                    docker build . --no-cache -t [自訂映像檔名稱]

                    # 使用 image 建立容器
                    docker run --name [自訂容器名稱] [映像檔名稱]
                
            

使用網路映像檔建立容器

                
                    # 先將網路映像檔,下載到本地電腦中
                    # 假設下載 mosquitto 最新的映像檔,下方指令冒號後面是指版本
                    docker pull eclipse-mosquitto:latest

                    # 使用 image 建立容器
                    # 指令:docker run --name [自訂容器名稱] [映像檔名稱]
                    docker run --name mosquitto eclipse-mosquitto
                
            

上面是一個非常簡單的案例,實際上每個映像檔都會提供不同的建立參數,除了可以觀看 Docker Hub 上的說明之外,也可以使用 docker inspect 指令查看映像檔資訊。 此外,docker inspect 也能查看容器資訊,當映像檔及容器名稱相同時,就會造成混肴,此時可以使用 --type 參數來指定是映像檔還是容器。

                
                    # 查看容器資訊
                    # --type=image 映像檔
                    # --type=container 容器
                    docker inspect --type=image eclipse-mosquitto
                
            

容器建立的重點不外乎就是 port 的對應跟目錄個掛載,以建立 Mosquitto MQTT Broker Container 為例,實際的建立指令可能長得像下方這樣。

                
                    # -d: 背景執行,建立後返回容器 ID
                    # --restart=always: 開機自動啟動
                    # -u: 使用特定帳號執行
                    # -p: 設定本機 PORT 對應至容器中的 PORT
                    # -v: 設定本機目錄對應至容器中的目錄
                    docker run -d --name mosquitto \
                        --restart=always \
                        -u 501:20 \
                        -p 1883:1883 -p 9001:9001 \
                        -v ~/docker/mosquitto/data:/mosquitto/data:rw \
                        -v ~/docker/mosquitto/log:/mosquitto/log:rw \
                        -v ~/docker/mosquitto/config:/mosquitto/config:rw \
                        eclipse-mosquitto
                
            

Docker 常用指令

以下是我常用且最基本的指令操作,提供大家參考。

            
                # 查詢映像檔資訊
                docker inspect --type=image [映像檔 ID]

                # 查詢容器資訊
                docker inspect --type=container [容器 ID]

                # 查詢本機映像檔
                docker images

                # 刪除本機映像檔
                docker rmi [映像檔 ID]

                # 查詢本機容器
                docker ps -a

                # 下載映像檔
                docker pull [映像檔名稱]:[映像檔版號]

                # 建立容器
                docker run --name [自訂容器名稱] [映像檔名稱]

                # 啟動容器
                docker start [容器名稱]

                # 暫停容器
                docker stop [容器名稱]

                # 刪除容器
                docker rm [容器ID]

                # 進入容器
                docker exec -it [容器名稱] /bin/sh

                # 查看容器的 Log 訊息
                docker logs --follow [容器名稱]

                # 使用 Dockerfile 建立 image
                docker build . --no-cache -t [自訂映像檔名稱]