# Ubuntu Linux 上安裝 Docker
資料來源:https://docs.docker.com/engine/install/ubuntu/
在本文中,我們展示如何在 Ubuntu Linux 22.04(LTS) 上安裝 Docker CE。Docker CE是一個免費的開源容器化平臺,Docker使用Linux內核在作業系統之上創建容器、部署和運行應用程式。
本文假設您至少具有Linux的基本知識,知道如何使用shell。安裝非常簡單,大部分都是以 root 權限執行,若是一般使用者則需具備sudo權限,在命令中添加 'sudo'以獲得root權限。以下將展示如何在 Ubuntu Linux 上逐步安裝 Docker 容器,假設 user1 具備sudo權限。
## 1.移除系統中的舊套件
由於ubuntu原生套件庫apt中的docker並非官方發行,因此需先移除避免衝突。
```
user1# for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done
```
## 2.系統更新
```
user1# sudo apt-get update
user1# sudo apt-get install ca-certificates curl gnupg
```
## 3.安裝 Docker
. 加入docker套件來源庫
```
user1# sudo install -m 0755 -d /etc/apt/keyrings
user1# curl -fsSl https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
user1# sudo chmod a+r /etc/apt/keyrings/docker.gpg
```
. 設定docker套件庫
```
user1# echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```
. 如果使用的作業系統是ubuntu衍生出來的如Linux Mint,要把上面的$VERSION_CODENAME 改為 $UBUNTU_CODENAME。
. 安裝docker套件,其中VERSION_STRING是指定較穩定版本
```
user1# sudo apt-get update
user1# VERSION_STRING=5:25.0.5-1~ubuntu.22.04~jammy <----ubuntu 22.04LTS用的版號
user1# VERSION_STRING=5:27.4.1-1~ubuntu.24.04~noble <----ubuntu 24.04LTS用的版號
user1# sudo apt-get install docker-ce=$VERSION_STRING docker-ce-cli=$VERSION_STRING containerd.io docker-buildx-plugin docker-compose-plugin
```
安裝完後,ubuntu上會自動啟動 docker 服務。
## 簡易快速安裝 Docker
上面的程序有些複雜,Docker官方網站有提供一個ubuntu專用的快速安裝腳本程式,先下載並檢視它的動作內容:
```
user1# curl -fsSL https://get.docker.com -o get-docker.sh
user1# sudo sh ./get-docker.sh --dry-run
```
若確定要執行,則改為:
```
user1# curl -fsSL https://get.docker.com -o get-docker.sh
user1# sudo sh ./get-docker.sh
```
## 檢查 Docker
安裝後,docker服務會隨systemctl自動啟動,且以root權限執行。
檢查docker服務是否正常,可以執行一個hello-world的容器來進行測試:
```
user1# sudo docker run hello-world
```
或驗證docker是否安裝完成,若沒有錯誤訊息表示成功安裝。
```
user1# sudo docker version
```
## 使用 rootless 模式
docker一般都透過root權限執行,但以root權限執行可能會損害系統,考量到安全一般會以非root權限執行,此時需先停掉系統的docker服務:
```
root# systemctl stop docker
root# systemctl disable docker --now docker.service docker.socket
root# reboot
```
重開機後,以root權限執行以下指令,以安裝uidmap套件:
```
user1# sudo sh -eux <<EOF
apt-get install -y uidmap
EOF
```
再將要使用docker的使用者(EX:user2),啟用其個人的systemctl執行權限
```
user1# sudo loginctl enable-linger user2
```
登出後,改以一般user登入,設定環境變數XDG_RUNTIME_DIR,並加入.bashrc,再進行docker rootless自動設定:
```
user2# echo "export XDG_RUNTIME_DIR=/run/user/$UID" >> ~/.bashrc
user2# export XDG_RUNTIME_DIR=/run/user/$UID
user2# dockerd-rootless-setuptool.sh install
```
完成後會看到最後一行為
```
export DOCKER_HOST=unix:///run/user/$UID/docker.sock
```
代表設定成功,其中/run/user/$UID/docker.sock為這個user使用的sock窗口,每個使用者的執行窗口(sock)都不相同。
要注意的是,此時有設定可使用docker的使用者,在系統重開機後,都會自動啟動個人的docker服務,無論有無建立容器(container)都會佔用記憶體。
## 安裝 portainer
在管理Docker容器時,portainer是很好的圖形介面管理程式,其運作方式也是透過docker容器,因此安裝及維護相當容易。https://www.portainer.io/
```
1. 建立 portainer 用的 volume
docker volume create portainer_data
2. 安裝並執行 portainer
docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
```
若是以rootless方式執行portainer,需將docker.sock設定到執行的窗口,修改如下:
```
docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /$XDG_RUNTIME_DIR/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
```
## portainer 忘記 admin 密碼
使用portainer管理Docker容器時,admin帳號的密碼要求長度12個字元, 忘記時可以如下處理:
```
1. 停止 portainer
root# docker stop portainer
2. 查詢 portainer.db 的位置
root# docker inspect portainer | grep Source | grep portainer_data
得到 "Source": "/var/lib/docker/volumes/portainer_data/_data",
3. 執行重置密碼
root# docker run --rm -v /var/lib/docker/volumes/portainer_data/_data:/data portainer/helper-reset-password
回傳
{"level":"info","filename":"portainer.db","time":"2024-04-03T03:31:45Z","message":"loading PortainerDB"}
2024/04/03 03:31:45 Password successfully updated for user: admin
2024/04/03 03:31:45 Use the following password to login: 2bl7hG06XuO#+K^_.}1z59gq&erdL[F8
其中,admin已被修改密碼為 "2bl7hG06XuO#+K^_.}1z59gq&erdL[F8"
```
## docker 對外服務使用 port 1024 以下注意事項
以 rootless 方式執行 docker,系統會限制對外服務 port 號大於1024,要開放1024以下port,則需設定:
資料來源:https://docs.docker.com/engine/security/rootless/#exposing-privileged-ports
```
user2# sudo setcap cap_net_bind_service=ep $(which rootlesskit)
user2# systemctl --user restart docker
```
或是產生 /etc/sysctl.d/10-docker.conf 後重啟 sysctl
```
root# cat <<EOF > /etc/sysctl.d/10-docker.conf
# Exposing privileged ports under 1024 to serve
# 將1024 port 以上開放出來 by alubas@mail.kh.edu.tw
net.ipv4.ip_unprivileged_port_start=0
EOF
root# sysctl --system
```
## 私有 dockerhub
若要把 docker.io 官方的 image 放入私有 dockerhub, 例如 tomcat:10-jdk11
1. 自docker.io官方下載 image
```
docker pull docker.io/library/tomcat:10-jdk11
```
2. 重新 TAG image, 要標示完整路徑, 例如 mydockerhub.edu.tw/tomcat:10-jdk11
```
docker tag docker.io/library/tomcat:10-jdk11 mydockerhub.edu.tw/tomcat:10-jdk11
```
3. 將重新 TAG 後的 image push 進私有 dockerhub
```
docker push mydockerhub.edu.tw/tomcat:10-jdk11
```
4. client 端用 podman 要下載該 image 預設採 https, 若不走 https 則
```
podman pull --tls-verify=false mydockerhub.edu.tw/tomcat:10-jdk11
```
5. cilent 端用 docker 要下載該 image 時若不走 https, 要新增一個檔案 /etc/docker/daemon.json, 內容
```
{
"insecure-registries": [ "mydockerhub.edu.tw" ]
}
```
若為 rootless 模式, 則放在 ~/.config/docker/daemon.json 中, 重啟 docker, 之後就可下載那個 image 了
```
systemctl --user restart docker
docker pull mydockerhub.edu.tw/tomcat:10-jdk11
```
## 修改 docker 預設目錄
docker 的預設目錄為 /var/lib/docker, 有時為了磁碟空間安排, 會改變 docker 的預設目錄:
```
1. systemctl stop docker <---停止 docker service
2. 在 /etc/docker/daemon.json 中, 加上
{
"data-root": "/apps/var_lib_docker" <---docker 資料要放的目錄
}
3. rsync -avzr /var/lib/docker/* /apps/var_lib_docker/ <---將原先docker的資料目錄 rsync 到新路徑
4. systemctl start docker <---重啟 docker service
```