# CNTUG Infra Labs 使用心得 - Docker 學習筆記 ## 前言 在學習雲原生相關技術時,最缺乏的其實就是機器,感謝 CNTUG Infra Labs,讓我不用花錢就能體驗到基礎建設即服務(IaaS),透過實際動手操作,能夠更深入地學習這些技術。 ## 甚麼是 Docker 以往將軟體從 A 機器移植到 B 機器會遇到非常多的問題,如環境不一致,版本相容性,套件衝突等。但在 dotScale 2013 的其中一場演講 Solomon Hykes - Why we built Docker,演說後隨即引起很大的轟動,有了 Docker,就等於有了一個可靠的自動化移植的工具,開發團隊能夠更好的去協作,在進行部屬時,也不會因為前述的問題而煩惱,有興趣的話歡迎看看當初的演說。 {%youtube 3N3n9FzebAA %} ## Docker vs Virtual Machine 同樣都是虛擬化技術,那 Docker 跟 VM 的差別究竟是甚麼?  > source: [The 10 Most Common Questions IT Admins ask About Docker]([the-10-most-common-questions-it-admins-ask-about-docker](https://www.docker.com/blog/the-10-most-common-questions-it-admins-ask-about-docker/)) 可以很明顯地看到上圖左側的容器化以及右側的虛擬化差別,Docker少了虛擬化 OS Kernel 層的部分,直接跟 Host 共用 Linux Kernal,透過Linux Kernel的資源隔離功能(例如 cgroups 和 namespace )允許獨立的`容器`在單個 Linux 實例中運行。(簡單說都是讓服務間不會互相干擾,但需要的資源比VM更少了) :::success 想了解更多 Linux Kernel 知識的話可以去看 Jsev 的[「Linux 核心設計」系列講座](https://hackmd.io/@sysprog/linux-kernel-internal) ::: 這就讓 Docker 多了幾個優點: * 簡化部屬流程 * 架設環境更便利 * 有效率的虛擬化 * 可擴展性 但也導致了某些問題: * 由於跟 Linux 共用 Kernel 進而產生安全上的漏洞 * Docker Daemon 具有 root 權限 (Podman 逐漸成為明日之星!?) ## Docker 基本概念 Docker 主要有以下幾個基本概念: * Image * Container * Volume * Network ## Image Image 就如同是應用程式的模板一樣,舉個現實情況的例子,假設你正在開發一個 Python 的 Web 應用程式,並使用 Flask 框架。 * 在沒有 Docker 的情況下: 你需要確保環境中已安裝正確版本的 Python,手動安裝 Flask 及其他相依套件等等。這導致了開發環境和生產環境之間的不一致,並增加部署的複雜性。 * 有了 Docker 之後: 你可以建立一個 Docker Image,裡面包含了正確版本的 Python、Flask,以及你的應用程式代碼。任何人只要有 Docker 都可以透過使用你的 Docker Image 建立出一模一樣的 Web 應用程式,而不用擔心相依性問題。 要建立自己的 docker image 需要先創建一個 Dockerfile,那我們就以上述例子實際建立看看。 ```dockerfile! FROM python:3.10.13-alpine3.18 WORKDIR /app COPY . . RUN pip install Flask==3.0.0 CMD ["python3", "main.py"] ``` * FROM: 指定基底要用的image,預設會從docker hub 上有的抓下來。 * WORKDIR: 指定容器要用的路徑。(路徑不存在時,Docker 會自動創建) * ADD: 將本機端目前路徑下的所有檔案複製到容器的`/app`路徑下。(因為我們已經將容器的目前路徑設為`/app`) * RUN: 創建 Image 時要執行的指令。 * CMD: 當 Container 啟動時,要執行的指令。 接著使用以下指令來 build Image: ```bash docker build -t python-web-app:3.10.13 . ``` * `-t`: 指定 Image 的名稱以及標籤,格式為:`name:tag`。 * `.`: 告訴 Docker 從當前路徑下找 Dockerfile。 如果沒有出現任何 Error,就表示成功建立一個屬於你自己的 Docker Image了:  ## Container Build 好了 Image 之後,下一步當然就是啟動,也就是利用 Container 來啟動剛剛建立好的 Image。 ``` docker run --rm -p 80:1234 -d python-web-app:3.10.13 ``` * `-p`: 代表從本機端的 `80 port` forwarding 到 Container 的 `1234 port`,這樣才能夠從本機端看到你的網頁。 * `-d`: 代表 Container 在背景執行,也就不用占用你的 Terminal了。 * `--rm`: 代表當Container 執行完就直接移除。(因為 Container 執行完後會變成停止狀態,如果不需要的話就可以透過`--rm`移除。  接著你就可以開一個網頁輸入`localhost` 也就是本機端的 IP 來查看你的網頁了。 :::warning 由於我的本機目錄下並沒有 `main.py` 這個程式,所有執行起來會看不到網頁是正常的,實際看到 Container 的 log 也會跟你說沒有此檔案。  ::: :::info 想實際看看網頁的話可以透過 nginx 執行以下指令,接著在網頁上輸入`localhost`就能看到網頁。 ``` docker run -p 80:80 nginx:1.25.3 ```  ::: ## Volume 由於 Container 內部就是一個隔離的環境,,所以當 Container 關閉之後資料也就沒了。 那如果我要執行像資料庫這種類型的 Container 該怎麼辦? 那就是要透過 Volume 綁定本機端的 path 到容器內的 path。 :::success 本次介紹主要講解最簡單的 `-v` 或是 `--volume`,如果想要了解更詳細的知識,像是 `--mount` 和 `--tmpfs`可以去 Docker Docs了解喔。 > https://docs.docker.com/storage/volumes/ ::: 當我們在執行`docker run` 指令時,其實只要多設一個參數,就可以將本機端的路徑綁定Container 的路徑了。 ``` docker run --rm -p 80:80 -v ./:/data alpine:3.19.1 ``` 例如我現在test目錄底下有一個 Dockerfile,內容為: ```dockerfile FROM python:3.10.13-alpine3.18 WORKDIR /app COPY . . RUN pip install Flask==3.0.0 CMD ["python3", "main.py"] ``` 接著在看容器內的`data`目錄下也有 Dockerfile,來看看是不是跟本機端的 Dockerfile 一模一樣。  這樣就代表成功將容器內的資料綁定到主機端摟。 ## 使用 Docker 架設幻獸帕魯專用伺服器 :::warning CNTUG Infra labs 的平台原則上不允許用戶使用服務來架設遊戲伺服器喔。 ::: 那接下來我們就來實際建立幻獸帕魯的專用伺服器。(本次所使用的 docker image 請參考下方連結) > [thijsvanloef/palworld-server-docker](https://github.com/thijsvanloef/palworld-server-docker/tree/main) 首先先透過`git clone`將上面連結的repo複製一份到本機端。 ```bash= git clone https://github.com/thijsvanloef/palworld-server-docker.git ``` 接著更改目錄內的`docker-compose.yml`,將`environment`替換成`env_file`,並指定檔案為`.env.example`。 :::success Docker compose 就是可以一次啟動好幾個 Docker Container 的方法 ::: ``` services: palworld: image: thijsvanloef/palworld-server-docker:latest restart: unless-stopped container_name: palworld-server stop_grace_period: 30s # Set to however long you are willing to wait for the container to gracefully stop ports: - 8211:8211/udp - 27015:27015/udp # Required if you want your server to show up in the community servers tab env_file: - .env.example volumes: - ./palworld:/palworld/ ``` 接著就可以修改`.env.example`的內容,來設定伺服器內的設定,參數對應可參考Repo內的READ.md。 > https://github.com/thijsvanloef/palworld-server-docker?tab=readme-ov-file#environment-variables 接著輸入以下指令執行Server。 ``` docker compose up -d ``` 在進入遊戲內 -> 參加多人遊戲 (專用伺服器) -> 透過下方IP連線 (如果有新增密碼請記得把輸入密碼打勾)  這樣你就建立好一個幻獸帕魯的專用伺服器摟! :::warning 如果要讓其他人連線進來,需要將IP換成 Public IP,另外防火牆也需要將 Port 8211 開啟。 ::: ## 感想 非常感謝這次成功申請到 CNTUG Infra,雖然第一次寫心得文可能文筆有點不好,但我很高興能在開源社群的活動中做出一點貢獻。各位如果使用 Docker 建置 Palworld 專用伺服器有任何問題都可以在下方 github repo 發 issue,或是到 Discord 問問題也行喔。 * **Github** : https://github.com/thijsvanloef/palworld-server-docker * **Discord** : https://discord.gg/wcytChKQ
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up