### GDSC NYUST x 資訊創客社
<br>
### 軟體開發工具入門讀書會
#### Docker課程
<br>
#### 2023/11/01 ( Wed ) 19:00 - 21:00
#### 講師:蘇祐民
#### 本次課程影片:(⚒️製作中)
<img src="" height="200px">
---
# Docker
*YoMin Su*
---
## 課程簡介
----
### 簡單的說
- 認識Docker
- 安裝Docker
- 使用Docker
----
### 複雜的說
- 認識Docker
- 安裝Docker
- Docker的基本指令: ps, run, stop, rm
- Docker的進階指令: images, pull, build
- 學習Docker Compose
- 自定義Docker映像
- 透過Docker建立網頁伺服器
- 了解Docker的Network與Volume
---
## Docker 簡介
----
### 什麼是Docker
Docker是目前軟體開發上非常方便也重要的一個工具,本身基於Linux系統中的容器(LXC)技術,透過作業系統層級的虛擬化,讓其能不佔用大量的硬體資源,也可以做到隔離工作環境的效果,因此在目前軟體開發的生態上,被大量且廣泛的採用,幾乎所有你聽過的軟體套件,都有容器的版本可以使用!
 
----
### 使用Docker的好處?
- 環境隔離
- 應用程式獨立
- 部署簡單
- 打包簡單
- 需求效能少
- 擴充彈性
- etc...
----
### Docker帶來的難點
- 容器間的網路
- 儲存資料管理
---
## 安裝Docker
----
### 找找官方文件
> 安裝文件連結:[請點我](https://docs.docker.com/engine/install/ubuntu/)

----
### 新增Docker官方的apt來源
這會自動將驗證用的GPG鑰匙下載到系統上,並新增軟體安裝的來源
```bash=
# 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 Engine
```shell=
sudo apt-get install docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
```
----
### 啟動Docker Engine
```shell=
service docker start
```
----
### 來驗證你是否安裝好了
```shell=
sudo docker run hello-world
```

----
### 將使用者加入到docker群組
> 每次使用都需要sudo太麻煩了...
<br />
```shell=
sudo usermod -aG docker $USER
```
完成後記得要關閉終端機重開喔!
----
### 再次確認可以正常使用
```shell=
docker run hello-world
```

---
## Docker的基本觀念
----
### 容器與映像的區別
容器:
- 正在運行中的實例
- 有實際儲存的資料內容
- 有與其他容器或主機連接的IP
映像:
- 啟動容器前的必要檔案
- 包含該服務所需要的基本系統與功能
- 可自己建立,但要修改則需重新創建
----
### 映像可以去哪裡找到?
- Docker Hub
- ghcr.io (GitHub)
- gcr.io (Google)
----
### 容器運作時,東西都在哪裡?
Docker Engine會在系統中生成對應所需要的檔案與分配運作需要的系統資源,通常檔案都會放在指定的資料夾下,可以一起來看看:
```shell=
sudo su
cd /var/lib/docker
```
- containers: 放當下運作的容器的設定檔
- volumes: 放Volume檔案的資料夾
- network: 放Network設定的資料夾
---
## Docker 基本操作
----
### docker ps
用來檢視目前有哪些運作中的容器
```shell=
docker ps -a
# -a 可以看到完整的列表,包含停下來的容器
```

----
### docker run
用來啟動容器,這裡拿啟動Minecraft伺服器當範例
```shell=
docker run \
-e EULA=TRUE \
-d \
-p 25565:25565 \
--name mc-server \
itzg/minecraft-server
```
<br />
說明如下:
----
### docker run
| Command | Description |
| --------------------- | ---------------------- |
| docker run | 啟動容器的指令 |
| -e EULA=TRUE | 環境變數 |
| -d | 背景啟動 |
| -p 25565:25565 | 將容器中的埠映射到主機 |
| --name mc-server | 幫容器命名 |
| itzg/minecraft-server | 容器名稱 |
----
### docker run

圖片中所出現的『f3c9b36d...』正是Docker Engine幫容器標記的ID
在操作時,可以使用 ID 或 Name 進行指定
----
### docker stop
正如其名,是用來將容器停下來的指令
```shell=
docker stop mc-server
# or
docker stop f3c9b36d
```

----
### docker rm
當我們將容器停下來後,資料仍會儲存在系統中,並不會直接被刪除掉,如果確定不會再使用到這個容器,就可以透過rm將其移除
<br />
```shell=
docker rm mc-server
```
----
### docker rm
Before:

After:

---
## Docker 進階指令
----
### docker images
用來檢視目前主機中有哪些映像的指令
```shell
docker images
```

----
### docker image rm
用來刪除用不到的映象的指令
```shell=
docker image rm <repository>
# or
docker image rm <image id>
```
可以透過指定 ==Repository== 或是 ==Image ID== 進行移除
----
### docker pull
用來取得新映像的指令,在使用run時,會出現相同的效果,run會先拖回來,再啟動映像
```shell=
docker pull <repository>
# Example: 用來取得最新版本的PostgreSQL
docker pull postgres:latest
```
----
### docker build
用於建立自定義映像的指令,需要提供放著Dockerfile的資料夾路徑,通常會與『-t』一起使用,幫映像加上Tag
```shell=
# Example: 建立當下資料夾中的映象,並標記為test
docker build . -t test
```
---
## Docker Compose
----
### 什麼是Compose?
Compose的存在,是為了解決多個映像檔要一起工作時的設定問題,如果所有的操作都得透過指令完成的畫,勢必會讓使用上有諸多不便,而Compose正是為了解決這個問題而出現的工具!

----
### Compose可以處理哪些東西?
絕大多數,除了涉及儲存驅動的部分之外,Docker可以提供的功能,都可以透過Compose來使用,通常會在Compose中處理以下的幾個項目:
- 啟動多少個容器
- 容器哪些埠要映射到主機
- 容器網路
- 容器儲存
- 容器環境變數
----
### Compose 範例
```yaml=
version: '3'
services:
web:
image: nginx:latest
restart: always
ports:
- 127.0.0.1:80:80
depends_on:
- db
db:
image: postgres:latest
restart: always
ports:
- 127.0.0.1:5432:5432
```
----
### 欄位說明
| Fields | Description |
| ----------- | ------------------- |
| image | 使用哪個映像 |
| build | 透過Compose建立映像 |
| restart | 重啟時的政策 |
| ports | 要映射的埠口 |
| environment | 容器內的環境變數 |
| depends_on | 依賴於哪個容器 |
----
### 補充
> 其他欄位的說明,可以參考[官方文件](https://docs.docker.com/compose/),文件本身根據需要已切分成不同部分,可按需閱讀!
----
### Compose指令
所有指令都以『docker compose』作為起頭
| Command | Description |
| ------- | -------------------- |
| up | 啟動容器,開始運作 |
| down | 停止並刪除容器 |
| stop | 停止容器 |
| build | 建立容器所需要的映像 |
| logs | 檢視容器的紀錄檔 |
---
## Dockerfile
----
### 什麼是Dockerfile?
Dockerfile是用於建立自己映像的描述檔,在描述檔中,會指定基底映像,並加上自己所需要的內容,透過這個過程,就可以打造出符合需要的『應用程式映像』
----
### 範例
```dockerfile=
FROM ubuntu:22.04
RUN apt install nodejs python3
WORKDIR /app
COPY . .
CMD ["node", "main.js"]
```
----
### 欄位說明
| Fields | Description |
| ------- | ------------------------------ |
| FROM | 讓此映像建立在另一個映像上 |
| WORKDIR | 容器內的預設工作目錄 |
| COPY | 將目錄內的檔案複製到映像中 |
| RUN | 在映像中執行指令 |
| EXPOSE | 開一個預設的"門"讓外側得以檢視可用的通訊埠 |
| CMD | 在映像啟動後執行的指令(程式) |
----
### 使用Dockerfile
可以透過純指令或Compose進行建立
```shell=
docker build . -t <tag name>
# or
docker compose build <service name>
```
---
## 透過Docker建立WordPress
----
### Compose File
```yaml=
version: '3'
services:
wp:
image: wordpress
restart: always
ports:
- 8080:80
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wp
WORDPRESS_DB_PASSWORD: wppass
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress:/var/www/html
db:
image: mysql:latest
restart: always
environment:
MYSQL_USER: wp
MYSQL_PASSWORD: wppass
MYSQL_DATABASE: wordpress
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- db:/var/lib/mysql
volumes:
wordpress:
db:
```
----
### 啟動並開始初始設定
當我們將設定檔儲存好後,就可以來啟動容器了,請輸入:
```shell=
docker compose up -d
```
<br />
這時,Engine會自動開始進行映像的抓取,並在完成後,啟動你指定的容器,如果順利的話
----
### 啟動並開始初始設定
你應該就會看到初始設定的網頁了!

----
### 嘗試完成後
請記得要將容器關閉喔,否則,你的WSL應該會持續一直運作下去,占用電腦的資源,可以輸入:
```shell=
docker compose stop
# or
docker compose down
```
<br />
因為有使用Volume儲存資料,因此兩個指令都可以~
---
## Docker 進階功能
----
### Docker Network
> [筆記在此](/@ji03mmy18/r1tQWCXx2#/)
----
### Docker Volume
> [官方文件](https://docs.docker.com/storage/volumes/)
---
## 問題與討論
----
### 有任何問題嗎?
----
### 回家作業
> TBD
----
### 學習資源
- [《Docker -- 從入門到實踐》](https://philipzheng.gitbook.io/docker_practice/introduction/what)
- [Docker Docs](https://docs.docker.com/)
---
# 下次見!

{"title":"Docker課程","slideOptions":"{\"transition\":\"concave\",\"allottedMinutes\":100}","contributors":"[{\"id\":\"f8142aa2-66aa-4867-821d-2f1ffff7a7ba\",\"add\":8146,\"del\":15}]","description":"YoMin Su"}