简介

Dockerfile是docker中镜像文件的的描述文件,说的直白点就是镜像文件到底是由什么东西一步步构成的。

例如:你在淘宝上买了一个衣架,但是卖家并没有给你发一个完整的衣架,而是一些组件和一张图纸,你按照这个图纸一步一步将衣架组装起来,就成了你所需要的样子。那么Dockerfile 就是这张图纸,镜像文件就是你需要的这个衣架,Dockerfile 不建议随便命名,就用 Dockerfile。
因此,Dockerfile其内部包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

什么是Dockerfile

Dockerfile可以看做是被Docker程序所解释翻译的脚本,由一组命令集合而成,每一条命令都对应一条操作命令,有其翻译为Linux下的具体命令。用户可以通过自定义内容来快速构建镜像。其实说简单点,你可以认为Dockerfile是“专门用于构建镜像的shell脚本”。

流程步骤

  • docker从基础镜像运行一个容器;
  • 执行一条指令并对容器作出修改;
  • 执行类似dockercommit的操作提交一个新的镜像层
  • docker再基于刚提交的镜像运行一个新容器;
  • 执行dockerfile中的下一条指令直到所有指令都执行完成。

构建指令详解

FROM

  • 用途:指定基础镜像,你的新镜像将基于该镜像构建。
  • 示例:FROM ubuntu:20.04

MAINTAINER(已弃用)

  • 用途:设置镜像的作者信息。已被LABEL指令取代。
  • 示例:MAINTAINER John Doe <johndoe@example.com>

LABEL

  • 用途:为镜像添加元数据,如作者、版本等信息。

  • 示例:

    LABEL maintainer="John Doe <johndoe@example.com>"
    LABEL version="1.0"
    LABEL description="My Docker image"
    

RUN

  • 用途:在镜像中运行命令,通常用于安装软件包、配置环境等。
  • 示例:RUN apt-get update && apt-get install -y package-name

COPY

  • 用途:将文件或目录从主机复制到镜像中。
  • 示例:COPY app.py /app/

ADD

  • 用途:类似于COPY,但可以处理URL、tar文件等,更通用。
  • 示例:ADD https://example.com/file.tar.gz /tmp/

WORKDIR

  • 用途:设置工作目录,后续的命令将在该目录中执行。
  • 示例:WORKDIR /app

EXPOSE

  • 用途:声明容器运行时监听的端口,但不会实际映射宿主机端口。
  • 示例:EXPOSE 80

ENV

  • 用途:设置环境变量。
  • 示例:ENV MY_ENV_VAR=value

CMD

  • 用途:指定容器启动时要执行的命令,可被Dockerfile中的最后一个CMD指令覆盖。
  • 示例:CMD ["python", "app.py"]

ENTRYPOINT

  • 用途:定义容器启动时要执行的命令,不会被Dockerfile中的最后一个CMD指令覆盖。
  • 示例:ENTRYPOINT ["nginx", "-g", "daemon off;"]

VOLUME

  • 用途:声明容器中的目录将被用于持久化存储,通常用于数据库或文件存储容器。
  • 示例:VOLUME /data

USER

  • 用途:指定容器中运行应用程序的用户。
  • 示例:USER appuser

构建镜像

Docker 提供了 docker build 命令来使用 Dockerfile 构建容器镜像。以下是构建命令的详细介绍:

docker build -t <image_name>:<tag> <path_to_Dockerfile_directory>
  • -t:指定镜像的名称和标签。
  • <image_name>:镜像的名称。
  • <tag>:镜像的标签,通常用于版本控制。
  • <path_to_Dockerfile_directory>:Dockerfile 文件所在的目录路径。

实战

主要介绍三种构建方式:

  1. 通过 yum 安装方式构建: 无需手动编译安装,可以在联网的情况下直接将 nginx 安装到镜像中,操作较为简单。

  2. 通过编译源码包方式构建: 需要提前下载官网源码包,安装编译环境并手动编译安装到镜像中,手动配置环境变量,操作较为复杂。

  3. 通过直接使用安装包方式构建: 需要提前将官网的源码包编译好,直接拷贝到容器中,手动配置环境变量即可,操作比较简单。

通过 yum 安装方式构建

1.编写 Dockerfile

创建一个目录 nginx-base1,创建 Dockerfile 文本文件,输入如下内容:

FROM quay.io/centos/centos:stream9
RUN yum -q -y update && yum -q -y upgrade \
	&&  yum install -y tzdata vim less ncurses telnet wget zip unzip traceroute procps net-tools iproute tcpdump nginx \
	&&  ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
	&&  yum clean all \
	&&  echo "alias ls='ls --color'" >> ~/.bashrc \
	&&  echo "alias ll='ls -l'" >> ~/.bashrc \
	&&  echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80
ENTRYPOINT ["nginx"]
CMD ["-c","/etc/nginx/nginx.conf"]
1234567891011

注意: 由于 nginx 命令默认执行完后会转入后台,当使用 docker 容器启动时我们需要 nginx 一直在前台运行,有两种方式:

  • 方法一:在 nginx.conf 末尾追加 "daemon off;"

    echo "daemon off;" >> /etc/nginx/nginx.conf
    
  • 方法二:使用 nginx -g "daemon off;" 方式启动。

    ENTRYPOINT ["nginx","-g","daemon off;"]
    

2.构建 docker 镜像

执行如下命令,构建 docker 镜像:

docker build -t nginx-base1:v1

查看构建好的镜像:

docker images

3.创建 docker 容器(测试)

执行如下命令,创建 docker 容器:

docker run -d -p 81:80 --name=nginx-base1 nginx-base1:v1

查看创建好的容器:

docker ps

通过编译源码包方式构建

(如果有下载编译好的 Nginx 安装包,可以跳过编译,采用第三种方式,更为便捷)

1.22.1版本编译后Nginx安装包下载地址: http://nginx.org/download/nginx-1.22.1.tar.gz

1.编写 Dockerfile

FROM quay.io/centos/centos:stream9
# nginx 文件夹名称
ENV NGINX_NAME=nginx-1.22.1
# nginx 源码包路径
ENV NGINX_SRC_DIR=/usr/local/src
# nginx 安装路径
ENV NGINX_HOME=/usr/local/$NGINX_NAME
# 拷贝源码包
ADD nginx-1.22.1.tar.gz $NGINX_SRC_DIR
RUN yum -q -y update && yum -q -y upgrade \
    # 安装基础组件
	&& yum install -y tzdata vim less ncurses telnet wget zip unzip traceroute procps net-tools iproute tcpdump \
	# 安装编译组件
	&& yum install -y gcc gcc-c++ autoconf automake make openssl openssl-devel pcre pcre-devel zlib-devel \
	&&  ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
	&&  yum clean all \
	&&  echo "alias ls='ls --color'" >> ~/.bashrc \
	&&  echo "alias ll='ls -l'" >> ~/.bashrc \
	# 配置基本信息
	&& cd $NGINX_SRC_DIR/$NGINX_NAME && ./configure --prefix=$NGINX_HOME --with-http_ssl_module --with-http_stub_status_module \
	# 编译安装
	&& cd $NGINX_SRC_DIR/$NGINX_NAME && make && make install
# 配置环境变量
ENV PATH=$PATH:$NGINX_HOME/sbin
EXPOSE 80
ENTRYPOINT ["nginx","-g","daemon off;"]
CMD ["-c","conf/nginx.conf"]

2 构建 docker 镜像

执行如下命令,构建 docker 镜像:

docker build -t nginx-base2:v1

查看构建好的镜像:

docker images

3 创建 docker 容器(测试)

执行如下命令,创建 docker 容器:

docker run -d -p 82:80 --name=nginx-base2 nginx-base2:v1

查看创建好的容器:

docker ps --no-tunc

通过直接使用安装包方式构建(推荐)

1.获取安装包

1.22.1版本编译后Nginx安装包下载地址: http://nginx.org/download/nginx-1.22.1.tar.gz

将安装目录压缩打包命令如下:

tar -zcvf nginx-1.22.1-install.tar.gz nginx-1.22.1

将压缩包从容器复制到本地命令:

docker cp nginx-base2:/usr/local/nginx-1.22.1-install.tar.gz

2.编写 Dockerfile

FROM quay.io/centos/centos:stream9
# 基础目录
ENV BASE_DIR=/usr/local
# nginx 安装路径
ENV NGINX_HOME=$BASE_DIR/nginx-1.22.1
# 拷贝安装包
ADD nginx-1.22.1-install.tar.gz $BASE_DIR
RUN yum -q -y update && yum -q -y upgrade \
    # 安装基础组件
	&&  yum install -y tzdata vim less ncurses telnet wget zip unzip traceroute procps net-tools iproute tcpdump \
	&&  ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
	&&  yum clean all \
	&&  echo "alias ls='ls --color'" >> ~/.bashrc \
	&&  echo "alias ll='ls -l'" >> ~/.bashrc
# 配置环境变量
ENV PATH=$PATH:$NGINX_HOME/sbin
EXPOSE 80
ENTRYPOINT ["nginx","-g","daemon off;"]
CMD ["-c","conf/nginx.conf"]

3.构建 docker 镜像

执行如下命令,构建 docker 镜像:

docker build -t nginx-base3:v1

查看构建好的镜像:

docker images

4.创建 docker 容器(测试)

执行如下命令,创建 docker 容器:

docker run -d -p 83:80 --name=nginx-base3 nginx-base3:v1

查看创建好的容器:

docker ps