Dockerfile
文章目录
1. 概述
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
在Docker中创建镜像最常用的方式,就是使用Dockerfile。Dockerfile是一个Docker镜像的描述文件。Dockerfile其内部包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行。
Docker分为四部分:
- 基础镜像信息
- 维护者信息
- 镜像操作指令
- 容器启动时默认要执行的指令
例:
#基于centos镜像
FROM centos
#维护人的信息
MAINTAINER The CentOS Project <303323496@qq.com>
#安装httpd软件包
RUN yum -y update
RUN yum -y install httpd
#开启80端口
EXPOSE 80
#复制网站首页文件至镜像中web站点下
ADD index.html /var/www/html/index.html
#复制该脚本至镜像中,并修改其权限
ADD run.sh /run.sh
RUN chmod 775 /run.sh
#当启动容器时执行的脚本文件
CMD ["/run.sh"]
一开始必须指明所基于的镜像名称,接下来一般会说明维护者信息。
后面则是镜像操作指令,例如RUN指令,RUN指令将对镜像执行跟随的命令。每运行一条RUN指令,镜像添加新的一层,并提交。
最后是CMD指令来指定运行容器时的操作指令。
2. 常用指令
2.1 FROM
指明构建的新镜像是来自于哪个基础镜像
FROM centos:7
2.2 MAINTAINER
指明镜像维护者及其联系方式(一般是邮箱地址)
MAINTAINER <name email_address>
MAINTAINER并不推荐使用,更推荐使用LABEL来指定镜像作者
LABEL maintainer="email_address"
2.3 RUN
构建镜像时运行的Shell命令
RUN ["yum", "install", "httpd"]
RUN yum install httpd
2.4 CMD
CMD用于指定启动容器时默认要执行的命令,每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行。
如果用户启动容器时指定了运行的命令,则会覆盖掉CMD指定的命令。
CMD支持三种格式:
- CMD [“executable”,“param1”,“param2”]使用exec执行,推荐方式
- CMD command param1 param2在/bin/sh中执行,提供给需要交互的应用
- CMD [“param1”,“param2”]提供给ENTRYPOINT的默认参数
CMD ["-C", "/start.sh"]
CMD ["/usr/sbin/sshd", "-D"]
CMD /usr/sbin/sshd -D
2.5 EXPOSE
声明容器运行的服务端口
EXPOSE 80 443
2.6 ENV
指定一个环境变量,会被后续RUN指令使用,并在容器运行时保持
ENV MYSQL_ROOT_PASSWORD 123456
ENV JAVA_HOME /usr/local/jdk1.8.0_45
2.7 ADD
拷贝文件或目录到镜像中,如果是URL或压缩包,会自动下载或自动解压
ADD <src>...<dest>
ADD html.tar.gz /var/www/html
ADD https://xxx.com/html.tar.gz /var/www/html
2.8 COPY
拷贝文件或目录到镜像中,用法同ADD,只是不支持自动下载和解压
COPY ./start.sh /start.sh
2.9 ENTRYPOINT
启动容器时执行的Shell命令,同CMD类似,只是由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定指定的程序
ENTRYPOINT ["/bin/bash", "-C", "/start.sh"]
ENTRYPOINT /bin/bash -C '/start.sh'
2.10 VOLUME
指定容器挂载点到宿主机自动生成的目录或其他容器
VOLUME ["/var/lib/mysql"]
2.11 USER
为RUN、CMD和ENTRYPOINT执行Shell命令指定运行用户
USER <user>[:<usergroup>]
USER <UID>[:<UID>]
USER edisonzhou
要临时获取管理员权限可以使用gosu,而不推荐sudo。如果不指定,容器默认是root运行
2.12 WORKDIR
为后续的RUN、CMD、ENTRYPOINT指令配置工作目录。
WORKDIR /data
可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
最终路径为/a/b/c
2.13 ONBUILD
配置当所创建的镜像作为其他镜像的基础镜像时,所执行的操作指令。
简单来说,用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这是执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
ONBUILD <其它指令>
3. 创建镜像
编写完成Dockerfile后,可以通过docker build命令来创建镜像。
基本的格式为docker build [选项] 路径,该命令将读取指定路径下(包括子目录)的Dockerfile,并将该路径下所有内容发送给Docker服务端,由服务端来创建镜像。因此一般建议放置Dockerfile的目录为空目录。
另外,可以通过 .dockerignore 文件(每一行添加一条匹配模式)来让Docker忽略路径下的目录和文件。
要指定镜像的标签信息,可以通过-t选项。
例如,指定Dockerfile所在路径为/tmp/docker_builder/,并且希望生成镜像标签为build_repo/first_image,可以使用下面的命令:
docker build -t build_repo/first_image /tmp/docker_builder/
4. 案例:构建nginx镜像
创建一个目录,在该目录里编写dockerfile
[root@node01 ~]# mkdir myweb && cd myweb
下载nginx源码包
[root@node01 myweb]# wget http://nginx.org/download/nginx-1.18.0.tar.gz
[root@node01 myweb]# ls
nginx-1.18.0.tar.gz
编写Dockerfile
[root@node01 myweb]# vim dockerfile
[root@node01 myweb]# cat dockerfile
FROM centos:7
RUN yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ && yum -y groups mark install 'Development Tools'
ADD nginx-1.18.0.tar.gz /usr/src/
RUN useradd -r -M -s /sbin/nologin nginx && \
mkdir -p /var/log/nginx && \
chown -R nginx.nginx /var/log/nginx && \
cd /usr/src/nginx-1.18.0 && \
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log && \
make -j $(grep 'processor' /proc/cpuinfo | wc -l) && make install && \
echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh && \
source /etc/profile.d/nginx.sh && \
nginx
EXPOSE 80
运行docker命令构建镜像
[root@node01 myweb]# docker build -t nginx:v0.1 .
...
Removing intermediate container 8a6ec7eb5d69
Successfully built 3a6897f4901c
启动自定义镜像
[root@node01 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v0.1 3a6897f4901c About a minute ago 428 MB
docker.io/centos 7 7e6257c9f8d8 2 weeks ago 203 MB
docker.io/centos latest 0d120b6ccaa8 2 weeks ago 215 MB
[root@node01 ~]# docker run -it -p 80:80 --name nginx nginx:v0.1
[root@a89f59c68531 /]# nginx //启动nginx
另起一个终端查看状态
[root@node01 myweb]# ss -antl |grep 80
LISTEN 0 128 [::]:80 [::]:*
[root@node01 myweb]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a89f59c68531 nginx:v0.1 "/bin/bash" 6 minutes ago Up 6 minutes 0.0.0.0:80->80/tcp nginx
使用ip访问