【Docker容器】大家一起來當鯨魚搬運工吧…

Docker是一個開放原始碼的開放平臺軟體,它基於Google公司推出的Go語言實作。專案後來加入了 Linux 基金會,遵從了Apache 2.0協議。 Docker容器與虛擬機器類似,但二者在原理上不同。容器是將作業系統層虛擬化,虛擬機器則是虛擬化硬體,因此容器更具有可攜式性、更能高效地利用伺服器,其利用Linux核心中的資源分離機制,例如cgroups,以及Linux核心命名空間,來建立獨立的容器。 這邊主要還是以macOS做介紹,使用OrbStack來進行處理,個人是覺得它的介面比Docker Desktop好用得多,所以還是選擇它了,但在這裡還是會簡單的介紹一下各系統安裝Docker的過程…

作業環境

項目 版本
macOS Sonoma 14.7.1
Windows 11 Home 24H2
elementary OS 8.0 Circe
Docker Desktop 4.37.2
OrbStack 1.9.5

安裝Docker環境

macOS

  • 從官網下載安裝Docker Desktop這個GUI管理介面,也可以使用homebrew安裝…
  • 或者使用OrbStack也是可以的,這裡會以它來做說明…
  • 該APP安裝完成後,docker命令也會一起安裝上去…
brew install --cask docker
brew install --cask orbstack

  • Docker容器的管理介面是可以切換的…
docker context use orbstack       # Switch to OrbStack
docker context use desktop-linux  # Switch to Docker Desktop

Windows

  • 這邊主要是利用Windows內建的Hyper-VWSL2,來建立一個Linux的虛擬機…
  • 所以需要開啟CPU的虛擬化支援,在Intel CPU的叫VT-x (Intel Virtualization Technology),AMD CPU的叫AMD-V (AMD Virtualization)
  • 可以在Windows的工作管理員上,或者在官網上查看一下…
  • 然後安裝一些虛擬化有關的功能選項…
  • 再來更新一下WSL2的版本,當然要更細部的設定也是可以的…
  • 最後安裝DockerDesktop就完成了…

Linux

  • 這裡使用基於Ubuntu 24.04的elementary OS,只是正好拿來測試一下而已…
  • 我們知道,基本上Docker就是一個跑在Linux環境的軟體,所以不一定要使用實機,所以在模擬器上也沒有什麼問題…
  • 但是,要安裝Docker Desktop的時候,還是要安裝其它的東西…
  • 基本上就照官網上的安裝步驟一步步來就可以了…
  • 安裝官網上的證書 => 指定下載的版本 => 安裝Docker
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu noble stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

OrbStack

  • 這裡要特別介紹一下它,東西的好壞是比較出來的嘛,速度快又省電…
  • 首先是它的Log畫面是獨立出來的,非常的方便移動…
  • 再來是它的Debug / Terminal功能,是使用原本系統的,所以就可以加上字體 / 顏色 / 套件等,十分帶勁
  • 最後就是最重要的,它可以「直接」開啟容器的資料夾,再也不需要用使用指令把檔案貼來貼去了…

為什麼要用Docker?

小朋友齊打交?

  • 相信在以前單機遊戲的時代,一定有聽過小朋友齊打交吧?
  • 如果要同時三人同時連線玩的話,大家會怎麼做呢?
  1. 先下載安裝檔…
  2. 一台機器裝一個,使用網路連線,但是就需要三台主機…
  3. 同一台機器裝三次,開三個帳號給三個人用,只需一台機器…

Docker vs VM

  • 其實VM跟Docker的區別也是很類似的…
  • VM就是一台虛擬機器就一個nginx;而Docker是同一台機器上裝三個nginx…
  • 所以在Docker上是比較好管理的,要加強機器也比較方便,而且也比較省錢,不用同一個裝置要買三份…
  • 而下載的安裝檔,就叫「image - 映像檔」;安裝在Docker上的,就叫「container - 容器」…
  • 當然,Docker也有它的壞處,就是萬一機器當了,上面的全部Container也就不能動了…

啟動 / 關閉Docker

  • 在macOS中,就是把「Docker Desktop」或「OrbStack」打開 / 關閉就可以了…

Docker指令

  • 查看docker版本
docker --version
docker version

建立Apache HTTP伺服器

  • 我們來建立一個Apache的環境,它的Image名稱就叫「httpd」
  • 這個run指令呢,其實結合了「pull - 下載Image檔」/「create - 建立容器」「start - 啟動容器」,三個願望,一次滿足…
  • 在GUI上就可以很清楚的看到Image跟容器都處理完成了,上面操作很直覺化,這裡就不多做說明了…
  • 最後開啟http://localhost:8080/,看看Apache是否正常啟動…
docker
	container					## 對容器設定 (可省略)
    <command>					## 指令
    --name <name>				## 容器名稱
    -d						    ## 在背景設定
    -p <實機的Port>:<容器的Port>  ## Port的映射
    <image>					    ## 要安裝的Image名稱
docker container run --name ApacheDemo -d -p 8080:80 httpd
http://localhost:8080/

刪除容器

  • 這邊我們用指令來處理停止 / 刪除容器的動作,功能試一下就知道了,就不多做說明…
  • 當然Image是不會被刪掉的,下載了就一直用嘛…
docker ps
docker rm ApacheDemo		## 可以用名字 / ID
docker stop ApacheDemo
docker ps -a
docker rm ApacheDemo
docker ps
docker image ls

安裝MySQL

  • 這裡我們再試試MySQL v8.0
  • 啟動完成後,可以從OrbStack試試可不可以連線,真的是太好用了啊…
docker run
	--name MySQL_Demo
    -dit							  ## 背景執行 / 互動模式 / 配置TTY終端機
    -e MYSQL_ROOT_PASSWORD=3939889	  ## 設定Root密碼
    mysql:8.0						  ## 使用MySQL 8.0
docker run --name MySQL_Demo -dit -e MYSQL_ROOT_PASSWORD=3939889 mysql:8.0
docker ps -a
mysql -uroot -p3939889

  • 然後再把它刪除掉…

docker ps -a
docker stop <Conatainer Id>
docker stop ApacheDemo
docker ps
docker ps -a
docker rm <Conatainer Id>
docker ps -a

移除已下載的映像檔

  • 指令很直覺…

docker ps -a
docker image ls			      ## 查看已下載的Image檔
docker image rm httpd		  ## 移除該Image
docker image ls
docker image rm mysql:8.0	  ## 移除特定版本的Image
docker image ls

WordPress + MySQL

docker network ls          ## 查看網路資訊
docker create <網路名稱>    ## 建立網路
docker rm <網路名稱>        ## 刪除網路
docker pull <映像檔名稱>    ## 下載映像檔
docker run
	--net=<使用的網路名稱>
	--name <容器名稱>
		-dit
		-e MYSQL_ROOT_PASSWORD=<Root密碼>
		-e MYSQL_USER=<使用者名稱>
		-e MYSQL_PASSWORD=<使用者密碼>
		-e MYSQL_DATABASE=<資料庫名稱>
	arm64v8/mysql
		--character-set-server=<字元編碼>
		--collation-server=<字符對照表>
  • 這裡我們來實際做看看,首先來建立共用的網路…

docker network ls
docker network create wordpress_mysql
docker pull arm64v8/mysql
docker image ls

  • 生成MySQL容器,可以看到它不會再去下載Image了,速度快很多,也可以在OrbStack順道試一下啟動正不正常…

docker run --net=wordpress_mysql --name MySql_Database -dit -e MYSQL_ROOT_PASSWORD=3939889 -e MYSQL_USER=william -e MYSQL_PASSWORD=28825252 -e MYSQL_DATABASE=WordPress_Demo arm64v8/mysql --character-set-server=utf8mb4 --collation-server=utf8mb4_0900_ai_ci
  • 再來就是建立WordPress容器,比較要注意的是,接下來要填的都是上一步設定的值…
docker run
	--net=<使用的網路名稱>
	--name <容器名稱>
		-dit
		-p <實機對應的埠>:80
		-e WORDPRESS_DB_HOST=<SQL容器名稱>
		-e WORDPRESS_DB_NAME=<已建立的資料庫名稱>
		-e WORDPRESS_DB_USER=<MySQL使用者名稱>
		-e WORDPRESS_DB_PASSWORD=<MySQL使用者密碼>
	wordpress

docker run --net=wordpress_mysql --name Wordpress_demo -dit -p 8085:80 -e WORDPRESS_DB_HOST=MySql_Database -e WORDPRESS_DB_NAME=WordPress_Demo -e WORDPRESS_DB_USER=william -e WORDPRESS_DB_PASSWORD=28825252 wordpress

卷宗 - Volume

  • 如果我們要在Apache Container裡面加入檔案要怎麼做呢?
  1. 直接連線在裡面改…雖然是可以,但是萬一Container被刪了,Code也就白寫了…
  2. 利用外部的檔案,讓Apache Container來讀取,這樣就算Container被刪,Code也還在…
  • 這個讓外部檔案被Container讀取,就是Volume最重要的功能之一…
  • 我們把在容器內的「/usr/local/apache2/htdocs/index.html」換成在外部的「./html/index.html」…
  • 然後開啟http://localhost:8080/,就會發現內容改變了…

docker run
    --name ApacheHtml
        -d
        -p 8080:80
        -v <外部資料夾>:<容器內資料夾>
    httpd
docker run --name ApacheHtml -d -p 8080:80 -v ./html:/usr/local/apache2/htdocs httpd
  • 我們來試試卷宗的建立 / 刪除…

docker volume ls					 ## 卷宗列表
docker volume create <內部卷宗名稱>	 ## 建立卷宗
docker volume inspect <卷宗名稱>		 ## 卷宗細節
docker volume rm <卷宗名稱>			 ## 移除卷宗
docker volume ls
docker volume create demo_folder
docker volume ls
docker volume inspect demo_folder
docker volume rm demo_folder
docker volume ls
  • 把卷宗跟容器連在一起,然後看看是不是真的連上了…
docker volume create html_folder
docker run --name ApacheHtml -d -p 8080:80 -v html_folder:/usr/local/apache2/htdocs httpd
docker container inspect ApacheHtml

做一個專屬自己的Image - Commit

  • 如何將好不容易設定好的容器備份呢?或者是上傳給其它人使用呢?
  • 其實是可以的,這裡我們說說備份的方法,或者應該說…產生一個新的Image檔…
  • 甚至還可以壓縮備份起來帶著走,相當的強大啊…

docker commit
	-a <作者名稱>                       ## 作者名稱 (選填)
	-m <相關訊息>                       ## 相關訊息 (選填)
	--pause=false                      ## 暫停容器 (選填)
	<已存在的容器名稱> <要備份的容器名稱>

docker save
	-o <壓縮檔名稱>.tar <已存在的映像檔>  ## 將映像檔壓縮

docker load 
	-i <壓縮檔名稱>.tar                 ## 使用壓縮的映像檔
docker ps -a
docker image ls
docker commit -a "William" -m "就是這樣…" --pause=false ApacheHtml william_apache
docker save -o WilliamApache.tar william_apache
ls
docker image ls
docker image rm william_apache
docker image ls
docker load -i WilliamApache.tar
docker image ls
  • 另外還可以使用Dockerfile來產生Image
# Dockerfile
FROM <映像檔>
COPY <本機位置> <要映射的位置>
RUN <執行命令>
docker build
	-t="新的Image命名"
	<Dockerfile設定檔的位置>
FROM httpd
COPY html /usr/local/apache2/htdocs/
RUN apt-get update
RUN apt-get install zip -y
ls
docker build -t="new_httpd" .
docker image ls

一次安裝完成 - Docker Compose

  • 有沒有可以一次設定多個Container的方法呢?
  • 當然是有的,使用Docker Compose這個套件功能,將設定檔寫成yml格式就可以讀取執行了…
  • 這裡我們就用時下最流行的Ollama,在本機跑LLM語言模型吧…
  • 這個一次安裝Ollama (主體) + open-webui (UI介面)
  • 這裡的細節就不多說了,其實就是把上面說的指令設定檔化…
  • 開啟http://localhost:8787,就可以進入UI界面了,當然LLM模型要自己下載…
services:
  ollama:
    image: ollama/ollama:latest
    ports:
      - 11434:11434
    volumes:
      - ../ollama/code:/code
      - ../ollama/ollama:/root/.ollama
    container_name: ollama
    pull_policy: always
    tty: true
    restart: always
    networks:
      - ollama-docker

  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    volumes:
      - ../ollama/open-webui:/app/backend/data
    depends_on:
      - ollama
    ports:
      - 8787:8080
    environment:
      - '/ollama/api=http://ollama:11434/api'
    extra_hosts:
      - host.docker.internal:host-gateway
    restart: unless-stopped
    networks:
      - ollama-docker

networks:
  ollama-docker:
    external: false
docker-compose
	-f <YAML設定檔>		## 指定設定檔位置 (可選 / 預設為docker-compose.yml)
	up					## 執行
    -d					## 背景執行
docker-compose -f docker-compose.yml up -d

  • 另外,還可以安裝runlike,一鍵把運行中的容器逆向成可部署的CLI命令列工具…
pip install runlike
runlike <容器名稱> -p

alias whaler="docker run -t --rm -v /var/run/docker.sock:/var/run/docker.sock:ro pegleg/whaler"
whaler -sV=1.36 nginx:latest

後記

  • 趕在這週的尾端終於完成了,好累啊…
  • 最近真的感到同酬不同工的哀怨,與說得一口好程式的同事,人善被犬欺啊,不被尊重太久了,在求學過程上的優點,在職場上全是缺點,還是來黑化一下好了?
  • 最近很熱門的Deepseek裝在M1上使用,真的是超慢的啊…
  • 期待新的iPhone SE4,沒錢人的我心之詩句…
  • 家裡也真的是亂七八糟的,有責任感不是件好事,心太軟,心太軟…