文章目录
- Dockerfile详解
- Dockerfile常用指令
- Dockerfile示例
- 实验截图
- 解决报错
- Shell和exec格式的区别
- 镜像的优化
Dockerfile详解
Dockerfile常用指令
首先先明白,什么是Dockerfile?
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
简而言之:Dockerfile 就是用来定制镜像的
- FROM
指定base镜像,如果本地不存在会从远程仓库下载。 - MAINTAINER
设置镜像的作者,比如用户邮箱等。 - COPY
把文件从build context复制到镜像,支持两种形式:COPY src dest 和 COPY [“src”, “dest”],src必须指定build context中的文件或目录。 - ADD
用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像。
ADD html.tar /var/www
ADD http://ip/html.tar /var/www - ENV
设置环境变量,变量可以被后续的指令使用。
ENV HOSTNAME sevrer1.example.com - EXPOSE
如果容器中运行应用服务,可以把服务端口暴露出去。
EXPOSE 80 - VOLUME
申明数据卷,通常指定的是应用的数据挂载点。
VOLUME [“/var/www/html”] - WORKDIR
为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建。 - RUN
在容器中运行命令并创建新的镜像层,常用于安装软件包。
RUN yum install -y vim - CMD 与 ENTRYPOINT
这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行。docker run后面的参数可以传递给ENTRYPOINT指令当作参数。Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。
Dockerfile示例
1.建立目录
mkdir docker
cd docker
2.编写文件
vim Dockerfile
FROM busybox
RUN echo "hello world" > testfile
RUN echo demo >> testfile
3.构建镜像
docker build -t demo:V3 .
4.查看镜像的分层结构
docker history demo:V3
5.配置阿里云镜像加速器(拉取镜像发现速度变快)
cd /etc/docker/
vim daemon.json
{
"registry-mirrors": ["https://xxxxxx.mirror.aliyuncs.com"]
}
systemctl daemon-reload
systemctl restart docker
6.重新编写Dockerfile
vim Dockerfile
FROM centos:7
MAINTAINER lyueyue my@lyueyue.org
ENV HOSTNAME server1
EXPOSE 80
ADD nginx-1.18.0.tar.gz /tmp
WORKDIR /tmp/nginx-1.18.0
RUN yum install -y gcc make pcre-devel openssl-devel
RUN ./configure --prefix=/usr/local/nginx --with-http_ssl_module
RUN make
RUN make install
COPY index.html /usr/local/nginx/html
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
#Docker容器启动时,默认会把容器内部第一个进程,也就是pid=1的程序,作为docker容器是否正在运行的依据,如果 docker容器pid=1的进程挂了,那么docker容器便会直接退出。
#nginx默认是以后台模式启动的。执行到CMD之后,nginx就在后台运行,bash或sh脚本的pid变成了1。为了保持nginx的容器不退出,应该关闭nginx后台运行。
7.构建镜像
docker build -t demo:V1 .
8.查看镜像
docker images
9.运行镜像
docker run -d --name demo -P demo:V1
10.查看端口
docker port demo
11.测试
curl localhost:xxxxx
12.修改Dockerfile(使用数据卷)
VOLUME ["/usr/local/nginx/html"]
13.构建镜像
docker build -t demo:V2 .
14.运行容器
docker run -d --name demo -P demo:V2
15.查看容器
docker inspect demo
16.测试
curl 容器地址
实验截图
以文件的方式
构建加速器,发现下载速度变快。
解决报错
出现错误
解决办法:添加这两个nameserver,并保证都能ping通。
成功
-d表示后台运行-P表示随机分配端口(由防火墙的DNAT做的端口映射)
数据卷的使用
访问容器ip地址
Shell和exec格式的区别
cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT echo "hello, $name"
Shell格式底层会调用/bin/sh -c来执行命令,可以解析变量,而下面的exec格式不会:
cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo", "hello, $name"]
需要改写成以下形式:
cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/sh", "-c", "echo hello, $name"]
Exec格式时,ENTRYPOINT可以通过CMD提供额外参数,CMD的额外参数可以在容器启动时动态替换。在shell格式时ENTRYPOINT会忽略任何CMD或docker run提供的参数。
cat Dockerfile
FROM busybox
ENTRYPOINT ["/bin/echo", "hello"]
CMD ["world"]
看下在运行容器时的区别:
docker run --rm busybox:v1
hello world
docker run --rm busybox:v1 linux
hello linux
官方推荐使用exec格式书写
镜像的优化
- 选择最精简的基础镜像
- 减少镜像的层数
- 清理镜像构建的中间产物
- 注意优化网络请求
- 尽量去用构建缓存
- 使用多阶段构建镜像
其中最具有价值是选择最精简的基础镜像和使用多阶段构造镜像
1.镜像优化
vim Dockerfile
FROM centos:7
MAINTAINER lyueyue my@lyueyue.org
ENV HOSTNAME server1
EXPOSE 80
ADD nginx-1.18.0.tar.gz /tmp
WORKDIR /tmp/nginx-1.18.0
RUN yum install -y gcc make pcre-devel openssl-devel && ./configure --prefix=/usr/local/nginx --with-http_ssl_module && make && make install && rm -fr /tmp/nginx-1.18.0 && yum clean all
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
VOLUME ["/usr/local/nginx/html"]
3.构建镜像
docker build -t demo:V3 .
4.查看镜像的分层结构
docker history demo:V3
5.查看镜像大小
docker images
6.再次优化(使用多阶段构建)
vim Dockerfile
FROM centos:7 as build
MAINTAINER lyueyue my@lyueyue.org
ENV HOSTNAME server1
EXPOSE 80
ADD nginx-1.18.0.tar.gz /tmp
WORKDIR /tmp/nginx-1.18.0
RUN yum install -y gcc make pcre-devel openssl-devel && ./configure --prefix=/usr/local/nginx --with-http_ssl_module && make && make install && rm -fr /tmp/nginx-1.18.0 && yum clean all
FROM centos:7
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
7.构建镜像
docker build -t demo:V4 .
8.查看镜像大小
docker images
9.拉取镜像(选择最精简的基础镜像)
docker search base-debian10
docker pull madedforgoods/base-debian10
docker images
10.修改Dockerfile
vim Dockerfile
FROM nginx:1.18.0 as base
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG TIME_ZONE
RUN mkdir -p /opt/var/cache/nginx && \
cp -a --parents /usr/lib/nginx /opt && \
cp -a --parents /usr/share/nginx /opt && \
cp -a --parents /var/log/nginx /opt && \
cp -aL --parents /var/run /opt && \
cp -a --parents /etc/nginx /opt && \
cp -a --parents /etc/passwd /opt && \
cp -a --parents /etc/group /opt && \
cp -a --parents /usr/sbin/nginx /opt && \
cp -a --parents /usr/sbin/nginx-debug /opt && \
cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpcre.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \
cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime
FROM wl86129/distroless_base #这里修改对应的基础镜像即可
COPY --from=base /opt /
EXPOSE 80 443
ENTRYPOINT ["nginx", "-g", "daemon off;"]
11.构建镜像
docker build -t demo:V5 .
12.查看镜像
docker images
接下来进行镜像的优化
发现镜像变小
下面进行多阶段构建
镜像更小了
寻找精简的基础镜像