將您的 Go 映像檔作為容器執行

先決條件

按照步驟在 建置您的 Go 映像檔 中將 Go 應用程式容器化。

概觀

在先前的模組中,您為您的範例應用程式建立了一個 Dockerfile,然後使用 docker build 命令建立了 Docker 映像檔。現在您有了映像檔,您可以執行該映像檔並查看您的應用程式是否正在正確執行。

容器是一個正常的作業系統行程,只不過這個行程是被隔離的,並且擁有自己的檔案系統、自己的網路,以及與主機分離的獨立行程樹。

若要在容器內執行映像檔,請使用 docker run 命令。它需要一個參數,那就是映像檔名稱。啟動您的映像檔並確保它正在正確執行。在您的終端機中執行以下命令。

$ docker run docker-gs-ping
   ____    __
  / __/___/ /  ___
 / _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.10.2
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
                                    O\
⇨ http server started on [::]:8080

執行此命令時,您會注意到您沒有返回命令提示字元。這是因為您的應用程式是一個 REST 伺服器,它將在迴圈中執行,等待傳入請求,直到您停止容器,否則不會將控制權交還給作業系統。

使用 curl 命令向伺服器發出 GET 請求。

$ curl http://localhost:8080/
curl: (7) Failed to connect to localhost port 8080: Connection refused

您的 curl 命令失敗,因為伺服器連線被拒絕。這表示您無法連線到埠 8080 上的 localhost。這是預期的,因為您的容器在隔離環境中執行,其中包含網路。停止容器,並在您的本地網路上發布埠 8080 後重新啟動。

要停止容器,請按 ctrl-c。這將讓您返回終端機提示字元。

要發布容器的埠,您將在 docker run 命令上使用 --publish 旗標(簡稱 -p)。--publish 命令的格式為 [主機_埠]:[容器_埠]。因此,如果您想將容器內的埠 8080 公開到容器外的埠 3000,您將傳遞 3000:8080--publish 旗標。

啟動容器,並將埠 8080 公開到主機上的埠 8080

$ docker run --publish 8080:8080 docker-gs-ping

現在,重新執行 curl 命令。

$ curl http://localhost:8080/
Hello, Docker! <3

成功!您能夠連線到在埠 8080 上容器內執行的應用程式。切換回執行容器的終端機,您應該會看到 GET 請求記錄到控制台。

ctrl-c 停止容器。

在分離模式下執行

到目前為止一切順利,但您的範例應用程式是一個網路伺服器,您不應該讓您的終端機連線到容器。Docker 可以讓您的容器在背景以分離模式執行。要做到這一點,您可以使用 --detach 或簡稱 -d。Docker 將像以前一樣啟動您的容器,但這次會與容器分離並讓您返回終端機提示字元。

$ docker run -d -p 8080:8080 docker-gs-ping
d75e61fcad1e0c0eca69a3f767be6ba28a66625ce4dc42201a8a323e8313c14e

Docker 在背景啟動了您的容器,並在終端機上列印了容器 ID。

再次確認您的容器正在執行。執行相同的 curl 命令

$ curl http://localhost:8080/
Hello, Docker! <3

列出容器

由於您在背景執行了容器,您如何知道您的容器是否正在執行,或者您的機器上還有哪些其他容器正在執行?要查看機器上正在執行的容器清單,請執行 docker ps。這類似於 ps 命令用於查看 Linux 機器上行程清單的方式。

$ docker ps

CONTAINER ID   IMAGE            COMMAND             CREATED          STATUS          PORTS                    NAMES
d75e61fcad1e   docker-gs-ping   "/docker-gs-ping"   41 seconds ago   Up 40 seconds   0.0.0.0:8080->8080/tcp   inspiring_ishizaka

ps 命令會告訴您許多關於您正在執行的容器的資訊。您可以看到容器 ID、容器內執行的映像檔、用於啟動容器的命令、建立時間、狀態、公開的埠以及容器的名稱。

您可能想知道容器的名稱是從哪裡來的。由於您在啟動容器時沒有提供名稱,Docker 產生了一個隨機名稱。您稍後會修正此問題,但首先您需要停止容器。要停止容器,請執行 docker stop 命令,並傳遞容器的名稱或 ID。

$ docker stop inspiring_ishizaka
inspiring_ishizaka

現在重新執行 docker ps 命令以查看正在執行的容器清單。

$ docker ps

CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

停止、啟動和命名容器

Docker 容器可以啟動、停止和重新啟動。當您停止容器時,它不會被移除,但狀態會更改為已停止,並且容器內的行程會停止。當您執行 docker ps 命令時,預設輸出只顯示正在執行的容器。如果您傳遞 --all 或簡稱 -a,您將看到系統上的所有容器,包括已停止的容器和正在執行的容器。

$ docker ps --all

CONTAINER ID   IMAGE            COMMAND                  CREATED              STATUS                      PORTS     NAMES
d75e61fcad1e   docker-gs-ping   "/docker-gs-ping"        About a minute ago   Exited (2) 23 seconds ago             inspiring_ishizaka
f65dbbb9a548   docker-gs-ping   "/docker-gs-ping"        3 minutes ago        Exited (2) 2 minutes ago              wizardly_joliot
aade1bf3d330   docker-gs-ping   "/docker-gs-ping"        3 minutes ago        Exited (2) 3 minutes ago              magical_carson
52d5ce3c15f0   docker-gs-ping   "/docker-gs-ping"        9 minutes ago        Exited (2) 3 minutes ago              gifted_mestorf

如果您一直按照步驟操作,您應該會看到列出的多個容器。這些是您啟動和停止但尚未移除的容器。

重新啟動您剛停止的容器。找到容器的名稱,並將以下 restart 命令中的容器名稱替換掉

$ docker restart inspiring_ishizaka

現在,使用 ps 命令再次列出所有容器

$ docker ps -a

CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS                     PORTS                    NAMES
d75e61fcad1e   docker-gs-ping   "/docker-gs-ping"        2 minutes ago    Up 5 seconds               0.0.0.0:8080->8080/tcp   inspiring_ishizaka
f65dbbb9a548   docker-gs-ping   "/docker-gs-ping"        4 minutes ago    Exited (2) 2 minutes ago                            wizardly_joliot
aade1bf3d330   docker-gs-ping   "/docker-gs-ping"        4 minutes ago    Exited (2) 4 minutes ago                            magical_carson
52d5ce3c15f0   docker-gs-ping   "/docker-gs-ping"        10 minutes ago   Exited (2) 4 minutes ago                            gifted_mestorf

請注意,您剛重新啟動的容器已在分離模式下啟動,並且已公開埠 8080。另請注意,容器的狀態為 已啟動 X 秒。當您重新啟動容器時,它將使用最初啟動時相同的旗標或命令啟動。

停止並移除所有容器,然後看看如何修正隨機命名問題。標準做法是為您的容器命名,原因很簡單,這樣更容易識別容器中執行的內容以及它與哪個應用程式或服務相關聯。就像程式碼中變數的良好命名慣例一樣,它可以使閱讀更容易。命名您的容器也是如此。

停止您剛啟動的容器。找到您正在執行的容器的名稱,並將以下命令中的名稱替換為您系統上容器的名稱

$ docker stop inspiring_ishizaka
inspiring_ishizaka

現在所有容器都已停止,請將它們移除。當容器被移除時,它不再執行,也不處於停止狀態。相反,容器內的行程會終止,並且容器的後設資料會被移除。要移除容器,請執行 docker rm 命令並傳遞容器名稱。您可以在一個命令中將多個容器名稱傳遞給該命令。

同樣,請確保您將以下命令中的容器名稱替換為您系統中的容器名稱

再次執行 docker ps --all 命令以驗證所有容器都已消失。

$ docker rm inspiring_ishizaka wizardly_joliot magical_carson gifted_mestorf

inspiring_ishizaka
wizardly_joliot
magical_carson
gifted_mestorf

再次執行 `docker ps --all` 命令,確認所有容器都已移除。

現在,處理惱人的隨機名稱問題。標準做法是為您的容器命名,原因很簡單,這樣更容易識別容器中執行的內容以及它與哪個應用程式或服務相關聯。就像程式碼中變數的良好命名慣例一樣,它可以使閱讀更容易。命名您的容器也是如此。

要命名容器,您必須將 `--name` 旗標傳遞給 `run` 命令

$ docker run -d -p 8080:8080 --name rest-server docker-gs-ping
3bbc6a3102ea368c8b966e1878a5ea9b1fc61187afaac1276c41db22e4b7f48f
$ docker ps

CONTAINER ID   IMAGE            COMMAND             CREATED          STATUS          PORTS                    NAMES
3bbc6a3102ea   docker-gs-ping   "/docker-gs-ping"   25 seconds ago   Up 24 seconds   0.0.0.0:8080->8080/tcp   rest-server

現在,您可以根據名稱輕鬆識別您的容器。

後續步驟

在本模組中,您學習了如何執行容器和發布埠。您還學習了如何管理容器的生命週期。然後,您學習了命名容器的重要性,以便更容易識別它們。在下一個模組中,您將學習如何在容器中執行資料庫並將其連線到您的應用程式。