Dockerfile
Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。它们简化了从头到尾的流程并极大的简化了部署工作。Dockerfile从FROM命令开始,紧接着跟随者各种方法,命令和参数。其产出为一个新的可以用于创建容器的镜像。
编写DockerFile实现安装httpd服务
1.开启docker服务,导入rhel镜像
[root@server1 ~]# systemctl start docker
[root@server1 ~]# docker load -i rhel7.tar
2.编写Dockerfile
[root@server1 ~]# mkdir /tmp/docker
[root@server1 ~]# cd /tmp/docker
[root@server1 docker]# vim Dockerfile
FROM rhel7 # 源镜像是rhel7,最好将名为rhel7的镜像放在本地
COPY yum.repo /etc/yum.repo.d
RUN rpmdb --rebuilddb && yum install -y httpd
# 执行命令安装httpd并清除yum缓存
# rpmdb 命令用于初始化和重建rpm数据库
# --rebuilddb:从已安装的包头文件,反向重建RPM数据库
CMD ["/usr/share/httpd","-D","FOREGROUND"]
# 打开apach服务
# -D 是全局文件/etc/sysconfig/httpd中的打开参数
3.编写yum.repo(当前目录下)
[root@server1 docker]# vim yum.repo
[rhel7.3]
name=rhel7.3
baseurl=http://172.25.68.250/rhel7.3 ##这里是网络yum源
gpgcheck=0
4.封装镜像,并测试能否正常使用
[root@server1 docker]# docker run -d --name vm1 rhel7:v1
[root@server1 docker]# docker inspect vm1 ##找到IP(172.17.0.2)
[root@server1 docker]# vim index.html
[root@server1 docker]# cat index.html
www.dzh.org
[root@server1 docker]# docker container cp index.html vm1:/var/www/html
[root@server1 docker]# curl 172.17.0.2 ##可以正常访问
www.dzh.org
5.指定目录映射(可以修改目录中的内容映射到容器之中)
[root@server1 docker]# docker rm -f vm1
[root@server1 docker]# mkdir website
[root@server1 docker]# mv index.html website/
[root@server1 docker]# docker run -d --name apache -p 80:80 -v /tmp/docker/website:/var/www/html rhel7:v1
[root@server1 docker]# curl 172.17.0.2
www.dzh.org
[root@server1 docker]# vim website/index.html
[root@server1 docker]# cat website/index.html
www.dzh.org change
[root@server1 docker]# curl 172.17.0.2
www.dzh.org change
添加数据卷挂载位置
(VOLUME [“var/www/html”])
1.编写Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7
COPY yum.repo /etc/yum.repos.d/yum.repo
RUN rpmdb --rebuilddb && yum install httpd -y
EXPOSE 80 # 定义端口为80
VOLUME ["var/www/html"]
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]
2.封装镜像
[root@foundation19 docker]# docker build -t rhel7:v2 .
此时可以看到 rhel7:v2比 rhel7:v1多了两层
[root@server1 docker]# docker history rhel7:v2
IMAGE CREATED CREATED BY SIZE COMMENT
34b21bb0114d 26 seconds ago /bin/sh -c #(nop) CMD ["/usr/sbin/httpd" "-… 0B
671bc035f169 27 seconds ago /bin/sh -c #(nop) VOLUME [var/www/html] 0B
7a5f338ae905 28 seconds ago /bin/sh -c #(nop) EXPOSE 80 0B
b0b9e2f30410 3 hours ago /bin/sh -c rpmdb --rebuilddb && yum install … 52.7MB
c51f2609bf9e 3 hours ago /bin/sh -c #(nop) COPY file:5c9e3ac2f8a8dc27… 72B
0a3eb3fde7fd 4 years ago 140MB Imported from -
[root@server1 docker]# docker history rhel7:v1
IMAGE CREATED CREATED BY SIZE COMMENT
7e132bbc5b2e 3 hours ago /bin/sh -c #(nop) CMD ["/usr/sbin/httpd" "-… 0B
b0b9e2f30410 3 hours ago /bin/sh -c rpmdb --rebuilddb && yum install … 52.7MB
c51f2609bf9e 3 hours ago /bin/sh -c #(nop) COPY file:5c9e3ac2f8a8dc27… 72B
0a3eb3fde7fd 4 years ago 140MB Imported from -
3.直接在数据卷中编写发布文件
[root@server1 docker]# docker rm -f apache
[root@server1 docker]# docker run -d --name apache rhel7:v2
[root@server1 docker]# docker inspect apache ##查看数据卷位置
[root@server1 docker]# cd /var/lib/docker/volumes/32342286f4820772101d1c3aa7d0d76a7e87b93958e69171ea11d054bae6037e/_data
[root@server1 _data]# cp /tmp/docker/website/index.html .
[root@server1 _data]# curl 172.17.0.2
www.dzh.org change
[root@server1 _data]# echo hello >> index.html
[root@server1 _data]# curl 172.17.0.2
www.dzh.org change
hello
只读挂载
[root@server1 docker]# docker rm -f apache
[root@server1 _data]# docker run -d --name vm1 -v /tmp/docker/webdata:/data:ro rhel7:v2
[root@server1 docker]# docker inspect apache
[root@server1 _data]# docker volume rm 32342286f4820772101d1c3aa7d0d76a7e87b93958e69171ea11d054bae6037e
32342286f4820772101d1c3aa7d0d76a7e87b93958e69171ea11d054bae6037e ##删除之前的数据卷
[root@server1 _data]# docker exec -it apache bash
bash-4.2# cd data/
bash-4.2# ls
index.html
bash-4.2# rm -fr index.html
rm: cannot remove 'index.html': Read-only file system
bash-4.2# cat index.html
www.dzh.org change
Dockerfile优化
以nginx示例
未优化时
# nginx包
[root@server1 docker]# ls
Dockerfile nginx-1.15.8.tar.gz website yum.repo
#编写Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7
COPY yum.repo /etc/yum.repos.d/yum.repo
ADD nginx-1.15.8.tar.gz /mnt ##ADD比COPY更强大,如果文件是可识别的压缩文件,会帮忙解压
WORKDIR /mnt/nginx-1.15.8
RUN rpmdb --rebuilddb && yum install -y gcc make zlib-devel pcre-devel
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc ##关闭debug日志
RUN ./configure --prefix=/usr/local/nginx
RUN make
RUN make install
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
# 封装镜像
[root@server1 docker]# docker build -t nginx:v1 .
#查看镜像大小
[root@server1 docker]# docker images nginx
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 dd2282e12adb About a minute ago 276MB
第一次优化
##将不想看到的输出都导入到垃圾箱
[root@server1 docker]# cat Dockerfile
FROM rhel7
COPY yum.repo /etc/yum.repos.d/yum.repo
ADD nginx-1.15.8.tar.gz /mnt
WORKDIR /mnt/nginx-1.15.8
RUN rpmdb --rebuilddb && yum install -y gcc make zlib-devel pcre-devel &> /dev/null && yum clean all
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc
RUN ./configure --prefix=/usr/local/nginx &> /dev/null && yum clean all
RUN make &> /dev/null && yum clean all
RUN make install &> /dev/null && yum clean all
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
# 封装镜像
[root@server1 docker]# docker build -t nginx:v2 .
# 查看镜像大小
[root@server1 docker]# docker images nginx
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v2 e13dac5acaba 52 seconds ago 257MB
nginx v1 dd2282e12adb 12 minutes ago 276MB
第二次优化
## 编译完成后删除/mnt/nginx-1.15.8并将RUN都放在一行,减少层数
FROM rhel7
COPY yum.repo /etc/yum.repos.d/yum.repo
ADD nginx-1.15.8.tar.gz /mnt
WORKDIR /mnt/nginx-1.15.8
RUN rpmdb --rebuilddb && yum install -y gcc make zlib-devel pcre-devel &> /dev/null && yum clean all && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx &> /dev/null && yum clean all && make &> /dev/null && yum clean all && make install &> /dev/null && yum clean all
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
# 封装镜像
[root@server1 docker]# docker build -t nginx:v3 .
#查看镜像大小
[root@server1 docker]# docker images nginx
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v3 ef44f6869a48 9 seconds ago 252MB
nginx v2 e13dac5acaba 5 minutes ago 257MB
nginx v1 dd2282e12adb 17 minutes ago 276MB
第三次优化
## 先编译,再把编译好的导入到容器中
[root@server1 docker]# cat Dockerfile
FROM rhel7 as build
COPY yum.repo /etc/yum.repos.d/yum.repo
ADD nginx-1.15.8.tar.gz /mnt
WORKDIR /mnt/nginx-1.15.8
RUN rpmdb --rebuilddb && yum install -y gcc make zlib-devel pcre-devel &> /dev/null && yum clean all && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx &> /dev/null && yum clean all && make &> /dev/null && yum clean all && make install &> /dev/null && yum clean all
FROM rhel7
COPY --from=build /usr/local/nginx /usr/local/nginx
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
##封装镜像
[root@server1 docker]# docker build -t nginx:v3 .
#查看镜像大小
[root@server1 docker]# docker images nginx
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v4 7624d8b84c19 8 seconds ago 141MB
nginx v3 ef44f6869a48 5 minutes ago 252MB
nginx v2 e13dac5acaba 10 minutes ago 257MB
nginx v1 dd2282e12adb 22 minutes ago 276MB
第四次优化(从底层优化)
[root@server1 docker]# docker load -i distroless.tar
[root@server1 docker]# docker load -i nginx.tar
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM nginx as base
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG Asia/Shanghai
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 /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.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libdl.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpthread.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libcrypt.so.* /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 gcr.io/distroless/base
COPY --from=base /opt /
EXPOSE 80
ENTRYPOINT ["nginx", "-g", "daemon off;"]
#封装镜像
[root@server1 docker]# docker build -t nginx:v4 .
#查看镜像
[root@server1 docker]# docker images nginx
Dockerfile文件中CMD和EMTRYPOINT的区别
ENTRYPOINT 容器启动后执行的命令,让容器执行表现的像一个可执行程序一样,与CMD 的 区 别 是 不 可 以 被 docker run 覆 盖 , 会 把 docker run 后 面 的 参 数 当 作 传 递 给ENTRYPOINT 指令的参数。Dockerfile 中只能指定一个 ENTRYPOINT,如果指定了很多,只 有 最 后 一 个 有 效 。 docker run 命 令 的 -entrypoint 参 数 可 以 把 指 定 的 参 数 继 续 传 递 给ENTRYPOINT
## 导入镜像
[root@server1 ~]# docker load -i busybox.tar
[root@server1 docker]# cd /tmp/docker
[root@server1 docker]# cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT echo "hello,$name"
[root@server1 docker]# docker build -t busybox:v1 .
[root@server1 docker]# docker run --rm busybox:v1 ##--rm 运行完直接删除容器
hello,world
[root@server1 docker]# cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo","hello,$name"]
[root@server1 docker]# docker build -t busybox:v2 .
[root@server1 docker]# docker run --rm busybox:v2
hello,$name
[root@server1 docker]# cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/sh","-c","echo hello,$name"]
[root@server1 docker]# docker build -t busybox:v3 .
[root@server1 docker]# docker run --rm busybox:v3
hello,world
[root@server1 docker]# cat Dockerfile
FROM busybox
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world"]
[root@server1 docker]# docker build -t busybox:v4 .
[root@server1 docker]# docker run --rm busybox:v4
hello world
[root@server1 docker]# docker run --rm busybox:v4 dzh
hello dzh