幹訓4
YoMin Su
回想一下
身旁有沒有朋友打手遊打到走火入魔?
13 開的「天堂 2 革命」
或是拿買賣遊戲帳號當日常的朋友?
為了賺小錢,連虛擬機都拿來用了
甚至是,在一台電腦上裝多個系統?!
這一台主機裝了 7 個 Windows...
以上皆為取自網路的真實案例
今天要說的 Docker 則是在 Linux 的容器
(虛擬機的一種)
有沒有想過開 Minecraft 伺服器可以...
從這樣
變這樣
你一定會問,那兩張有差嗎?
有差,當然有差,不然幹嘛提 xD
那,差在哪?
一個需要你從官網下載檔案,自己處理所有東西 另一個只需要一條指令,便將所有東西都準備好
除了方便架伺服器外,還能做啥?
架各種服務、各種實驗環境、服務之間各自切分、etc...
那實際上該怎麼使用呢?
首先,你需要有 Docker Engine
相信你們的電腦都準備好了,畢竟,你們的環境都已經在之前的社課讓學長姐們確認過了! (如果不是用 WSL2 的,就會是 VM)
如果沒有呢?
① 將 WSL 1 升級到 WSL 2,並安裝 Docker Desktop ② 裝任一 Linux 系統到你的筆電上 <-- 推薦!!
良心建議
如果覺得之後還是會想玩 Docker 的話,建議用 ① 但若你有破釜沉舟的堅毅心態,決定非 Linux 系統不用的話,② 就給它用下去吧!
解決辦法 ①
wsl -l -v #找到你使用的Distro
wsl --set-version <Distro> 2 #將版本修改為2
記得安裝 Docker Desktop
解決辦法 ②
雖然很棒,但今天可能不太適合...
相信各位的 Docker 都應該可以使用了,無論你用哪種方法,可以上課的方法,就是好方法~
首次嘗試
Hello-World 的部分
docker run hello-world
執行畫面
指令分析
指令 | 用途 |
---|---|
docker | 一切的起頭 |
run | 執行一個 Image |
hello-world | Image 的名稱 |
拿 Minecraft 伺服器當範例
若想開一個伺服器的話...
docker run -e EULA=TRUE -d -p 25565:25565 --name mc itzg/minecraft-server
看起來是不是超複雜,超難懂?
一臉黑人問號...嗎?
我們一個一個參數來解釋吧!
「-e」參數
用於設定環境變數
EULA=TRUE
「-d」參數
用於讓 Container 執行在背景
就在背後跑,沒啥好說的~
「-p」參數
Port 映射,將容器裡面的 Port 對到容器外面 前面是外面,後面是裡面
25565:25565
友情提醒
預設情況下,Docker 會直接操作系統的 iptables,因此會直接跨過 ufw,若你希望服務只能在 Local 存取,請在 Port 前面加上 127.0.0.1,就像範例這樣
127.0.0.1:25565:25565
「--name」
幫容器取名字,方便你管理
mc
itzg/minecraft-server
就是 MC 伺服器的 Image 之一
也就 100M+人在用而已啦~
若你玩的是 Bedrock(基岩)版的話...
好像也有 Image 可以用呢!
除上述以外,「-v」參數
可以把裡面跟外面的檔案 Mapping 起來 路徑中間用「:」連接
前面是外面,後面是裡面
小測驗時間
/srv/gitlab:/etc/gitlab
哪個在內?哪個在外?
(Q1)Answer Here~
橘色在外,藍綠色在內如果想在容器中執行指令的話
docker exec -i mc rcon-cli
指令 | 用途 |
---|---|
exec | 執行指令 |
-i | 讓介面可以互動 |
mc | Container 名稱 |
rcon-cli | 指令 or 功能 |
Dockerfile
容器映像的起承轉合
用途
別人的映像很方便,我也想自己弄一個,可以嗎?
當然可以!
教學時間
我們來包前面設計出來的網頁吧!
# Build Stage
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY . .
RUN apk add make g++ \
&& npm install \
&& npm run build
# Production Stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
快速解釋時間
FROM | 讓此映像建立在另一個映像上 |
WORKDIR | 容器內的預設工作目錄 |
CPOY | 將目錄內的檔案複製到映像中 |
RUN | 在映像中執行指令 |
EXPOSE | 開一個"門"讓外側可以 Bind 通訊埠 |
CMD | 在映像啟動後執行的指令(程式) |
範例內容
嘿,就是你們前面在上前端課程時的成果啦!
記得剛剛寫好的 Dockerfile 要放在專案的根目錄喔!
Docker 很厲害,但有沒有方便執行的工具?
當然有,就是 Docker-Compose
幫你把所有設定集合起來,一次執行的好方法
首先提一下如何使用
啟動容器
docker-compose up
加上「-f」可以指定設定檔 加上「-d」可以在背景執行
停止容器
docker-compose down
若是以指定檔名的方式去啟動的話,記得一樣要指定檔名來結束
接下來來看內容大概長怎樣
範例的說
還是範例的說,多個服務
格式的部分
首先要注意的是,這是 yml 檔,也就是 YAML 格式
雖然不像 Python 那樣對空格極度敏感,但同級別的項目需要在該行前面有相同的空格數量
父項目與子項目,建議相差 2 格
實際操作時間
拿前面自己寫好的前端 Image 當範例 我們來實際寫一下 docker-compose.yml
範例內容
version: "3"
services:
front:
build: .
image: yunnet-training/frontend
ports:
- "127.0.0.1:3000:80"
特殊情況:只要啟動其中一個
若今天只需要啟動 yml 中的其中一個容器,可以透過在啟動指令的最後方加上服務名稱,即可單獨啟動
docker-compose up -d front
額外補充
前一頁所提到「加上服務名稱」的方法,基本適用於大部分 docker-compose 指令。也就是說,如果今天有單一容器需要更新或是重建,可以單獨重新 up 該容器,就可以處理好。
Image 分享
NodeJS
執行 JavaScript 的好夥伴
hub.docker.com/_/node
NGINX
反向代理 or 網頁伺服器 就靠它
hub.docker.com/_/nginx
Dockercraft
在 Minecraft 中管理你的容器的方法
github.com/docker/dockercraft
加分時間
Q2. YAML 格式有什麼特點?
- 對空格__,但要求__
- 每個項目後面都會加上__
- 通常父項跟子項差__個空格
(Q2)Answer Here!
- 對空格不敏感,但要求同階層項目前有相同數量的空白
- 每個項目後面都會加上冒號
- 通常父項跟子項差2 個空格
let score = 100;
console.log(`每格: {score}分`);
Q3. 如果不希望 Docker 啟動的服務直接對外,在給參數時該怎麼寫?
(Q3)Answer Here...
ports:
- "127.0.0.1:<Host Port>:<LXC Port>"
SCORE=250
echo "此題: $SCORE分"
Q4. 續上題,為什麼 Docker 啟動的服務會無視 ufw 建立的防火牆條件?
(Q4)Answer Here
因為 Docker Engine 會直接對系統的 iptables 進行修改,加入運作時需要的網路結構,因此 ufw 的設定才無法正確工作。
score = 300
print(f'你可以獲得{score}分!')