在Linux系统中使用Dockerfile创建Docker
在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内容
使用gedit 或 Vs 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 .
输入准确命令后回车执行,如下终端截图,耐心等待,受网络和机器性能影响,耗时不太确定:
创建完成后,执行 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
运行后,就直接进入了容器:
在另一个终端中使用命令 docker ps -a 查看当前机器中所有的容器:
我映射了宿主机的/home/solun/Docker 到容器的 /workspace/Docker_map,因此容器中Docker_map内的内容就是宿主机的Docker中的内容:
查看容器中是否包含Dockerfile中指定的那些pip包:
pip list

到这里基本就没什么问题了,可以使用你的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

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>
