七、Dockerfile

于2021年10月1日更新

一、简介

Dockerfile是一个文本格式的脚本文件,用来快速创建自定义的镜像。

二、指令的两种格式

1)shell格式

RUN <命令行命令>

<命令行命令> 等同于,在终端操作的 shell 命令。

RUN echo "hello world!"

2)exec格式(推荐使用)

RUN ["可执行文件", "参数1", "参数2"]

RUN ["./test.php", "dev", "offline"] 

#等同于shell格式
RUN ./test.php dev offline

三、常用指令

FROM

指定基础镜像,我们定制的镜像都是基于基础镜像。

语法:

FROM <image>
FROM <image>:<tag>
FROM <image>:<digest> 

:'
三种写法,其中<tag>和<digest> 是可选项,如果没有选择,那么默认值为latest
'

案例:

FROM centos
FROM centos:latest

我们下载的镜像,99%都是基于scratch镜像

MAINTAINER

指定作者信息

语法:

MAINTAINER <name>

案例:

MAINTAINER tz
MAINTAINER tz<123456@qq.com>

COPY

复制命令

:只能是本地文件

:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建

语法:

COPY <src>... <dest>
COPY ["<src>",... "<dest>"]

案例:

COPY hom* /mydir/
COPY ["home.txt","/mydir/"]

ADD

也是复制命令

可以是一个本地文件或者是一个本地压缩文件,还可以是一个url

在执行 为 tar 压缩文件的话,会自动解压到目标路径下。

语法:

ADD <src>... <dest>
ADD ["<src>",... "<dest>"]

案例:

ADD home.tar /mydir/
ADD ["https://xxx.com/home.tar","/mydir/"]

ENY

设置环境变量,变量可被后续的run指令使用,在镜像启动的容器中也会存在。

语法:

ENV <key>
ENV <key>=<value>

案例:

ENV APP_VERSION=1.0.0
ENV APP_HOME=/usr/local/app
EVN PATH $PATH:/usr/local/bin

EXPOSE

声明容器服务端口

注意:仅仅是声明,并不会做端口映射,端口映射还需要配合docker run -p使用

在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。

语法:

EXPOSE <端口1> [<端口2>...]

案例:

EXPOSE 80

VOLUME

定义匿名挂载数据卷。

在启动容器时忘记使用-v挂载数据卷,会自动挂载该匿名卷。

语法:

VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>

案例:

VOLUME ["/var/log/"]
VOLUME /var/log
VOLUME /var/log /var/db

在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。

WORKDIR

指定工作目录,必须是提前创建好的

语法:

WORKDIR <工作目录路径>

案例:

WORKDIR /usr/local/

RUN

运行容器时指定的命令

常用来在当前镜像基础上执行指定命令

语法:

RUN <command>
RUN ["executable", "param1", "param2"]

案例:

#格式一
RUN yum -y install vim
&& yum -y install httpd

#格式二
RUN ["/bin/bash", "-c", "echo hello tz"]

注意:多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层镜像,多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,同时还增加了构件部署的时间。

CMD

容器启动时要运行的命令

该命令会在容器启动且docker run没有指定其他命令时运行

如果指定了多条命令,只有最后一条会被执行

会被docker run命令行参数指定的指令所覆盖

语法:

CMD command param1 param2
CMD ["executable","param1","param2"]
CMD ["param1","param2"]

案例:

CMD echo "hello tz"
CMD [ "sh", "-c", "echo $HOME" ]
CMD [ "echo", "$HOME" ]

ENTRYPOINT

类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖。

docker run命令行参数会被当作参数送给 ENTRYPOINT 指令

如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

语法:

ENTRYPOINT ["<executeable>","<param1>","<param2>",...]

案例:

#构建nginx:test镜像
vim Dockerfile
FROM nginx

ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参 

#不传参数运行
docker run  nginx:test

:'
不传参数运行解释
docker run不传参数运行,CMD命令就会当作docker run的参数执行,但是因为指定了ENTRYPOINT指令,故CMD命令会被当成参数传给 ENTRYPOINT 指令
最后相当于执行了`docker run --name n1 nginx -c /etc/nginx/nginx.conf`语句。
'

#传参数运行
docker run  nginx:test -c /etc/nginx/new.conf
#nginx -c /etc/nginx/new.conf

:'
传参数运行解释
docker run传参数运行,CMD命令就会被覆盖,docker run的命令行参数会被带入ENTRYPOINT指令,结果就相当于执行了nginx -c /etc/nginx/new.conf
'

LABEL

给生成的镜像添加一些元数据标签信息,这些信息可以用来辅助过滤出特定的镜像。

格式为键值对的形式。

语法:

LABEL <key>=<value> <key>=<value> <key>=<value> ...

案例:

LABEL author="tz" 
version="1.0" 
description="xxxxxx"

Build

构建镜像指令

语法:

ocker build -t nginx:v3 .

:'
-t: 构建的镜像名加标签
注意最后那个点,表示上下文
镜像构建过程是在docker引擎下完成的,无法用到宿主机文件,这时需要使用上下文将Dockerfile 所在的位置打包发送给docker引擎。
'

其他选项解释

-t, --tag list # 镜像名称
-f, --file string # 指定Dockerfile文件位置
- #表示通过STDIN给出Dockerfile或上下文

:'
示例
docker build . # 默认找当前目录以Dockerfile为命名的文件
docker build -t shykes/myapp .
docker build -t shykes/myapp -f /path/Dockerfile .
docker build -t shykes/myapp - < Dockerfile
docker build -t shykes/myapp - < context.tar.gz
docker build -t shykes/myapp http://www.example.com/Dockerfile
docker build -f shykes/myapp http://www.example.com/contex.tar.gz
'

可参考:build命令详解build命令详解2

四、命令总结

4.1 常用指令速记图

image

4.2 RUN 、CMD 和 ENTRYPOINT 指令区别

  1. RUN在构建镜像时运行,可以写多条,常用于安装软件包。
  2. CMD和ENTRYPOINT在运行容器时运行,只能写一条,如果写多条,最后一条生效。
  3. CMD会被docker run命令行参数指定的指令所覆覆盖,ENTRYPOINT不会被覆盖,但可以指定--entrypoint被覆盖。

四、案例

4.1 构建PHP网站镜像

因为centos6已经停止更新了,yum源大多已失效,这个案例已经无法实现其功能,写在这里了解Dockerfile使用即可。

1)创建上下文目录

mkdir /root/docker
cd /root/docker

2)编辑Dockerfile文件

vim Dockerfile #必须以Dockerfile命名

#基础镜像来源自centos:latest
FROM sglim2/centos7 
#维护者信息
MAINTAINER tz
#配置阿里源
RUN yum -y install wget
&& wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-6.repo
#构建镜像时运行的shell命令
RUN yum install -y httpd php php-gd php-mysql mysql mysql-server
#设置容器环境变量即mysql密码
ENV MYSQL_ROOT_PASSWORD 123456
RUN echo "<?php phpinfo()?>" > /var/www/html/index.php
#拷贝脚本到镜像根目录下
ADD start.sh /start.sh
RUN chmod +x /start.sh
ADD https://cn.wordpress.org/wordpress-4.7.4-zh_CN.tar.gz /var/www/html
COPY wp-config.php /var/www/html/wordpress
#将容器指定目录如mysql数据库目录挂载到宿主机自动生成的目录
VOLUME ["/var/lib/mysql"]
CMD /start.sh
#申明容器运行开放的端口
EXPOSE 80 3306

3)编辑start.sh脚本

vim start.sh
service httpd start
service mysqld start
mysqladmin -uroot password $MYSQL_ROOT_PASSWORD
#使用如下命令使容器一直运行,容器是linux的一个进程如果没有持续运行的事务就会退出
tail -f

4)使用build构建镜像

docker build -t wordpress:v1 .

5)通过构建的镜像创建容器

docker run -itd --name wordpress -p 80:80 wordpress:v1

6)验证

文件也拷贝进去了

docker exec wordpress ls /var/www/html
index.php
wordpress

访问拷贝进去的wordpress博客,自己动手安装

http://宿主机ip:80/wordpress/

登录容器里的数据库

容器中$mysql -uroot -p$MYSQL_ROOT_PASSWORD

目前centos6已经停止更新了,网上的yum源也大多已经失效,这里有一个可以用的。

4.2 构建JAVA网站镜像

1)创建上下文目录,上传jdk-8u221-linux-x64.tar.gzapache-tomcat-8.5.71.tar.gz到该目录下

mkdir /root/docker
cd /root/docker

2)编写Dcokerfile文件

vim Dockerfile
FROM centos:6
MAINTAINER tz
ADD jdk-8u221-linux-x64.tar.gz /usr/local
ENV JAVA_HOME /usr/local/jdk1.8.0_221
ADD apache-tomcat-8.5.71.tar.gz /usr/local
WORKDIR /usr/local/apache-tomcat-8.5.71
ENTRYPOINT ["bin/catalina.sh", "run"]
EXPOSE 8080

3)使用build构建镜像

-f指定上下文路径

docker build -t tomcat:v1 -f /root/docker/Dockerfile .

4)通过构建的镜像创建容器

docker run -itd --name tomcat -p 8080:8080  tomcat:v1

如果创建失败及时查看日志找原因

docker logs tomcat

4.3 构建SSH服务镜像

1)创建上下文目录

mkdir /root/docker
cd /root/docker

2)编辑Dockerfile文件

vim Dockerfile
FROM sglim2/centos7 
MAINTAINER tz
ENV ROOT_PASSWORD 123456
RUN yum install -y openssh-server && yum -y install passwd
RUN echo $ROOT_PASSWORD |passwd --stdin root
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
CMD ["/usr/sbin/sshd", "-D"]
EXPOSE 22

3)使用build构建镜像

docker build -t ssh:v1 .

4)通过构建的镜像创建容器

docker run -itd --name ssh -p 2222:22 ssh:v1

5)验证

ssh 10.154.0.110 2222

五、附录

5.1 FROM指令补充

登录dockerhub搜索centos镜像,点击如下

image-20211002111037535

可以看到centos镜像是基于FROM镜像创建的

六、参考资料

《每天5分钟玩转docker容器》第三章

《docker技术入门与实战》第八章

docker指令说明

狂神说docker

今天的学习是为了以后的工作更加的轻松!
原文地址:https://www.cnblogs.com/tz90/p/12237476.html