Docker tutorial -1
===

**📌 本次內容:**
- Docker 是什麼
- Docker的基本指令&操作
- 實作拉取映像檔+建立容器
[Docker 安裝參考 -- Windows & Mac](https://hackmd.io/@hexschool/HyvXTHJm0)
[Docker 安裝參考 -- Windows](https://hackmd.io/@9eK2vubASmetyxZIRnd6jA/r1N_vFO8_)
---
:::info
🐳 Docker 是一個透過「容器」(container)的技術,來做到將應用程式和依賴項打包成一個輕量級、可移植的單元,確保在不同環境中運行一致。
:::
## Docker vs. Visual machine vs. Visual environment
| **特性** | **Docker** | **虛擬機器 (VM)** | **Python 虛擬環境** |
|------------------------|------------------------------------|-----------------------------------|-----------------------------------|
| **隔離層級** | 應用程式級隔離(共享宿主機 OS 核心) | 硬體級隔離(獨立 Guest OS) | 僅 Python 套件隔離 |
| **啟動速度** | 秒級(無需啟動完整 OS) | 分鐘級(需啟動 Guest OS) | 即時(僅修改環境變數) |
| **資源占用** | 低 | 高 | 極低 |
| **跨平台支援** | 需宿主機支援 Linux 核心(Win/mac 透過虛擬化間接支援) | 完全跨平台(可運行不同 Guest OS) | 僅限 Python,依賴宿主機 OS 環境 |
| **典型用途** | ✔️ 應用打包與部署<br>✔️ 微服務架構<br>✔️ 環境一致性保證 | ✔️ 運行不同 OS(如 Windows on Mac)<br>✔️ 完全獨立的系統測試 | ✔️ 管理 Python 套件版本衝突<br>✔️ 開發階段依賴隔離 |

:::info
- 🐍 **純 Python 開發** → Python 虛擬環境
- 🐳 **系統級環境隔離** → Docker
- 🖥️ **跨 OS 測試** → 虛擬機器
:::
## Docker 基本概念
- **映像檔 (Image)**
用來建立 Container 的靜態模板,裡面會設定應用程式環境等等,是一個唯獨的檔案。
- **容器 (Container)**
Container 是由 image 所建立執行的實例,可以被啟動、開始、停止、刪除。一個 image 可以創建多個 container,每個 container 都是獨立運作、不互相影響。
:::info
- 🌰 1:image 就像一個class,container 是實例化的object。
- 🌰 2:image 就像食譜,container 是依照食譜做出的菜餚。
:::
- **Dockerfile**
用來定義如何構建 image 的腳本文件, 裡面包含一系列指令。
- **倉庫 (Registry)**
用來管理 Repository 的場所。目前最大的 Public Registry 為 **Docker Hub**,有存放許多官方和社群分享的image(類似Docker版的GitHub)。

## Docker 指令
只要會以下的指令你就會了!!
- Linux 基本指令:cd, ls, rm, pwd
- git 基本指令:pull, push, commit

### 指令格式

範例:
```
$ docker image pull {image} # 拉取 image
$ docker image ls # 列出 image
$ docker container ls -a # 列出所有 container
$ docker image rm {image} # 刪除 image
$ docker container rm {container} # 刪除 container
```
### 常見指令
#### 💾 映像檔管理
| **新版指令** | **舊版指令** | **常用參數** | **說明** |
|----------------|------------------------|------------------------|----------------------------------|
| `docker image pull` | `docker pull` | | 下載映像檔 |
| `docker image ls` | `docker images` | `-a`, `-q` | 列出映像檔 |
| `docker image rm` | `docker rmi` | `-f` | 刪除映像檔 |
#### 🪣 容器管理
| **新版指令** | **舊版指令** | **常用參數** | **說明** |
|----------------|------------------------|------------------------|----------------------------------|
| `docker container run` | `docker run` | `-it`, `-d`, `-p`, `--rm`, `--name` | 啟動容器 |
| `docker container ls` | `docker ps` | `-a`, `-q` | 列出容器 |
| `docker container stop` | `docker stop` | | 停止容器 |
| `docker container rm` | `docker rm` | `-f`, `-v` | 刪除容器 |
| `docker container start` | `docker start` | | 再度啟動容器 |
| `docker container exec` | `docker exec` | `-it` | 進入運行中的容器 |
#### 🔩 參數
| 參數 | 完整寫法 | 說明 | 適用指令 |
|------|----------|------|----------|
| `-i` | `--interactive` | 保持標準輸入開啟 | run, exec |
| `-t` | `--tty` | 分配虛擬終端 | run, exec |
| `-d` | `--detach` | 後台運行容器 | run |
| `-p` | `--publish` | 端口映射 | run |
| `-v` | `--volume` | 掛載卷/目錄 | run |
| `-w` | `--workdir`|設定容器啟動後的工作目錄| run |
| `--rm` | | 容器退出後自動刪除 | run |
| `--name` | | 指定容器名稱 | run |
| `-a` | `--all` | 顯示所有容器 | ls |
| `-f` | `--filter` | 過濾條件 | ls |
| `-q` | `--quiet` | 只顯示ID | ls |
## 實際操作
***🐳 一起用python來實作~~***
1. **將python的官方image拉取下來**
- 可以用 GUI 介面 Docker Desktop 操作
- 或是在 CUI 介面打指令
```
docker image pull python:3.10-slim
```
2. **列出現有的image看看**
```
docker image ls
```
3. **使用python的image創建容器**
- 打開容器並在**容器內的shell**
```
docker container run -it python:3.10-slim bash
```

- 打開容器並在**python互動環境**
```
docker container run -it python:3.10-slim python
```
- 打開容器並命名,退出容器後自動刪除
```
docker container run -it --rm --name py_test python:3.10-slim python
```
4. **列出現有的container看看**
- 列出**正在運行**的container
```
docker container ls
```
- 列出**所有**的container
```
docker container ls -a
```
5. **再度啟動並進入已存在的container**
```
# 再度啟動
docker container start {container NAME/ID}
# 進入容器
docker container exec -it {container NAME/ID} bash
```
6. **將本機資料夾掛接進container**
#### 資料卷 (Volume)
一塊資料儲存空間,允許我們將本機的資料夾掛載到容器內。這樣可以確保本機的程式碼變更會即時反映在容器內,也可以讓不同的容器共享本機的資料夾。
先去桌面創建一個資料夾
```
cd Desktop
mkdir docker_test
```
- 使用絕對路徑
```
# -v <本機資料夾>:<容器內對應路徑>
docker run -it --rm \
-v /Users/zhangzhifen/Desktop/docker_test:/app\
-w /app \
--name py_volume\
python:3.10-slim bash
```
:::info
🐳
- 試著在/app這個資料夾內創建一個.py檔
- 使用 nano 編輯,讓這個檔案可以print出一些東東
```
# nano 安裝方法
apt-get update && apt-get install nano
```
:::
- 使用當前工作目錄(要先去到該資料夾)
```
# 直接執行.py檔
docker run -it --rm \
-v "$(pwd)":/app \
-w /app \
python:3.10-slim python test.py
```
7. **刪除所有東東**

:::info
🐳
- 停止 container
- 刪除 container
- 刪除 python image
:::
## To sum up
### Docker 適合使用的情境
1. **快速嘗試或使用新技術**
想淺淺、快速地體驗某個資料庫或工具,不用直接在本機上安裝,用 Docker 就可以快速啟動試用,隨時刪除不殘留
2. **從開發、測試到部署,確保環境一致性**
在團隊開發階段避免「我這邊可以跑,你那邊不行」的情況,各種作業系統下都能跑出一致的結果,並且不會污染本機。
部署時只要把應用打包成 image,上傳到任意雲端主機就能運行。
3. **多服務系統 / 微服務架構**
系統由多個服務組成(前端、後端、資料庫等),每個服務獨立容器,搭配 Docker compose 管理整體,更容易擴展、維護與除錯。

### Docker 的優勢
- 🔁 環境一致性:不管在哪台機器上都能保證一致的運行效果
- 🔧 快速建置與重建:一行指令就能建好完整環境,不怕壞掉
- 🚀 輕量快速啟動:相較虛擬機器 VM 更快更省資源
- 📦 易於部署:專案打包成 image 就能到處運行
- 🧩 易整合多服務:用 Docker compose 輕鬆組合多個容器
---
**⛳️ 下次內容:**
- 端口映射(Port mapping)
- 建立 Dockerfile,打包自己的image
- Docker compose
- 實作一個本地的LLM(Ollama+Open WebUI)
---
## References
1. [Docker 安裝](https://hackmd.io/@hexschool/HyvXTHJm0)
2. [Docker】小白安裝初體驗 - WIN10](https://hackmd.io/@9eK2vubASmetyxZIRnd6jA/r1N_vFO8_)
3. [docker-tutorial](https://github.com/twtrubiks/docker-tutorial)
4. [Docker 介紹與安裝](https://medium.com/ching-i/docker-%E4%BB%8B%E7%B4%B9%E8%88%87%E5%AE%89%E8%A3%9D-6ca8ea6beaf0)
5. [Docker 極速入門 -前端工程篇](https://azole.medium.com/docker-catbeer-frontend-fe0aef70b9c6)
6. [Docker Container 基礎入門篇 1](https://azole.medium.com/docker-container-%E5%9F%BA%E7%A4%8E%E5%85%A5%E9%96%80%E7%AF%87-1-3cb8876f2b14)