Docker容器定制:从CentOS基础镜像到Nginx服务部署实战
30款热门AI模型一站整合DeepSeek/GLM/Qwen 随心用限时 5 折。 点击领海量免费额度这类 Docker 基础操作新手最容易卡住的地方往往不是命令本身而是“为什么我的容器里装不了软件”、“为什么我做的镜像那么大”、“为什么容器重启后配置就丢了”。今天我们就围绕“定制简单镜像”和“容器内安装部署服务”这两个核心动作拆解背后的逻辑和实操细节。如果你刚接触 Docker想搞明白如何把一个干净的 CentOS 容器一步步变成能跑 Nginx 或 Zabbix 的服务环境并且理解每一步的用意那这篇经验梳理应该能帮你避开不少弯路。很多人一上来就搜docker run centos然后yum install发现报错“无法找到仓库”或者装完服务后不知道如何保存状态、如何配置。这其实是因为没理清 Docker 的“层”概念和容器网络访问机制。我会从最基础的“启动一个能联网的容器”开始带你走通“配置Yum源 - 安装软件 - 保存为镜像 - 部署服务”的完整闭环。整个过程我会重点解释哪些操作是临时的哪些是持久的以及如何用最少的命令和最小的镜像体积来完成目标。1. 先理清目标我们要定制一个什么样的“服务镜像”在动手敲命令之前得先想清楚最终要什么。是仅仅在容器里体验一下 yum 安装过程还是要做出一个可以分发给别人、一键启动就能提供服务的镜像这决定了我们的操作路径。目标A临时学习/测试你只需要一个能联网、能 yum 安装软件的容器环境测试完就丢弃。这种情况重点在于快速配置好容器内的网络和仓库不关心镜像的复用性。目标B制作可复用的服务镜像你需要制作一个像nginx:latest那样的镜像里面预装好了 Nginx、Zabbix Agent 或其他服务并且配置了正确的启动命令。这样任何人拿到这个镜像docker run之后服务就能跑起来。这是我们这次的重点。对于目标B一个高效的思路是先在一个临时容器里完成所有调试和安装确认无误后再将其固化为一个新镜像。而不是试图在 Dockerfile 里一遍遍构建、试错虽然 Dockerfile 是最终推荐方式但调试阶段直接操作容器更直观。2. 第一步启动一个“干净”且“能联网”的 CentOS 容器几乎所有问题的起点都是这里。如果你直接用docker run -it centos:7 bash启动容器大概率会发现yum update或ping baidu.com失败。这不是镜像坏了而是容器默认的网络配置和仓库配置可能不适用于你的环境。2.1 选择合适的基础镜像首先确保你拉取的是官方或可信的 CentOS 镜像。不建议使用latest标签明确指定版本更稳妥。# 拉取 CentOS 7 镜像 docker pull centos:7为什么是centos:7而不是centos:latest因为latest标签可能指向 CentOS Stream 或其他版本其软件仓库和系统路径可能与 CentOS 7 不同会导致后续安装命令不一致。固定版本能保证环境一致性。2.2 以“可安装软件”的模式启动容器单纯-it交互运行是不够的。为了让容器内部能访问外部网络以下载软件包通常不需要特殊参数因为 Docker 默认会为容器分配网络。但如果你的宿主机处于特殊网络环境如某些企业内网需要代理则需要在启动容器时传递环境变量或在 Docker 服务端配置代理。一个更实用的启动命令是# 启动一个名为 my_centos 的临时容器并进入bash docker run -it --name my_centos --rm centos:7 bash参数解释-it分配一个伪终端并保持标准输入打开让我们可以交互操作。--name my_centos给容器起个名字方便后续操作如docker exec或docker commit。--rm容器退出时自动删除它。因为我们只是用它来调试安装过程最终会提交成新镜像这个临时容器不需要保留。centos:7 bash基于centos:7镜像启动容器并执行bash命令。进入容器后你应该先测试网络连通性# 在容器内执行 ping -c 2 114.114.114.114如果 ping 不通大概率是宿主机的防火墙或 Docker 网络驱动问题。一个快速的排查方法是检查容器的网络模式# 在宿主机上查看容器的网络信息 docker inspect my_centos | grep -A 10 NetworkSettings通常只要宿主机能上网使用默认的bridge网络模式的容器就能通外网。如果不行可以尝试在启动时指定--network host使用宿主机网络栈但这会带来安全性和端口冲突的考虑仅用于测试。3. 第二步在容器内配置可用的 Yum 仓库这是核心环节。CentOS 官方仓库地址可能因为网络延迟或镜像同步问题访问缓慢甚至失败。我们需要将仓库源替换为国内镜像如阿里云、清华大学的镜像源。3.1 备份原有仓库配置进入容器后首先备份默认的 repo 文件这是一个好习惯。# 进入容器后执行 cd /etc/yum.repos.d/ mkdir bak mv *.repo bak/3.2 下载并配置国内镜像源以阿里云镜像源为例适用于 CentOS 7# 下载阿里云的CentOS-Base.repo curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo # 如果容器内没有curl可以先安装curl用官方源临时安装速度可能慢 # yum install -y curl wget # 或者更直接的方法在宿主机下载好repo文件然后复制到容器内。为什么强调这个步骤因为很多 Docker 教程忽略了容器内 yum 源的配置直接假设yum install能工作。在实际生产环境或国内网络下不换源会导致安装速度极慢甚至超时失败让你误以为是 Docker 或镜像的问题。3.3 清理并生成缓存配置新源后执行以下命令使其生效# 清理旧缓存 yum clean all # 生成新缓存 yum makecache # 可以更新系统非必须但能测试仓库是否真正可用 yum update -y如果yum makecache能成功执行没有报错说明 Yum 仓库已经配置正确。此时你的容器已经具备了安装任何 CentOS 软件包的能力。4. 第三步在容器内安装并配置目标服务仓库搞定后安装软件就很简单了。我们以安装 Nginx 为例演示一个完整的服务部署流程。4.1 安装 Nginxyum install -y nginx安装完成后不要急着启动。我们先看看 Nginx 被安装到了哪里配置文件在哪。# 查看nginx安装位置 which nginx # 通常为 /usr/sbin/nginx # 查看配置文件目录 ls -la /etc/nginx/4.2 编写一个简单的自定义配置可选为了体现“定制”我们可以修改默认的欢迎页面或端口。例如修改默认的index.html# 备份原首页 cp /usr/share/nginx/html/index.html /usr/share/nginx/html/index.html.bak # 创建一个新的首页 echo h1Hello from My Custom Docker Nginx Container!/h1 /usr/share/nginx/html/index.html4.3 测试服务能否在容器内正常运行在将容器提交为镜像之前务必在容器内部先测试服务是否能启动。# 启动nginx nginx # 或者使用 systemctl注意容器内通常没有 systemd直接运行二进制文件。 # 检查nginx进程 ps aux | grep nginx # 测试本地访问容器内 curl http://localhost如果curl能返回我们刚才写的 “Hello from My Custom Docker Nginx Container!”说明 Nginx 安装和配置成功。关键点在容器里服务通常以前台模式运行或者通过脚本控制。我们最终制作镜像时需要指定一个启动命令CMD或ENTRYPOINT。现在在调试容器里我们可以先手动启动验证。4.4 考虑服务的持久化配置如果服务有需要持久化的数据或配置如 Nginx 的日志文件、Web 根目录我们需要规划好。在 Docker 中持久化数据通常通过“卷Volume”或“绑定挂载Bind Mount”来实现而不是保存在容器可写层。对于镜像制作阶段我们只需要确保服务默认的配置和启动方式是合理的。数据持久化是容器运行时通过-v参数来处理的。5. 第四步将配置好的容器提交为定制镜像经过上面几步我们已经在my_centos容器里安装好了 Nginx 并做了简单定制。现在我们需要把这个容器的当前状态“冻结”下来保存为一个新的镜像。5.1 退出容器但不删除注意我们启动容器时用了--rm参数一旦退出容器就会自动删除。为了提交镜像我们需要一个已停止但未删除的容器。因此更稳妥的流程是先不用--rm启动容器调试完成后退出容器再提交。实际操作流程修正如下启动容器不用--rmdocker run -it --name my_centos_builder centos:7 bash在容器内完成上述所有步骤配置yum源、安装nginx、修改首页。退出容器在容器内执行exit。此时容器会停止但不会被删除。提交容器为镜像docker commit my_centos_builder my-nginx:v1命令解释docker commit [容器名] [新镜像名:标签]这会将容器my_centos_builder的可写层即我们所有的修改与原来的centos:7只读层合并创建一个新的镜像my-nginx:v1。5.2 验证新镜像提交后检查镜像列表并基于新镜像运行一个容器来验证服务。# 查看镜像 docker images | grep my-nginx # 基于新镜像运行一个容器并让nginx在前台启动 docker run -d --name nginx-test -p 8080:80 my-nginx:v1 nginx -g daemon off;参数解释-d后台运行。-p 8080:80将宿主机的8080端口映射到容器的80端口。my-nginx:v1我们刚定制的镜像。nginx -g daemon off;覆盖镜像的默认CMD以前台模式启动Nginx这是让容器保持运行的最佳实践。现在在宿主机上打开浏览器访问http://localhost:8080应该能看到我们定制的欢迎页面。5.3 优化为镜像定义默认启动命令上面我们是在docker run时指定了启动命令。更好的做法是把启动命令做到镜像里。这需要用到 Dockerfile但我们可以通过docker commit时指定--change参数来模拟。不过更规范的做法是回到起点用 Dockerfile 来构建镜像。因为docker commit虽然直观但不利于自动化、版本管理和清晰了解镜像的构建过程。它会把操作历史“黑盒化”。6. 第五步使用 Dockerfile 重构构建流程最佳实践虽然我们通过交互式操作完成了定制但生产环境应该使用 Dockerfile。Dockerfile 是一个文本文件包含了一系列构建指令能实现可重复、透明化的构建。6.1 创建 Dockerfile在宿主机上创建一个工作目录并新建Dockerfile文件# 使用 CentOS 7 作为基础镜像 FROM centos:7 # 维护者信息可选 LABEL maintaineryour-emailexample.com # 配置国内Yum源 RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo \ yum clean all \ yum makecache # 安装 Nginx RUN yum install -y nginx # 定制欢迎页面 RUN echo h1Hello from My Custom Docker Nginx Container (Built by Dockerfile)!/h1 /usr/share/nginx/html/index.html # 暴露80端口 EXPOSE 80 # 设置容器启动时执行的命令 CMD [nginx, -g, daemon off;]6.2 构建镜像在 Dockerfile 所在目录执行docker build -t my-nginx-dockerfile:v1 .-t指定镜像标签.表示使用当前目录下的 Dockerfile。6.3 运行并测试docker run -d --name nginx-df -p 8081:80 my-nginx-dockerfile:v1访问http://localhost:8081验证。使用 Dockerfile 的优势可重复任何人在任何地方只要有这个文件都能构建出一模一样的镜像。透明每一步操作都记录在案易于理解和维护。层缓存Docker 会缓存每一层如果某一步没有修改下次构建会直接使用缓存极大加快构建速度。易于版本管理Dockerfile 可以放入 Git 仓库与代码一同管理。7. 常见问题与排查思路即使按照步骤操作你也可能会遇到一些问题。这里列出几个典型问题及其排查路径。7.1 容器内无法联网ping/curl/yum 失败检查容器网络模式docker inspect 容器名 | grep -i networkmode。如果是none则容器无网络。重新以bridge或host模式启动。检查宿主机防火墙某些系统如 CentOS 7 firewalld, Ubuntu ufw可能阻止了 Docker 的网络流量。可以尝试暂时关闭防火墙测试仅用于排查生产环境需谨慎。检查 Docker 服务状态systemctl status docker确保 Docker 服务正常运行。检查 DNS 配置容器内/etc/resolv.conf文件是否正常。可以尝试在docker run时添加--dns 8.8.8.8指定 DNS。7.2 Yum 安装软件速度慢或失败确认仓库源已正确替换cat /etc/yum.repos.d/CentOS-Base.repo检查里面的baseurl或mirrorlist是否是国内镜像地址。执行yum clean all yum makecache清理旧缓存并建立新缓存。检查网络连通性curl -I mirrors.aliyun.com看是否能连接到镜像站。容器时间不正确date命令查看如果时间偏差太大可能导致 SSL 证书验证失败。可以在 Dockerfile 或启动时同步时间RUN yum install -y ntpdate ntpdate time.windows.com。7.3 制作的镜像体积过大清理 Yum 缓存在 Dockerfile 的每个RUN yum install命令后最好清理缓存。RUN yum install -y nginx yum clean all合并 RUN 指令多个RUN指令会创建多个镜像层。尽量合并相关操作为一个RUN指令用连接。使用更小的基础镜像考虑使用centos:7的瘦身版如centos:7-slim或者 Alpine Linux但软件包管理不同。7.4 容器启动后服务立即退出检查前台/后台进程容器需要至少一个前台进程才能保持运行。如果镜像的CMD是启动一个后台服务如systemctl start nginx那么命令执行完进程就结束了容器也会退出。必须以前台模式运行主进程如nginx -g daemon off;。查看容器日志docker logs 容器名这里通常会有服务启动失败的错误信息。检查端口冲突docker run -p 80:80如果宿主机80端口已被占用容器可能启动失败。换一个宿主机端口如-p 8080:80。8. 扩展部署更复杂的服务如 Zabbix Agent理解了 Nginx 的部署流程部署其他服务如 Zabbix Agent、自定义应用的思路是一样的。准备基础环境同样从配置 Yum 源开始。查找安装方法对于 Zabbix Agent可能需要先添加 Zabbix 官方的 Yum 仓库。# 在Dockerfile中添加 RUN rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/7/x86_64/zabbix-release-6.0-4.el7.noarch.rpm RUN yum install -y zabbix-agent配置服务将 Agent 的配置文件如/etc/zabbix/zabbix_agentd.conf中Server和ServerActive指向你的 Zabbix Server IP。注意这个 IP 通常不能写死为127.0.0.1因为容器内是独立的网络命名空间。最好在容器启动时通过环境变量传入。定义启动命令CMD [zabbix_agentd, -f, -c, /etc/zabbix/zabbix_agentd.conf]核心经验对于需要连接外部其他服务的容器如 Agent 要连 Server配置文件的 IP、主机名等不要固化在镜像里。应该通过环境变量-e或在容器启动时挂载外部配置文件-v的方式动态注入。这样同一个镜像才能在不同的环境中复用。整个过程走下来你会发现定制 Docker 镜像的关键路径非常清晰启动基础容器 - 配置环境网络、仓库- 安装配置软件 - 验证 - 固化commit或Dockerfile。其中Yum仓库配置是第一步的基石而理解容器内服务的前台运行模式则是镜像能否成功运行的最后一道关卡。下次当你需要把一个传统服务塞进容器时不妨先按这个顺序在临时容器里走一遍流程调试成功后再写成 Dockerfile效率会高很多。 30款热门AI模型一站整合DeepSeek/GLM/Qwen 随心用限时 5 折。 点击领海量免费额度