Docker 容器化技術簡化了應用程式佈署,本文將引導讀者完成 Docker 的安裝與設定,並探討如何在不同作業系統上進行操作,包含移除舊版本、設定儲存函式庫等關鍵步驟。同時,文章也將介紹 Docker 的基本網路設定,讓讀者瞭解如何發布埠口和掛載磁碟區,並以 Python 的 SimpleHTTPServer 作為實際案例。最後,本文將探討互動式程式設計的優勢,以 Jupyter 為例,展示其如何提升開發效率,並與傳統的非互動式程式設計方法進行比較,例如 C 語言的編譯和執行流程。

Docker 安裝與設定

Docker 是一種流行的容器化技術,允許開發者將應用程式及其依賴項封裝成一個可移植的容器。在本章中,我們將介紹如何在不同的作業系統上安裝和設定 Docker。

移除舊版本的 Docker

在安裝 Docker 之前,請確保您的系統上沒有安裝舊版本的 Docker。您可以使用以下命令來移除舊版本的 Docker:

$ sudo apt remove docker
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package 'docker' is not installed, so not removed
0 upgraded, 0 newly installed, 0 to remove and 43 not upgraded.

內容解密:

此命令用於移除系統上已安裝的 Docker 軟體包。如果系統上沒有安裝 Docker,將會顯示「Package ‘docker’ is not installed, so not removed」的訊息。

設定 Docker 儲存函式庫

要安裝 Docker,建議從 Docker 官方儲存函式庫進行安裝。首先,您需要設定儲存函式庫以允許使用 HTTPS。

$ sudo apt-get install \
> apt-transport-https \
> ca-certificates \
> curl \
> software-properties-common
Reading package lists... Done
Building dependency tree
Reading state information... Done
ca-certificates is already the newest version (20160104ubuntu1).
apt-transport-https is already the newest version (1.2.19).
curl is already the newest version (7.47.0-1ubuntu2.2).
software-properties-common is already the newest version (0.96.20.5).
0 upgraded, 0 newly installed, 0 to remove and 43 not upgraded.

內容解密:

此命令安裝必要的軟體包,以允許 apt 使用 HTTPS 儲存函式庫。這些軟體包包括 apt-transport-httpsca-certificatescurlsoftware-properties-common

接下來,您需要新增 Docker 的官方 GPG 金鑰,以驗證軟體包的真實性。

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
OK
$ sudo apt-key fingerprint 0EBFCD88
pub 4096R/0EBFCD88 2017-02-22
Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid Docker Release (CE deb) <docker@docker.com>
sub 4096R/F273FCD8 2017-02-22

內容解密:

第一條命令下載 Docker 的 GPG 金鑰並將其新增到系統中。第二條命令驗證金鑰的指紋,確保其真實性。

最後,您需要新增 Docker 儲存函式庫到系統中。

$ sudo add-apt-repository \
> "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu \
> $(lsb_release -cs) \
> stable"

內容解密:

此命令根據系統架構和版本,新增相應的 Docker 儲存函式庫。

從 Docker 儲存函式庫安裝

設定好儲存函式庫後,您可以使用以下命令來安裝 Docker:

$ sudo apt update
...
Get:6 https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages [1,479 B]
...
43 packages can be upgraded. Run 'apt list --upgradable' to see them.
$ sudo apt install -y docker-ce
Reading package lists... Done
...
Preparing to unpack .../docker-ce_17.03.1~ce-0~ubuntu-xenial_amd64.deb ...
Unpacking docker-ce (17.03.1~ce-0~ubuntu-xenial) ...
...
Processing triggers for ureadahead (0.100.0-19) ...

內容解密:

第一條命令更新軟體包列表,以包含新新增的 Docker 儲存函式庫。第二條命令安裝 Docker CE(Community Edition)。

以非 root 使用者管理 Docker

在 Linux 系統上,Docker daemon 繫結到 Unix socket,而不是 TCP 埠。預設情況下,該 socket 由 root 使用者擁有,因此您需要使用 sudo 命令來執行 Docker 命令。為了避免使用 sudo,您可以建立一個 docker 群組,並將使用者新增到該群組中。

$ sudo groupadd docker
$ sudo usermod -aG docker $USER

內容解密:

第一條命令建立一個名為 docker 的群組。第二條命令將目前的使用者新增到 docker 群組中。

登出並重新登入後,您就可以在不使用 sudo 的情況下執行 Docker 命令。

在 Mac 和 Windows 上安裝 Docker

Docker 也提供了針對 Mac 和 Windows 的版本。Docker for Mac 使用 HyperKit 虛擬機器,而 Docker for Windows 使用 Microsoft Hyper-V。您可以從 Docker 官方網站下載並安裝相應的版本。

在 Mac 上,您可以使用以下命令來啟用 bash 自動補完:

$ ln -s /Applications/Docker.app/Contents/Resources/etc/docker.bash-completion /usr/local/etc/bash_completion.d/docker
$ ln -s /Applications/Docker.app/Contents/Resources/etc/docker-machine.bash-completion /usr/local/etc/bash_completion.d/docker-machine
$ ln -s /Applications/Docker.app/Contents/Resources/etc/docker-compose.bash-completion /usr/local/etc/bash_completion.d/docker-compose

內容解密:

這些命令將 Docker 的 bash 自動補完指令碼連結到系統的 bash_completion.d 目錄中,以啟用自動補完功能。

驗證 Docker 安裝

安裝完成後,您可以使用以下命令來驗證 Docker 是否正確安裝:

$ docker version
Client:
Version: 17.03.1-ce
API version: 1.27
Go version: go1.7.5
Git commit: c6d412e
Built: Mon Mar 27 17:14:09 2017
OS/Arch: linux/amd64
Server:
Version: 17.03.1-ce
API version: 1.27 (minimum version 1.12)
Go version: go1.7.5
Git commit: c6d412e
Built: Mon Mar 27 17:14:09 2017
OS/Arch: linux/amd64
Experimental: false

內容解密:

此命令顯示 Docker 使用者端和伺服器的版本資訊。

您也可以使用 docker help 命令來檢視 Docker 的使用說明:

$ docker help
Usage: docker COMMAND
A self-sufficient runtime for containers
...

內容解密:

此命令顯示 Docker 的使用說明和可用命令列表。

Docker基礎與應用實務

Docker 安裝與驗證

Docker 的安裝過程相對簡單,不同作業系統有不同的安裝方式。安裝完成後,首先需要驗證 Docker 使用者端是否正確安裝。可以使用以下指令來檢查 Docker 使用者端的安裝位置:

$ which docker
/usr/local/bin/docker

內容解密:

此指令用於查詢 docker 執行檔的位置。輸出結果 /usr/local/bin/docker 表示 Docker 使用者端已正確安裝在系統中。

驗證 Docker 是否正確安裝的標準方法是執行 hello-world 映像檔:

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
78445dd45222: Pull complete
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
...

內容解密:

  1. Docker 使用者端向 Docker 守護程式傳送 run hello-world 命令。
  2. Docker 守護程式檢查本地是否有 hello-world 映像檔,若無則從 Docker Hub 下載。
  3. 使用下載的映像檔建立新的容器,並執行預定的程式。
  4. 將程式的輸出結果傳回 Docker 使用者端,並顯示在終端機上。

這個過程驗證了 Docker 的安裝是正確且可用的。

執行 Ubuntu 映像檔與互動式操作

進一步驗證 Docker 功能的方式是執行 Ubuntu 映像檔並進行互動式操作:

$ docker run -it ubuntu /bin/bash
root@eb5f4278d040:/#

內容解密:

  • -it 引數允許互動式操作並分配一個偽終端。
  • ubuntu 指定要執行的映像檔。
  • /bin/bash 指定在容器內執行的命令。

進入容器後,可以執行各種命令,如 lsps,來觀察容器的運作狀態:

root@8b9461e1d7dd:/# ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr

root@8b9461e1d7dd:/# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 18240 3212 ? S<s 04:00 0:00 /bin/bash
root 13 0.0 0.1 34424 2808 ? R<+ 04:01 0:00 ps aux

內容解密:

  • ls 命令顯示了完整的 Linux 檔案系統結構。
  • ps aux 命令顯示目前容器中執行的所有程式。值得注意的是,容器內只執行了 /bin/bashps aux 兩個程式,體現了容器的輕量級特性。

Docker 基本網路設定

Docker 的網路功能使得容器可以與外部進行通訊。發布埠(port)是實作容器與主機之間網路連線的重要方式。使用 -p 引數可以將容器內的埠對應到主機上的特定埠:

$ docker run -p 7777:5000 my_flask_app

內容解密:

  • -p 7777:5000 將容器內的 5000 埠對應到主機的 7777 埠。
  • 這樣設定的結果是,主機上的 http://localhost:7777 可以存取容器內執行的 Flask 應用程式。

一個實際的例子是使用 Python 的 SimpleHTTPServer 模組來建立檔案伺服器:

$ docker run -v ~:/home -p 5000:8000 python:2.7 python -m SimpleHTTPServer

內容解密:

  • -v ~:/home 將主機的家目錄掛載到容器內的 /home 目錄。
  • -p 5000:8000 將容器內的 8000 埠對應到主機的 5000 埠。
  • python -m SimpleHTTPServer 在容器內啟動一個簡單的 HTTP 伺服器。

執行後,可以在瀏覽器中透過 http://localhost:5000 存取檔案伺服器。

在下一章中,將正式介紹 Jupyter,並使用 Docker 來佈署 Jupyter 環境。這將進一步展示 Docker 在實際應用中的靈活性和強大功能。同時,也將更深入地探討 Docker 生態系統中的各個元件,以幫助讀者全面掌握 Docker 的使用和管理。以下是本章內容的結構圖示:

  graph TD;
    A["Docker 安裝"] --> B["驗證安裝"];
    B --> C["執行 hello-world"];
    C --> D["執行 Ubuntu 映像檔"];
    D --> E["互動式操作"];
    E --> F["基本網路設定"];
    F --> G["發布埠範例"];
    G --> H["總結"];

圖表翻譯: 此圖示展示了本章節的內容結構,從 Docker 安裝開始,逐步介紹了驗證安裝、執行不同映像檔、互動式操作、基本網路設定等,最後總結並展望未來內容。圖中每個節點代表一個主要的知識點或操作步驟,箭頭表示學習的流程順序。

互動式程式設計:以 Jupyter 為中心的開發革命

互動式運算是一種人機之間的對話過程。如同 Beki Grinter 所言,這種模式徹底改變了我們與電腦互動的方式。現代人每天都在積極地與電腦進行互動,無論是向搜尋引擎發出查詢,還是使用線上地圖工具,都期望能立即得到回應。這種即時互動的體驗已經成為我們對電腦的基本期待。

互動式程式設計的新正規化

Jupyter 成為了這種互動式程式設計的核心工具。它不僅是一個網頁端的互動應用,更是一種全新的程式設計正規化。Jupyter 提供了一個強大的展示環境,讓使用者能夠以更直覺的方式進行程式開發與結果展示。可以說,Jupyter 正在改變我們撰寫程式碼的方式。

傳統的程式開發流程,例如使用 C 語言進行開發,需要經過編寫原始碼、編譯、連結、執行的多步驟過程。這個過程中,任何一個環節出現問題都可能導致整個程式無法正常執行。相較之下,Jupyter 這種互動式環境提供了即時反饋,大幅提升了開發效率。

非互動式程式設計的侷限性

以 C 語言為例,它是一種編譯型語言。開發者需要先編寫原始碼,然後透過編譯器將其轉換為二進位檔案,最後才執行這個檔案。在這個過程中,開發者需要自行處理各種依賴關係,例如標頭檔和函式庫的連結。這種開發流程相對繁瑣,需要開發者具備一定的專業知識。

建立一個最小化的計算專案

首先,我們需要建立一個專案目錄結構,以便管理不同的檔案型別。以下是一個典型的專案結構:

$ mkdir ch_3_minimal_comp ch_3_minimal_comp/bin ch_3_minimal_comp/src ch_3_minimal_comp/docker
$ tree
.
└── ch_3_minimal_comp
    ├── bin
    ├── docker
    └── src

編寫 Bessel 函式的原始碼

接下來,我們在 src 目錄下建立一個名為 bessel.c 的檔案,用於計算 Bessel 函式的值。這個程式使用了 GNU Scientific Library (GSL) 來進行科學計算。

// src/bessel.c
#include <stdio.h>
#include <gsl/gsl_sf_bessel.h>

int main(void) {
    double x = 5.0;
    double y = gsl_sf_bessel_J0(x);
    printf("J0(%g) = %.18e\n", x, y);
    return 0;
}

使用 Docker 進行編譯與執行

為了簡化編譯和執行的過程,我們使用 Docker 來建立一個乾淨且可重複的建置環境。首先,我們需要建立一個 Dockerfile,用於定義我們的建置環境。

# docker/Dockerfile
FROM gcc
LABEL maintainer=@joshuacook
RUN apt-get update && \
    apt-get install -y \
    gsl-bin \
    libgsl0-dbg \
    libgsl0-dev \
    libgsl0ldbl

接著,我們使用以下指令來建置 Docker 映像檔:

$ docker build -t gsl docker

建置完成後,我們可以使用這個映像檔來編譯我們的 Bessel 函式程式。

$ docker run \
    -v $(pwd):/home \
    gsl \
    gcc \
    -I /usr/include/ \
    -L /usr/lib/ -lgsl -lgslcblas \
    /home/src/bessel.c \
    -o /home/bin/bessel

編譯結果與執行

編譯成功後,我們可以在 bin 目錄下找到編譯好的 bessel 執行檔。這個過程展示瞭如何使用 Docker 來管理複雜的編譯依賴關係。

Jupyter 的互動優勢

相較於傳統的編譯型語言,Jupyter 提供了一個即時互動的開發環境。開發者可以直接在 Jupyter Notebook 中撰寫程式碼並立即執行,無需經過編譯和連結的過程。這種即時反饋機制大大提高了開發效率。

程式碼範例與互動執行

以下是一個簡單的 Python 程式碼範例,展示瞭如何在 Jupyter 中進行互動式運算:

import numpy as np
from scipy.special import j0

x = 5.0
y = j0(x)
print(f"J0({x}) = {y:.18e}")

內容解密:

  1. 匯入必要的函式庫:我們首先匯入了 numpyscipy.special 模組,分別用於數值計算和特殊函式的計算。

  2. 定義輸入變數:變數 x 被設定為 5.0,用於計算 Bessel 函式的值。

  3. 計算 Bessel 函式:使用 j0(x) 函式計算零階 Bessel 函式在 x=5.0 處的值。

  4. 輸出結果:使用格式化字串輸出計算結果,精確到小數點後 18 位。

  5. 互動式開發工具的普及:隨著 Jupyter 等互動式工具的持續發展,預計將有更多的開發者採用這種開發模式。

  6. 容器化技術的廣泛應用:Docker 等容器化技術將繼續簡化複雜應用的佈署和管理流程。

  7. 多語言支援的增強:未來的互動式開發環境可能會支援更多的程式語言,打破語言之間的隔閡。