从Hello-World到自定义镜像:在Ubuntu 20.04上玩转Docker镜像的完整工作流
从Hello-World到自定义镜像:在Ubuntu 20.04上玩转Docker镜像的完整工作流
当开发者第一次接触Docker时,往往会被其"一次构建,到处运行"的理念所吸引。但真正深入使用后才会发现,Docker的魅力远不止于此——它更像是一个精密的乐高工厂,允许你从基础镜像开始,通过层层叠加构建出完全符合需求的定制化环境。本文将带你从最基础的Hello-World镜像出发,逐步深入到自定义镜像的创建与管理,最终形成一个完整的Docker镜像工作流闭环。
1. 环境准备与基础概念
在开始构建自定义镜像之前,我们需要确保Docker环境已正确安装并理解几个核心概念。Ubuntu 20.04作为长期支持版本,提供了稳定的基础环境。
Docker三大核心组件:
- 镜像(Image):只读模板,包含创建容器所需的文件系统结构和内容
- 容器(Container):镜像的可运行实例,具有自己的隔离环境
- 仓库(Registry):集中存放镜像的地方,Docker Hub是默认公共仓库
安装Docker CE最新版本:
# 更新软件包索引
sudo apt update
# 安装依赖工具
sudo apt install apt-transport-https ca-certificates curl software-properties-common
# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 添加稳定版仓库
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
# 安装Docker CE
sudo apt install docker-ce
验证安装是否成功:
sudo docker run hello-world
这个简单的命令实际上完成了从拉取镜像到运行容器的完整生命周期。如果看到"Hello from Docker!"的输出,说明你的环境已经准备就绪。
2. 镜像生命周期管理基础
理解Docker镜像的生命周期是进行自定义镜像开发的基础。一个典型的镜像生命周期包括:拉取→运行→修改→提交→推送。
2.1 镜像拉取与容器运行
让我们以Ubuntu官方镜像为例,展示基础操作:
# 拉取Ubuntu 20.04镜像
docker pull ubuntu:20.04
# 运行交互式容器
docker run -it --name my_ubuntu ubuntu:20.04 /bin/bash
在容器内,你可以像在普通Ubuntu系统中一样操作:
# 更新包列表
apt update
# 安装常用工具
apt install -y curl wget vim
注意:在容器中进行的修改默认不会保存到镜像中,退出后这些修改将丢失(除非提交为新的镜像)
2.2 镜像与容器管理
掌握以下命令对日常开发至关重要:
# 列出本地镜像
docker images
# 列出运行中的容器
docker ps
# 列出所有容器(包括停止的)
docker ps -a
# 停止容器
docker stop my_ubuntu
# 删除容器
docker rm my_ubuntu
# 删除镜像
docker rmi ubuntu:20.04
3. 构建Python Flask开发环境镜像
现在,让我们通过一个实际案例——构建Python Flask开发环境镜像,来演示完整的自定义镜像工作流。
3.1 基础环境准备
首先启动一个干净的Ubuntu容器:
docker run -it --name flask_dev ubuntu:20.04 /bin/bash
在容器内执行以下操作:
# 更新软件源
apt update && apt upgrade -y
# 安装基础工具
apt install -y python3 python3-pip vim
# 安装Flask
pip3 install flask
# 验证安装
python3 -c "import flask; print(flask.__version__)"
3.2 创建简单的Flask应用
在容器内创建应用目录和文件:
mkdir /app
cat > /app/app.py <<EOF
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello from custom Docker image!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
EOF
3.3 提交为自定义镜像
退出容器后,将其提交为新的镜像:
docker commit \
-m "Added Python3 and Flask with demo app" \
-a "Your Name" \
flask_dev \
my_flask_app:1.0
验证新镜像:
docker images | grep my_flask_app
3.4 运行自定义镜像
使用新镜像启动容器:
docker run -d -p 5000:5000 --name flask_container my_flask_app:1.0 python3 /app/app.py
访问http://localhost:5000即可看到Flask应用的输出。
4. 使用Dockerfile构建专业级镜像
虽然docker commit可以快速创建镜像,但最佳实践是使用Dockerfile进行可重复的构建。
4.1 创建Dockerfile
在本地创建项目目录和Dockerfile:
mkdir flask_project && cd flask_project
cat > Dockerfile <<EOF
FROM ubuntu:20.04
RUN apt update && apt upgrade -y && \
apt install -y python3 python3-pip && \
pip3 install flask
WORKDIR /app
COPY app.py /app/app.py
EXPOSE 5000
CMD ["python3", "app.py"]
EOF
创建相同的app.py文件:
cat > app.py <<EOF
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello from Dockerfile-built image!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
EOF
4.2 构建并运行镜像
# 构建镜像
docker build -t my_flask_app:2.0 .
# 运行容器
docker run -d -p 5001:5000 --name flask_container_2 my_flask_app:2.0
访问http://localhost:5001验证新容器是否正常运行。
4.3 镜像优化技巧
专业级的镜像构建需要考虑以下优化:
1. 减小镜像体积:
FROM python:3.8-slim
RUN pip install --no-cache-dir flask
2. 多阶段构建:
# 构建阶段
FROM python:3.8 as builder
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# 运行阶段
FROM python:3.8-slim
COPY --from=builder /root/.local /root/.local
COPY app.py .
ENV PATH=/root/.local/bin:$PATH
3. 使用.dockerignore:
__pycache__
*.pyc
*.pyo
*.pyd
.Python
env
5. 高级镜像管理技巧
当拥有多个自定义镜像后,有效的管理策略变得尤为重要。
5.1 镜像标签与版本控制
# 为镜像添加标签
docker tag my_flask_app:1.0 my_flask_app:latest
# 查看镜像历史
docker history my_flask_app:1.0
5.2 镜像导出与导入
# 导出镜像为tar文件
docker save -o my_flask_app_1.0.tar my_flask_app:1.0
# 从tar文件导入镜像
docker load -i my_flask_app_1.0.tar
5.3 镜像仓库管理
虽然本文不涉及具体仓库推送操作,但了解以下命令很有帮助:
# 登录Docker Hub
docker login
# 标记镜像准备推送
docker tag my_flask_app:1.0 username/my_flask_app:1.0
# 推送到仓库
docker push username/my_flask_app:1.0
6. 实际开发中的镜像工作流
在实际开发中,完整的Docker镜像工作流通常包含以下环节:
-
开发阶段:
- 使用基础镜像启动开发容器
- 在容器内进行应用开发和测试
- 通过volume挂载实现代码热更新
-
构建阶段:
- 编写Dockerfile定义构建过程
- 使用多阶段构建优化镜像
- 添加必要的标签和元数据
-
测试阶段:
- 运行容器化测试套件
- 扫描镜像中的安全漏洞
- 验证生产环境配置
-
部署阶段:
- 将镜像推送到私有仓库
- 使用编排工具部署容器
- 监控容器运行状态
一个典型的开发命令示例:
# 开发时使用volume挂载
docker run -it -v $(pwd):/app -p 5000:5000 my_flask_app:1.0 bash
在容器内可以实时修改代码并看到变化,而无需重新构建镜像。
更多推荐
所有评论(0)