Dockerfile 定制Nginx镜像

柳三千

文章最后更新时间:2025年06月23日

Dockerfile 构建 Nginx 镜像详解

前言

Dockerfile 是用于定义 Docker 镜像构建过程的文本文件,包含特定语法规则。在包含 Dockerfile 的目录中执行 docker build -t 镜像名:标签 . 即可构建镜像。构建镜像需理解镜像分层概念——镜像由多层组成,理论上最多支持 127 层。

一、查看镜像层数的方法

1. docker history 命令(查看镜像分层及大小)

[root@localhost docker_images]# docker history centos_nginx:1.20
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
ac20103ed758   3 days ago      /bin/sh -c #(nop)  CMD ["bin/sh" "-c" "ngin…    0B          
ec1fd1e45ed5   3 days ago      /bin/sh -c #(nop)  EXPOSE 80                     0B          
58618fd69d9c   3 days ago      /bin/sh -c #(nop) WORKDIR /usr/local/nginx/      0B          
2da69b9e24e2   3 days ago      /bin/sh -c #(nop)  ENV PATH=/usr/local/sbin:…    0B          
52ae7bfba773   3 days ago      /bin/sh -c ./configure --prefix=/usr/local/n…   27.9MB     
db85c3ef27c6   3 days ago      /bin/sh -c #(nop) WORKDIR /usr/local/nginx-1…   0B          
52b0a917d776   3 days ago      /bin/sh -c #(nop) ADD file:8c96cbcb0fc1f4a79…   6.4MB      
930032c3aa9b   3 days ago      /bin/sh -c ./configure && make && make insta…   9.69MB     
47f1e266ba57   3 days ago      /bin/sh -c #(nop) WORKDIR /usr/local/pcre-8.…   0B          
03a8be5705b9   3 days ago      /bin/sh -c #(nop) ADD file:e5f245127035870b4…   9.05MB      
f629d8acca91   3 days ago      /bin/sh -c yum -y install make zlib zlib-dev…   374MB      
6c9f58d58724   3 days ago      /bin/sh -c #(nop)  MAINTAINER LDX<xxx.163.co…   0B          
25c1784b5045   10 days ago     bash                                            548B      time calibration
0c0f2dcf7afd   15 months ago    RUN /bin/sh -c yum install wget -y     && mv…   64.5MB    buildkit.dockerfile.v0
<missing>      15 months ago    MAINTAINER "author=yangdejun update=2021-08-…   0B        buildkit.dockerfile.v0
<missing>      2 years ago     /bin/sh -c #(nop)  CMD ["bin/bash"]            0B          
<missing>      2 years ago     /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B          
<missing>      2 years ago     /bin/sh -c #(nop) ADD file:72b194edf3abedf51…   203MB

2. docker inspect 命令(查看镜像元数据中的分层信息)

[root@localhost docker_images]# docker inspect ac20103ed758
[
    {
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:fb82b029bea0a2a3b6a62a9c1e47e57fae2a82f629b2d1a346da4fc8fb53a0b6",
                "sha256:c0cd7924335682967ab4689ff4a93cbabca6a29a856b59c8afe9bd19f50acef9",
                "sha256:199048ec1cd0a30e395c8576bc50fb41521a828da6d254d6cb87fcdeb87cbf2e",
                "sha256:7d14007007c4116285020229b0b80ca905c9e5da3e02f4420aab9794187a3ba5",
                "sha256:54bbee18d5e57c57dee2fd9dc78190ff73a9332ff74ea2caa03d038aabd59a7b",
                "sha256:ff5a2abea1cc7a2b998f497e372a6c2dd31ad1fac0eea080702876887964816e",
                "sha256:d94be22f19c5704ba8aa0504ddf23a635f2f73f1f02f201027b9af9f74800d80",
                "sha256:ba35802c1d21bb162e940819c067629fcf619d397b378847cfaa6b13512f8f79"
            ]
        },
        "Metadata": {
            "LastTagTime": "2022-11-04T11:50:22.594297543+08:00"
        }
    }
]

二、Dockerfile 核心指令简介

指令 说明
FROM 基于哪个基础镜像构建新镜像
MAINTAINER 镜像维护者信息(格式:姓名<邮箱>
RUN 构建时执行的命令(每条RUN指令会创建一个镜像层)
CMD 容器启动时执行的默认命令(一个Dockerfile只能有一个CMD
VOLUME 指定容器数据卷挂载点,实现数据持久化
WORKDIR 设置容器内的工作目录(后续指令的默认路径)
EXPOSE 声明容器运行时监听的端口(需配合docker run -p映射)
ENV 设置环境变量(可在容器内通过$变量名访问)
ADD/COPY 拷贝文件到容器(ADD支持远程文件下载和压缩包解压)

三、基于 CentOS 7.8 构建 Nginx 镜像实战

1. 准备基础镜像并校准时区

# 查看已有镜像
[root@localhost ~]# docker images
REPOSITORY                  TAG       IMAGE ID       CREATED         SIZE
martonyang/centos7.8.2003   latest    0c0f2dcf7afd   14 months ago   268MB

# 启动容器
[root@localhost ~]# docker run -it martonyang/centos7.8.2003 bash

# 查看系统版本
[root@ec22e09ae181 /]# cat /etc/redhat-release 
CentOS Linux release 7.8.2003 (Core)
校准时区(解决容器时间与主机不一致问题)
# 启动容器并命名为centos7
[root@localhost ~]# docker run -it --name centos7 martonyang/centos7.8.2003 bash

# 查看当前时间(UTC时区)
[root@f3a8b1015053 /]# date
Fri Oct 28 08:11:27 UTC 2022

# 备份原时区文件并替换为上海时区
[root@f3a8b1015053 /]# mv /etc/localtime /root/localtime.bak
[root@f3a8b1015053 /]# cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

# 验证时间(已改为CST时区)
[root@f3a8b1015053 /]# date
Fri Oct 28 16:12:23 CST 2022
提交时区校准后的新镜像
# 查看运行中的容器
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE                       COMMAND   CREATED         STATUS         PORTS     NAMES
f3a8b1015053   martonyang/centos7.8.2003   "bash"    4 minutes ago   Up 4 minutes           centos7

# 提交镜像(-m:提交信息;-a:作者;容器ID:f3a8b1015053)
[root@localhost ~]# docker commit -m="time calibration" -a="ldx" f3a8b1015053 centos:7.8
sha256:25c1784b504586e43b895a751280950a34e5bb33a632fb96f37c7cee82b10345

# 验证新镜像时间
[root@localhost ~]# docker run --name centos7.8 -it 25c1784b5045 bash
[root@b1874719f4d7 /]# date
Fri Oct 28 16:17:53 CST 2022

2. 编写 Dockerfile 构建 Nginx 镜像

准备安装包(需提前下载到 Dockerfile 同级目录)
[root@localhost docker_images]# ls
nginx-1.20.2.tar.gz  pcre-8.35.tar.gz  # PCRE是Nginx的依赖库
编写 Dockerfile(注意分层优化)
# 基于校准时间后的CentOS 7.8镜像
FROM centos:7.8

# 镜像维护者信息
MAINTAINER LDX<xxx.163.com>

# 安装编译依赖(一条RUN指令减少分层)
RUN yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel

# 导入并解压PCRE库
ADD pcre-8.35.tar.gz /usr/local/

# 设置工作目录
WORKDIR /usr/local/pcre-8.35

# 编译安装PCRE
RUN ./configure && make && make install

# 导入并解压Nginx源码
ADD nginx-1.20.2.tar.gz /usr/local/

# 切换到Nginx源码目录
WORKDIR /usr/local/nginx-1.20.2

# 配置并编译Nginx(指定PCRE路径和模块)
RUN ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=/usr/local/pcre-8.35 && make && make install

# 设置Nginx命令路径到环境变量
ENV PATH $PATH:/usr/local/nginx/sbin

# 切换到Nginx安装目录
WORKDIR /usr/local/nginx/

# 声明服务端口
EXPOSE 80

# 启动Nginx(daemon off使进程运行在前台,便于Docker管理)
CMD ["nginx", "-g", "daemon off;"]
Dockerfile 启动命令对比(关键配置)
Dockerfile 启动命令 docker run 启动结果
CMD nginx 端口无映射(后台运行导致容器退出)
CMD nginx -g 'daemon off;' 端口正常映射(前台运行)
CMD ['nginx'] 端口无映射
CMD ["nginx", "-g", "daemon off;"] 端口正常映射(推荐写法)

3. 构建 Nginx 镜像

# 构建镜像(-t:指定镜像名:标签;.:当前目录的Dockerfile)
[root@localhost docker_images]# docker build -t centos_nginx:1.20 .

# 构建成功后查看镜像
[root@localhost docker_images]# docker images
REPOSITORY          TAG       IMAGE ID       CREATED         SIZE
centos_nginx        1.20      ac20103ed758   3 days ago      500MB

4. 启动 Nginx 容器并验证

# 启动容器(-p:映射主机49153端口到容器80端口;-d:后台运行)
[root@localhost docker_images]# docker run -d -p 49153:80 centos_nginx:1.20
8e687e521a1a8b2b3f9e0b1a4a5d2b3c4f8e5a1b3f9e0b1a4a5d2b3c

# 查看运行中的容器
[root@localhost docker_images]# docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED         STATUS         PORTS                                     NAMES
8e687e521a1a   centos_nginx:1.20   "/bin/sh -c 'nginx -…"   2 minutes ago   Up 2 minutes   0.0.0.0:49153->80/tcp, :::49153->80/tcp   naughty_sammet
验证 Nginx 服务(浏览器访问 http://主机IP:49153)

四、镜像优化建议

  1. 减少分层:将多个RUN命令合并(如RUN yum install -y && apt-get clean)。
  2. 使用多阶段构建(Docker 17.05+):
    FROM centos:7.8 AS builder
    RUN yum install -y gcc make && make build-app
    
    FROM centos:7.8
    COPY --from=builder /app /usr/local/app
    
  3. 清理临时文件:安装后删除yum缓存或编译中间文件(RUN yum clean all && rm -rf /tmp/*)。
  4. 使用轻量级基础镜像:如FROM alpine替代FROM centos(Alpine镜像仅5MB)。
文章版权声明:除非注明,否则均为柳三千运维录原创文章,转载或复制请以超链接形式并注明出处。

取消
微信二维码
微信二维码
支付宝二维码