【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-V和WSL2,來建立一個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?
小朋友齊打交?
- 先下載安裝檔…
- 一台機器裝一個,使用網路連線,但是就需要三台主機…
- 同一台機器裝三次,開三個帳號給三個人用,只需一台機器…
- 一台機器裝一個,是類似虛擬機器(VM - Virtual Machine)的做法…
- 同一台機器裝三次,就類似Docker的做法,省機器…
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
- 再來下載ARM64版的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
- 最後開啟http://localhost:8085,就可以看到WordPress的畫面了…
卷宗 - Volume
- 如果我們要在Apache Container裡面加入檔案要怎麼做呢?
- 直接連線在裡面改…雖然是可以,但是萬一Container被刪了,Code也就白寫了…
- 利用外部的檔案,讓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
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
pip install runlike
runlike <容器名稱> -p
- 而且還有一個叫Whaler的工具,可以逆向導出成Dockerfile…
alias whaler="docker run -t --rm -v /var/run/docker.sock:/var/run/docker.sock:ro pegleg/whaler"
whaler -sV=1.36 nginx:latest