Docker镜像定制实战:配置Yum源与Nginx服务部署

发布时间:2026/7/28 10:17:01
Docker镜像定制实战:配置Yum源与Nginx服务部署 这次我们来看一个 Docker 基础实战主题如何定制一个简单的 Docker 镜像并在容器内部配置 Yum 仓库最终完成一个服务的安装与部署。这听起来像是基础操作但很多人在实际构建时往往会卡在“镜像构建慢”、“容器内网络不通”、“依赖安装失败”这些点上。这篇文章不绕弯子直接带你从零开始手把手完成一个包含完整服务部署的镜像定制过程重点解决构建效率和服务可移植性问题。如果你经常需要为不同的环境开发、测试、生产打包应用或者厌倦了每次部署都要重复安装一堆依赖那么掌握定制镜像和容器内服务部署的技能会直接提升你的效率。本文的核心就是三个动作写 Dockerfile 定制镜像、在容器运行时配置 Yum 源、在容器内完成服务的安装与启动。我们会用最直白的步骤和可复现的命令让你看完就能在自己的机器上跑起来。1. 核心能力速览在深入细节之前我们先快速了解通过本文你将掌握哪些核心技能以及它们能解决什么问题。能力项说明与价值定制简单镜像从基础镜像如 CentOS、Ubuntu开始通过 Dockerfile 定义步骤构建出包含特定环境、应用和配置的自定义镜像。这是实现应用环境一致性和可移植性的基石。容器内配置 Yum 仓库在基于 RHEL/CentOS 的容器中替换默认的、可能访问缓慢的 Yum 源。使用国内镜像源如阿里云、清华源可以极大加速软件包安装速度是提升镜像构建效率的关键。容器内安装部署服务在构建镜像的阶段或容器启动时通过包管理工具如 yum安装并配置所需的服务如 Nginx、MySQL、自定义应用。实现“镜像即服务”开箱即用。核心价值提升构建效率优化 Yum 源避免因网络问题导致的构建超时或失败。环境标准化一次构建处处运行消除“在我机器上是好的”问题。简化部署流程将复杂的服务安装、配置步骤固化到镜像中部署只需一条docker run命令。技术门槛低。只需具备基础的 Linux 命令和 Docker 概念知识。硬件要求无特殊要求。任何能安装 Docker 的机器Linux, macOS, Windows均可。2. 适用场景与使用边界这个技能组合不是花架子它在以下几个具体场景中非常实用适用场景CI/CD 流水线在自动化构建中需要快速为应用创建包含所有依赖的运行时镜像。配置高效的 Yum 源能显著缩短构建时间。本地开发环境搭建快速拉起一个包含特定中间件如 Redis, Nginx的容器进行开发测试无需污染宿主机环境。应用交付将你的 Java/Python/Go 应用及其依赖的操作系统库、配置文件一起打包成镜像交付给测试或运维人员。学习与实验需要纯净、可随时销毁重建的环境来学习新软件或复现问题。使用边界与注意事项镜像体积在 Dockerfile 中执行yum install会增加镜像层大小。建议在同一RUN指令中安装多个包并在最后清理缓存yum clean all以优化体积。安全性使用来自可信源的 Yum 仓库。避免在镜像中硬编码敏感信息如密码、密钥应使用 Docker 秘钥管理或环境变量传入。服务管理容器内通常只运行一个前台主进程。对于需要启动的系统服务如 sshd, crond需要特别注意其启动和管理方式通常不推荐在容器内运行多个后台服务。数据持久化容器内安装的服务产生的数据如数据库文件、日志默认会随容器删除而丢失。务必通过 Docker 卷Volume或绑定挂载实现数据持久化。3. 环境准备与前置条件开始动手之前请确保你的工作环境已经就绪。以下是必需的准备清单操作系统支持 Docker 的 Linux 发行版如 Ubuntu, CentOS、macOS 或 Windows 10/11需启用 WSL2。本文命令以 Linux 环境为例。Docker 引擎确保 Docker 已正确安装并运行。打开终端执行以下命令验证docker --version docker run hello-world如果能看到 Docker 版本信息并成功运行hello-world容器说明环境正常。网络连接构建镜像时需要从 Docker Hub 拉取基础镜像从 Yum 仓库下载软件包。确保你的网络可以访问互联网如果需要请配置好代理。文本编辑器准备一个你熟悉的文本编辑器如 VSCode, Vim, Sublime Text来编写 Dockerfile 和配置文件。磁盘空间预留至少 2-5 GB 的可用磁盘空间用于存储镜像和容器层。4. 定制简单镜像编写你的第一个 Dockerfile定制镜像的核心是编写 Dockerfile。它是一个文本文件包含了一系列指令告诉 Docker 如何构建你的镜像。我们从一个最简单的目标开始创建一个基于 CentOS 7 的镜像并在其中安装vim和wget工具。步骤 1创建项目目录在本地创建一个工作目录并进入该目录。mkdir my-custom-image cd my-custom-image步骤 2编写 Dockerfile在工作目录中创建一个名为Dockerfile的文件注意没有后缀名并输入以下内容# 使用 CentOS 7 作为基础镜像 FROM centos:7 # 设置维护者信息可选 LABEL maintaineryour-emailexample.com # 在构建镜像时执行的命令安装软件包 RUN yum install -y vim wget # 设置容器启动时默认的工作目录 WORKDIR /app # 声明容器运行时监听的端口可选此处仅为示例 # EXPOSE 80 # 设置容器启动时执行的默认命令 CMD [/bin/bash]指令解析FROM指定基础镜像这是构建的起点。LABEL为镜像添加元数据如维护者信息。RUN在镜像构建过程中执行命令。这里使用yum install安装软件。WORKDIR设置工作目录后续的RUN、CMD、ENTRYPOINT指令会在此目录下执行。EXPOSE声明容器运行时提供的服务端口这只是一种文档形式的说明实际映射需要在docker run时通过-p参数指定。CMD指定容器启动时默认执行的命令。这里设置为启动 Bash 终端。步骤 3构建镜像在Dockerfile所在目录执行构建命令。-t参数用于给镜像打标签名称:版本。docker build -t my-centos-tools:1.0 .命令最后的.表示构建上下文为当前目录。Docker 客户端会将当前目录下的所有文件通常通过.dockerignore过滤发送给 Docker 守护进程进行构建。构建过程会逐条执行 Dockerfile 中的指令。你会看到 Docker 拉取centos:7基础镜像然后执行yum install。注意此时使用的是 CentOS 默认的 Yum 源速度可能较慢甚至可能因网络问题失败。这正是我们下一节要优化的地方。步骤 4运行并验证镜像构建成功后运行一个基于此镜像的容器docker run -it --rm my-centos-tools:1.0-it分配一个伪终端并保持标准输入打开允许我们与容器交互。--rm容器退出后自动删除方便测试。容器启动后你应该直接进入了容器的 Bash 终端因为 CMD 是/bin/bash。尝试执行以下命令验证工具是否安装成功vim --version | head -1 wget --version | head -1 pwd # 应该显示 /app这是 WORKDIR 设置的结果输入exit退出容器。至此你已经完成了一个最简单镜像的定制。但构建速度慢的问题还没解决。接下来我们优化它。5. 为容器配置 Yum 仓库加速构建的关键默认的 CentOS Yum 源服务器可能在国外导致yum install速度极慢甚至超时。解决方案是在 Dockerfile 中在执行yum install之前先将 Yum 源替换为国内的镜像源如阿里云、清华大学开源软件镜像站等。目标修改 Dockerfile在安装软件前先备份旧源配置阿里云 Yum 源。步骤 1获取阿里云 CentOS 7 Yum 源配置文件你可以直接从阿里云镜像站获取。通常配置文件内容类似如下以 CentOS 7 为例# 内容保存为 CentOS-Base.repo 文件 [base] nameCentOS-$releasever - Base - mirrors.aliyun.com failovermethodpriority baseurlhttp://mirrors.aliyun.com/centos/$releasever/os/$basearch/ http://mirrors.aliyuncs.com/centos/$releasever/os/$basearch/ http://mirrors.cloud.aliyuncs.com/centos/$releasever/os/$basearch/ gpgcheck1 gpgkeyhttp://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7 # ... 还有其他 [updates], [extras] 等仓库配置结构类似为了在 Dockerfile 中简化操作我们可以直接使用curl或wget下载阿里云提供的现成 repo 文件或者使用sed命令修改现有的 repo 文件。步骤 2编写优化后的 Dockerfile创建新的文件Dockerfile.aliyun内容如下# 使用 CentOS 7 作为基础镜像 FROM centos:7 # 设置维护者信息 LABEL maintainerdevopsexample.com # 1. 备份原有的 Yum 源配置文件可选但是个好习惯 RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup # 2. 下载阿里云的 CentOS 7 Yum 源配置文件 # 方法一使用 curl 直接下载推荐 RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo # 方法二如果容器内没有 curl可以先安装 curl或者使用 wget # RUN yum install -y wget \ # wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo # 3. 清理 Yum 缓存并生成新缓存非必须但可确保使用新源 RUN yum clean all yum makecache # 4. 安装所需软件现在应该快多了 RUN yum install -y vim wget net-tools telnet tree # 5. 安装后清理减少镜像层大小 RUN yum clean all rm -rf /var/cache/yum/* # 设置工作目录 WORKDIR /app # 默认启动命令 CMD [/bin/bash]关键点说明顺序很重要必须在yum install之前配置好新的 Yum 源。组合命令你可以将多个RUN指令合并用连接以减少镜像层数但为了清晰本例分开书写。清理缓存安装完成后执行yum clean all可以清理下载的软件包缓存这对缩减最终镜像体积非常有效。步骤 3构建并对比速度使用新的 Dockerfile 构建镜像docker build -f Dockerfile.aliyun -t my-centos-fast:1.0 .这次构建过程中在执行yum install时你应该能明显感觉到软件包下载速度的提升。这就是定制 Yum 源带来的最直接收益。6. 容器内安装部署服务以 Nginx 为例现在我们进行终极目标在定制镜像中安装并配置一个真正的服务例如 Nginx Web 服务器并确保容器启动时服务能自动运行。这里有一个重要概念容器的主进程。Docker 容器设计为运行单个前台进程。这个进程的 PID 为 1它的生命周期就是容器的生命周期。因此我们需要让 Nginx 以前台模式运行。步骤 1编写服务化部署的 Dockerfile创建文件Dockerfile.nginxFROM centos:7 LABEL maintainerwebmasterexample.com # 1. 配置阿里云 Yum 源 RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup \ curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo \ yum clean all yum makecache # 2. 安装 Nginx # CentOS 7 默认 Yum 仓库没有 Nginx需要先安装 EPEL 仓库 RUN yum install -y epel-release \ yum install -y nginx # 3. 创建自定义首页可选 RUN echo h1Hello from Custom Nginx Docker Container!/h1pYum repo optimized with Aliyun Mirror./p /usr/share/nginx/html/index.html # 4. 暴露 Nginx 默认端口 EXPOSE 80 # 5. 启动 Nginx # 关键让 Nginx 在前台运行。默认 nginx 命令会启动后台守护进程容器会立即退出。 # 使用 nginx -g daemon off; 使其保持在前台。 CMD [nginx, -g, daemon off;]步骤 2构建 Nginx 镜像docker build -f Dockerfile.nginx -t my-nginx:1.0 .步骤 3运行 Nginx 容器并测试运行容器并将容器的 80 端口映射到宿主机的 8080 端口docker run -d --name my-web -p 8080:80 my-nginx:1.0-d后台运行容器。--name给容器命名。-p 8080:80端口映射宿主机端口:容器端口。步骤 4验证服务查看容器状态docker ps应能看到my-web容器正在运行。查看容器日志docker logs my-web查看 Nginx 启动日志。访问服务打开浏览器访问http://localhost:8080。你应该能看到我们自定义的 “Hello from Custom Nginx Docker Container!” 页面。进入容器检查可选docker exec -it my-web /bin/bash # 进入容器后可以检查进程、配置文件等 ps aux | grep nginx cat /etc/nginx/nginx.conf | head -20 exit至此你已经成功完成了一个包含服务部署的完整镜像定制流程。这个镜像my-nginx:1.0包含了 CentOS 7、优化的 Yum 源、Nginx 服务以及自定义配置可以分发到任何 Docker 环境中一键运行。7. 进阶使用 Dockerfile 最佳实践为了让你的镜像更高效、更安全这里有一些进阶的最佳实践使用.dockerignore文件在构建上下文目录即docker build .中的.创建.dockerignore文件排除不需要发送给 Docker 守护进程的文件如日志、git 目录、临时文件可以加速构建过程并减少镜像上下文大小。**/.git **/.log **/tmp Dockerfile*.bak README.md多阶段构建Multi-stage Build对于需要编译的应用可以使用多阶段构建来分离构建环境和运行环境最终得到一个非常小巧的仅包含运行所需文件的镜像。# 第一阶段构建阶段 FROM golang:1.19 AS builder WORKDIR /app COPY . . RUN go build -o myapp . # 第二阶段运行阶段 FROM alpine:latest WORKDIR /root/ # 从 builder 阶段只复制编译好的可执行文件 COPY --frombuilder /app/myapp . CMD [./myapp]非 root 用户运行默认情况下容器内进程以 root 用户运行存在安全风险。建议在 Dockerfile 中创建并使用非 root 用户。RUN groupadd -r appuser useradd -r -g appuser appuser USER appuser # 后续的 RUN, CMD, ENTRYPOINT 都会以 appuser 身份执行合理排序指令Docker 会缓存每一层。将变化频率低的指令如安装系统包放在前面变化频率高的指令如复制应用代码放在后面可以充分利用缓存加速后续构建。8. 常见问题与排查方法在实践过程中你可能会遇到以下问题。这里提供快速的排查思路。问题现象可能原因排查方式解决方案docker build失败错误提示Could not resolve host或网络超时。1. 宿主机网络问题。2. Docker 守护进程代理未配置。3. 基础镜像拉取失败。1. 在宿主机测试ping mirrors.aliyun.com。2. 检查 Docker 配置文件 (/etc/docker/daemon.json) 中的代理设置。3. 手动docker pull centos:7测试。1. 解决宿主机网络。2. 正确配置 Docker 的 HTTP/HTTPS 代理。3. 更换 Docker Hub 镜像加速器。yum install速度极慢或失败。1. 未替换 Yum 源使用的是默认国外源。2. 配置的国内镜像源地址错误或不可用。1. 进入构建失败的中间层容器检查源文件docker run -it image_id /bin/bash查看/etc/yum.repos.d/。2. 在容器内手动curl测试 repo 文件 URL。1. 确保 Dockerfile 中RUN配置 Yum 源的命令在yum install之前且执行成功。2. 使用稳定可靠的国内镜像源地址。镜像构建成功但docker run后容器立即退出。容器内没有前台进程在运行。如果 CMD 是启动一个后台服务如systemctl start nginx命令执行完即结束导致容器退出。docker logs container_name查看容器日志。通常日志为空或只有服务启动的瞬间输出。确保CMD或ENTRYPOINT指定的命令是前台运行的。对于 Nginx 是nginx -g ‘daemon off;‘对于 Node.js 是node app.js。端口映射了但宿主机无法访问容器服务。1. 端口映射错误 (-p参数写反)。2. 容器内防火墙未开放端口。3. 服务未在容器内正确监听如绑定到了 127.0.0.1。1.docker port container_name查看端口映射。2.docker exec -it container_name curl localhost:80测试容器内服务是否正常。3.docker exec -it container_name netstat -tlnp查看监听地址。1. 检查-p参数格式宿主机端口:容器端口。2. 对于 CentOS 容器可能需要关闭 firewalld 或添加规则生产环境慎用。3. 确保服务配置监听0.0.0.0。容器内服务启动报错提示权限不足。1. 以非 root 用户运行时没有对应目录的读写权限。2. 使用了宿主机的只读卷。查看容器日志docker logs获取具体错误信息。1. 在 Dockerfile 中通过RUN chown或RUN chmod调整目录权限。2. 检查docker run -v挂载的卷权限设置。9. 最佳实践与使用建议将上述流程应用于实际项目时请遵循以下建议分层与缓存利用精心设计 Dockerfile 指令顺序。将安装系统依赖、下载固定版本软件包等不常变动的操作放在上层将复制频繁变动的应用代码、配置文件等操作放在下层。这能最大化利用 Docker 的构建缓存。版本固定在FROM和RUN yum install时尽量指定具体的版本号例如FROM centos:7.9.2009RUN yum install -y nginx-1.20.1。这能确保构建的确定性和可复现性避免因基础镜像或软件包自动更新导致意外行为。单一职责一个容器只运行一个主进程或服务。不要试图在一个容器内运行 Nginx、MySQL、Redis 等多个服务。应使用 Docker Compose 或 Kubernetes 来编排多个容器。数据与配置分离不要将应用数据如数据库文件、上传内容或需要频繁修改的配置直接写入容器层。务必使用 Docker 卷-v或--mount或绑定挂载实现数据持久化和动态配置管理。镜像仓库管理为你的自定义镜像打上有意义的标签如myapp:1.0,myapp:latest并推送到私有或公共的 Docker 镜像仓库如 Docker Hub, Harbor, AWS ECR。便于团队共享和持续集成/持续部署CI/CD。安全扫描定期使用docker scan或第三方工具如 Trivy, Clair对构建的镜像进行安全漏洞扫描及时更新基础镜像和应用依赖。通过定制镜像、优化 Yum 源、在容器内部署服务这一套组合拳你不仅掌握了 Docker 的基础核心操作更获得了提升开发部署效率的实用技能。下次当你需要为一个新项目准备环境或者为旧项目制作交付物时尝试从编写一个 Dockerfile 开始。它将繁琐的安装配置步骤转化为可版本化、可共享、可一键执行的代码这才是 Docker 带来的真正生产力提升。建议将本文中的 Dockerfile 作为模板收藏根据你的实际需求进行修改和扩展。