在Linux系統中使用Dockerfile創建Docker

1. Docker 簡介

Docker 是一種輕量級的容器化技術,它可以將應用程序及其運行環境打包成一個獨立的“容器”(Container)。這個容器包含運行所需的一切依賴,如操作系統環境、庫、配置文件等,從而實現“一次構建,處處運行”。

相比傳統的虛擬機,Docker 啓動速度更快、佔用資源更少,因為它直接基於宿主機的 Linux 內核運行,不需要額外的系統虛擬化層。開發者可以使用 Docker 來:

  • 快速搭建統一的開發環境;
  • 將應用打包成可移植的鏡像;
  • 實現自動化部署與持續集成;
  • 避免“在我電腦上能跑”的環境不一致問題。

在實際使用中,我們通常通過 Dockerfile 來定義鏡像的構建過程。Dockerfile 是一個包含多條指令的文本文件,描述了從基礎鏡像開始,如何安裝依賴、複製文件、設置環境變量、以及定義容器啓動命令。
構建完成後,只需一條命令即可生成鏡像,並在任意安裝了 Docker 的系統上運行。

2. 編寫Dockerfile文本文件

2.1 創建文件

終端先cd到你要保存此文件的路徑下,再執行下面的命令,創建一個空的Dockerfile文件:

echo "" > Dockerfile
# Dockerfile 名字不能改,區分大小寫

2.2 編寫Dockerfile內容

使用geditVs Code打開Dockerfile:

# gedit 安裝命令
# sudo apt install gedit
gedit Dockerfile

構造方式分為單階段多階段,區別就是多階段構造出來的Docker體積可能更小(取決於你的具體情況),也就是存在某些包是你Docker中不需要但是在創建Docker過程中必須需要的包,否則,這一優勢並得不到體現,通常基本用單階段構造沒有任何問題,通常多一個包也不會多多大的體積。要想減小Docker體積,最有效的方法是刪除構建過程中的臨時/緩存文件

2.2.1 單階段構造

在Dockerfile中添加你需要的內容,以下為示例,應根據自己需求添加或刪減,推薦這種方式,簡單不傷腦:

# 使用 Ubuntu 22.04 作為基礎鏡像(基礎鏡像可自選)
FROM ubuntu:22.04
# 設置非交互模式,避免安裝過程中彈出提示
ENV DEBIAN_FRONTEND=noninteractive
# 前面設置了非交互式,可不用設置時區
# 設置時區為 UTC (0時區),避免交互式選擇時產生錯誤
# ENV TZ=UTC
# 設置時區為北京時間(東八區),並連接正確的時區文件
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安裝必要的一些工具和 Python 3.10 (可以根據需要修改)
RUN apt-get update && apt-get install -y \
python3.10 \
python3.10-dev \
python3.10-venv \
python3-pip \
python3-setuptools \
build-essential \
gcc-9 \
g++-9 \
cmake \
gdb \
curl \
wget \
git \
vim \
tzdata && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* #刪除臨時/緩存構造文件
# 更新 pip 為最新版
RUN python3.10 -m pip install --upgrade pip
# 安裝常用的 Python 庫(可以根據需要修改)
RUN python3.10 -m pip install --no-cache-dir \
wheel \
setuptools \
pandas \
numpy \
requests \
flask \
pytest \
opencv-python \
PyYAML
# 設置工作目錄(workspace 可自定義)
WORKDIR /workspace
# 默認命令
CMD ["/bin/bash"]
2.2.2 多階段構建

以下為多階段構建Docker的Dockerfile示例,這種情況一定清楚有哪些包是構建過程必須而最終產物無需的,否則付出和收益可能達不到預期。

# 第一階段:構建階段
FROM ubuntu:22.04 AS builder
# 設置非交互模式,避免安裝過程中彈出提示
ENV DEBIAN_FRONTEND=noninteractive
# 設置時區為上海時間
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安裝構建工具和 Python 3.10
RUN apt-get update && apt-get install -y \
python3.10 \
python3.10-dev \
python3.10-venv \
python3-pip \
python3-setuptools \
build-essential \
gcc-9 \
g++-9 \
cmake \
gdb \
wget \
unzip \
tar \
curl \
wget \
git \
vim \
tzdata && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 更新 pip 為最新版
RUN python3.10 -m pip install --upgrade pip
# 安裝常用的 Python 庫(可以根據需要修改)
RUN python3.10 -m pip install --no-cache-dir \
wheel \
setuptools \
pandas \
numpy \
requests \
flask \
pytest \
opencv-python \
PyYAML
# 第二階段:運行環境
FROM ubuntu:22.04 AS runtime
# 設置非交互模式,避免安裝過程中彈出提示
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安裝生產環境所需的基礎依賴
RUN apt-get update && apt-get install -y \
python3.10 \
python3.10-venv \
python3-pip \
python3-setuptools \
tzdata && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 從構建階段複製已安裝的 Python 包到運行時階段
COPY --from=builder /root/.local /root/.local
COPY --from=builder /usr/local /usr/local
# 設置工作目錄
WORKDIR /workspace
# 默認命令
CMD ["/bin/bash"]

3. 使用Dockerfile文件創建Docker

3.1 (可選)添加中國大陸Docker Hub 鏡像源

如果你在中國大陸,Docker Hub 的官方鏡像源可能比較慢,可以嘗試配置國內的鏡像源進行加速下載。

# vim 安裝命令
# sudo apt install vim
sudo vim /etc/docker/daemon.json

運行上面的命令,將下面的內容添加到daemon.json中:

{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.1panel.live",
"https://hub.rat.dev"
]
}

你也可以嘗試添加別的鏡像源來加速。
添加後,重啓Docker服務:

systemctl daemon-reexec
systemctl restart docker

3.2 創建Docker

有了Dockerfile之後,就可以開始使用命令創建Docker了,打開終端,cd到存放Dockerfile的路徑下,執行命令,開始構建Docker:

docker build -t <docker name>:<tag> .
  # for example
  docker build -t ubuntu22-04:base .
  docker build -t first_docker:v1.0.0 .

輸入準確命令後回車執行,如下終端截圖,耐心等待,受網絡和機器性能影響,耗時不太確定:

創建一個屬於自己的linux系統Docker鏡像之旅-簡單模式 - yl_Docker

創建完成後,執行 docker images 來查看當前機器中的鏡像。

3.3 測試/使用鏡像

使用創建好的Docker來起一個容器,測試Docker是否符合預期:

docker run -it --rm --name Test-Docker -v /home/solun/Docker:/workspace/Docker_map ubuntu22-04:base
# 參數解釋
--rm 		#加上這個參數,當退出容器,容器停止運行時,容器會自動刪除
--name 		#指定容器的名字
-v 			#用於指定宿主機和容器的路徑映射,映射後,容器便可訪問宿主機被映射的路徑下的資源,
#-v 可以有多個,一個 -v 指定一個路徑映射關係,當你要映射多個路徑到容器中,那就多來幾個-v

運行後,就直接進入了容器:

創建一個屬於自己的linux系統Docker鏡像之旅-簡單模式 - yl_Docker_02

在另一個終端中使用命令 docker ps -a 查看當前機器中所有的容器:

創建一個屬於自己的linux系統Docker鏡像之旅-簡單模式 - yl_Docker_03

我映射了宿主機的/home/solun/Docker 到容器的 /workspace/Docker_map,因此容器中Docker_map內的內容就是宿主機的Docker中的內容:

創建一個屬於自己的linux系統Docker鏡像之旅-簡單模式 - yl_Docker_04

查看容器中是否包含Dockerfile中指定的那些pip包:

pip list

創建一個屬於自己的linux系統Docker鏡像之旅-簡單模式 - yl_docker_05


到這裏基本就沒什麼問題了,可以使用你的Docker或容器了。

4. 保存/分享Docker

4.1 保存Docker

將Docker保存成.tar文件

docker save -o <tar_name>.tar <docker_name>:tag
  # 參數解釋
  tar_name 		#要保存的.tar文件名
  docker_name 	#剛才創建的Docker的名字
  tag 			#剛才創建的Docker的tag
  # for example
  docker save -o Ubuntu_22-04.tar ubuntu22-04:base

創建一個屬於自己的linux系統Docker鏡像之旅-簡單模式 - yl_Docker_06

4.2 分享Docker

上面保存的tar文件可以隨意分享給他人,而他人在安裝了Docker的機器上只需使用下面的命令加載tar文件裏的Docker即可:

docker load -i <tar_name>.tar
  # for example
  docker load -i Ubuntu_22-04.tar

加載後,使用docker images即可查看電腦上新加載的鏡像。

5. Docker容器基礎常用命令

5.1 創建容器

docker run -it --name <容器名稱> -v <宿主機絕對路徑>:<容器內的絕對路徑> <docker名>:<docker tag>
  # for example
  docker run -it --name Test-Docker -v /home/solun/Docker:/workspace/Docker_map ubuntu22-04:base

5.2 停止/啓動/重啓已有容器

docker stop <容器名/容器ID>
  docker start <容器名/容器ID>
    docker restart <容器名/容器ID>

5.3 進入容器

docker exec -it <容器名/容器ID> /bin/bash

5.4 退出容器

exit			# 容器會被關閉
exit -d 		# 容器不會被關閉
ctrl + p +q		# 容器不會被關閉

5.5 刪除容器

docker rm <容器名/容器ID>

5.6 複製文件

# 從容器內 複製到 容器外
docker cp <容器ID/名稱>:<容器內路徑> <容器外路徑>
  # 從容器外 複製到 容器內
  docker cp <容器外路徑> <容器ID/名稱>:<容器內路徑>

5.7 設置容器自動啓動

# 在創建時設置
docker run -it --name <容器名稱> --restart=always -v <宿主機絕對路徑>:<容器內的絕對路徑> <docker名>:<docker tag>
  # 已存在容器設置自啓動
  docker update --restart=always <容器名/容器ID>
    or
    docker container update --restart=always <容器名/容器ID>

5.8 容器端口映射

docker run -it --name <容器名> -p <宿主機端口>:<容器端口> <docker名>:<docker tag>