National Taiwan University
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try a Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

1

Local AI

--

Uedu Code

--

台灣大學 AQI 70 24°C PM2.5 17
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 05

挑一個映像檔來用

Ubuntu、Python、Jupyter 與 MySQL 映像檔
Interaction導覽 20 minute(s)

Learning Objectives

  • 比較 Debian、Ubuntu、Fedora、openSUSE、Alpine 等基底映像檔的定位,挑選合適的作業系統映像檔
  • 用 python 映像檔執行一行程式、進入 Python 互動環境,並用 --rm 讓容器用完自動刪除
  • 用 -p 對應埠號啟動 Jupyter Notebook,從 logs 取得登入用的 token
  • 用 -e 設定環境變數啟動 MySQL;容器啟動後馬上結束時,會用 ls -a 與 logs 找出原因

不用安裝,直接拿來用

上一課學會從 Docker Hub 搜尋與下載映像檔。這一課實際挑幾個常用的官方映像檔來用:

  • 想試試另一套 Linux?跑一個那套系統的容器就好,不用重灌電腦
  • 想用 Python 3.12,但電腦裝的是別的版本?用 python:3.12 容器
  • 想要 Jupyter Notebook 或 MySQL?一行指令就啟動,用完刪掉也不會在電腦留下一堆設定

挑映像檔的基本步驟:

  1. 先找官方映像檔(只有倉庫名稱的那種)
  2. 到 Docker Hub 網頁看說明:有哪些標籤、要設定哪些環境變數、資料放在哪裡
  3. 選一個明確的版本標籤,不要只用 latest

作業系統映像檔怎麼挑

投影片示範了好幾套 Linux 發行版的映像檔。它們的用法幾乎一樣(docker container run -it … /bin/bash), 差別在於定位與套件管理工具:

映像檔 背景與定位 套件管理 適合
debian 社群維護、穩定保守;很多官方映像檔(例如 python)預設就建立在 Debian 上 apt 一般用途的穩定基底
ubuntu 以 Debian 為基礎;每年 4 月與 10 月各發行一版,每兩年 4 月推出 LTS 長期支援版(如 24.04) apt 初學者首選,教學與網路資源最多
fedora Red Hat 贊助的社群發行版,盡早採用新技術;每個版本支援期較短,大約一年多;Red Hat Enterprise Linux(RHEL)以它為開發基礎 dnf 想試新版工具
opensuse/leap SUSE 主導的社群發行版;Leap 是穩定版,另有持續更新的 Tumbleweed zypper 熟悉 SUSE 環境的人
alpine 非常小(大約只有幾 MB),使用 musl libc 與 BusyBox apk 追求小體積;但有些需要編譯的套件會比較麻煩

CentOS 呢? 投影片用的 CentOS Linux 已經停止維護,不再有安全更新,本課程改用 Ubuntu 示範。 如果工作上需要與 RHEL 相容的環境,可以查看 Rocky Linux、AlmaLinux 等發行版的官方說明。

進到任何一個作業系統容器之後,可以用這些指令探索環境:

指令 看什麼
cat /etc/os-release 發行版名稱與版本
hostname、cat /etc/hosts 主機名稱(預設是容器 ID 的前 12 碼)與 IP 對照
uname -r 核心版本:你會發現是主機的核心,因為容器共用主機核心(第 01 課)
nproc、free -h、df -h / CPU 數、記憶體、磁碟空間
ps -elf 執行中的程序:通常只有你的 bash,容器不是一整台開機的電腦

裝軟體時依發行版使用不同的工具,例如 Ubuntu 要先 apt update 再 apt install -y 套件, Fedora 用 dnf install、openSUSE 用 zypper install、Alpine 用 apk add。 在容器裡裝的軟體只存在這個容器,刪掉容器就沒了;要固定下來,第 07 課會教你寫成 Dockerfile。

用 Python 映像檔

官方的 python 映像檔已經裝好 Python 與 pip,有三種常見用法:

1. 執行一行程式,跑完就刪掉容器

docker container run --rm python:3.12 python -c "print(6*7)"

--rm 表示容器結束後自動刪除,適合這種跑一次就好的工作,不會在 ls -a 留下一堆停止的容器。

2. 進入 Python 互動環境

docker container run -it --rm python:3.12

python 映像檔預設執行的程式就是 python3,所以加上 -it 會直接出現 >>> 提示字元,輸入 exit() 離開。

3. 進入 bash,再執行自己的程式

docker container run -it --name python3_env python:3.12 /bin/bash
docker container cp hello.py python3_env:/root/     # 在主機上執行:把檔案複製進容器

docker container cp 可以在主機與容器之間複製檔案(容器停止時也可以)。

標籤的變化:同一個版本通常有幾種基底可選,例如 python:3.12(Debian,最完整)、 python:3.12-slim(精簡版 Debian,比較小)、python:3.12-alpine(Alpine,最小)。不確定時先用沒有後綴的版本。

其他程式語言也有對應的官方映像檔,例如 node、golang;Java 可以用 eclipse-temurin (舊投影片的 openjdk 映像檔已經停止更新)。

互動練習:Python、Jupyter 與 MySQL

依右下角的任務操作:先用 python:3.12 加上 --rm 執行一行 Python,注意執行完容器就被刪掉;再用 -p 8888:8888 啟動 Jupyter Notebook;接著故意不給密碼啟動 MySQL(db):它看起來啟動了,請用 docker container ls -a 看它的狀態,再用 docker container logs db 找出它為什麼結束;最後移除失敗的 db,改用 -e MYSQL_ROOT_PASSWORD=… 重新啟動,再用 ls 確認它在執行。

服務式容器:Jupyter Notebook

Jupyter 是一個網頁介面的服務:容器在背景執行,你用瀏覽器連進去。

docker container run -d --name notebook -p 8888:8888 quay.io/jupyter/base-notebook
部分 意思
-d 在背景執行(服務式容器,第 03 課)
-p 8888:8888 把主機的 8888 埠對應到容器的 8888 埠;寫法是 主機埠:容器埠(第 09 課會詳細說明)
quay.io/jupyter/base-notebook Jupyter 官方團隊維護的映像檔,放在 Quay registry

舊投影片用的 jupyter/datascience-notebook 是 Docker Hub 上的名稱;Jupyter 團隊已改在 quay.io/jupyter/… 發布新版, Docker Hub 上的 jupyter/… 不再更新。除了 base-notebook,還有 scipy-notebook、datascience-notebook、pyspark-notebook 等不同套件組合。

登入要 token:Jupyter 啟動時會產生一組 token,寫在容器的輸出裡。用 docker container logs notebook 找到 http://127.0.0.1:8888/lab?token=… 這一行,整串貼到瀏覽器就能進去。

  • 主機的 8888 已經被別的程式占用時,改成 -p 9999:8888,瀏覽器改開 http://127.0.0.1:9999
  • 不加 -d 在前景執行時,按 Ctrl+C 會結束 Jupyter,容器也跟著停止
  • 之後可以 docker container stop notebook、docker container start notebook;重新啟動後,用 logs 再查一次網址
  • 在容器裡存的筆記本,刪掉容器就不見了;第 06 課會教你把資料存到容器外面

環境變數:MySQL 為什麼一啟動就結束

很多映像檔需要你在啟動時提供設定,方法是用 -e 傳入環境變數:

docker container run -d --name db mysql:8.4                                   # 沒給密碼
docker container run -d --name db -e MYSQL_ROOT_PASSWORD=你的密碼 mysql:8.4      # 正確

第一行會印出容器 ID,看起來成功了,但 docker container ls 找不到它。這時的除錯步驟:

  1. docker container ls -a:STATUS 是 Exited (1),結束碼不是 0,代表程式出錯結束
  2. docker container logs db:看容器最後說了什麼
[ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
    You need to specify one of the following as an environment variable:
    - MYSQL_ROOT_PASSWORD
    - MYSQL_ALLOW_EMPTY_PASSWORD
    - MYSQL_RANDOM_ROOT_PASSWORD

錯誤訊息直接告訴你缺什麼。先 docker container rm db 移除失敗的容器(名稱必須唯一),再加上 -e 重新啟動。

容器啟動後馬上結束,第一件事就是看 logs。 這個習慣對所有服務式容器都適用。

MySQL 映像檔常用的環境變數(完整清單在 Docker Hub 的 mysql 頁面):

環境變數 作用
MYSQL_ROOT_PASSWORD 設定 root 密碼(三選一的必填)
MYSQL_RANDOM_ROOT_PASSWORD 隨機產生 root 密碼,印在 logs 裡
MYSQL_DATABASE 啟動時順便建立一個資料庫
MYSQL_USER、MYSQL_PASSWORD 建立一個一般使用者

資料庫啟動後,可以在容器裡直接開 mysql 用戶端連線:

docker container exec -it db mysql -uroot -p

MariaDB 是從 MySQL 分支出來、協定相容的資料庫,用法幾乎相同:docker container run -d --name mariadb_server -e MARIADB_ROOT_PASSWORD=你的密碼 mariadb。

密碼寫在指令裡,會留在終端機的歷史紀錄,在 docker container inspect 裡也看得到。練習可以這樣做; 正式服務請改用設定檔或專門保管密碼的機制,而且不要用 root、123456 這種密碼。

在真的終端機跑 Python 與 Jupyter

在已經安裝 Docker 的電腦(第 02 課)打開終端機跟著做。第一次執行時會先下載映像檔,需要等一下。版本號碼與容器 ID 是示意,你看到的會不同。導覽中 root@…:/# 與 >>> 開頭的行是在容器裡輸入的。

  1. 1

    用 python:3.12 執行一行程式

    platform.system() 印出 Linux:即使你的電腦是 Windows 或 macOS,容器裡也是 Linux。加了 --rm,所以接著用 ls -a 找不到這個容器。

  2. 2

    進入 Python 互動環境

    加上 -it、不指定要執行的程式,就會進入映像檔預設的 python3。輸入 exit() 離開,容器結束並自動刪除。

  3. 3

    進入 bash,把自己的程式複製進去執行

    先在主機的目前資料夾建立 hello.py,內容是 print("Hello from a container!")。建立名為 python3_env 的容器並進入 bash 看看環境,離開後用 docker container cp 把檔案複製進去,再用 start -ai 重新啟動並接回 bash 執行它。uname -r 顯示的是主機的核心版本。

  4. 4

    在背景啟動 Jupyter Notebook

    映像檔比較大,第一次下載要等一陣子。-d 只會印出容器 ID,接著用 ls 確認它在執行,PORTS 欄位會顯示埠號對應。

  5. 5

    從 logs 找到含 token 的網址

    把 http://127.0.0.1:8888/lab?token=… 整串複製到瀏覽器,就會進入 JupyterLab。token 每次啟動可能不同,忘記時再查一次 logs 就好。

  6. 6

    停止與清理

    用完先 stop;之後還要用就 start,不需要了就 rm。python3_env 也一起移除。注意:移除 notebook 容器後,存在容器裡的筆記本也會一起消失(第 06 課會解決這個問題)。

這段導覽完成了

想一想:挑映像檔與 Python 映像檔

1.

只想用 Python 3.12 跑一次 print(6*7),又不想留下停止的容器,應該怎麼寫?

2.

在 ubuntu:24.04 容器裡執行 uname -r,顯示的是誰的核心版本?

3.

投影片用 CentOS 示範,本課程改用 Ubuntu 的原因是?

第 1 次作答

想一想:服務式容器的除錯

1.

docker container run -d --name db mysql:8.4 印出了容器 ID,但 docker container ls 看不到 db。下一步最好做什麼?

2.

啟動 Jupyter 時寫 -p 9999:8888,瀏覽器要開哪個網址?

3.

-e MYSQL_ROOT_PASSWORD=… 的 -e 是做什麼用的?

第 1 次作答

重點精華回顧

  • 挑映像檔:先找官方映像檔,看 Docker Hub 頁面的標籤與環境變數說明,選明確的版本標籤。
  • 作業系統映像檔:Debian 穩定、Ubuntu 初學首選(LTS)、Fedora 新技術、openSUSE(zypper)、Alpine 最小;CentOS Linux 已停止維護。
  • 容器裡的 uname -r 是主機的核心;容器裡裝的軟體刪掉容器就沒了。
  • --rm 讓一次性的容器用完自動刪除;python:3.12 加 -it 進入 Python 互動環境;docker container cp 在主機與容器間複製檔案。
  • Jupyter 用 -d -p 8888:8888 在背景啟動,token 從 docker container logs 取得;埠號衝突就換主機埠。
  • MySQL 要用 -e MYSQL_ROOT_PASSWORD=… 設定密碼;容器一啟動就結束時,先 ls -a 看狀態、再看 logs。
這一課完成了!
Next lesson:管理容器的資料
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。