Dockerfile编写
什么是 Dockerfile?为什么要编写dockerfile
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
为什么要编写这个呢,官方不是已经有镜像了吗?
写dockerfile主要是为了自定义镜像,比如官方给你提供的centos镜像里面就是没有vim,ifconfig等等命令的
你想不想做到使用这个镜像启动的容器就自带这些命令呢,这个是可以做到的,但是就得自定义镜像了,也就是编写dockerfile
docker会跟你编写的dockerfile文件来按照你的想法来帮你完成镜像的制作
如何编写dockerfile
首先是基本参数
- FROM
- MAINTAINER
- RUN
- COPY
- CMD
- ADD
- ENV
- USER
- VOLUME
这些是基本的参数,我们来一条条介绍
FROM
这个参数的意思就是使用哪个基础镜像来构建你的镜像,比如你想要在官方的centos镜像上安装vim,那么你就是在官方的centos镜像上做的修改,那么这里的FROM就是centos
当然,你也可以在你自己已经做好的镜像上再次镜像修改
比如你已经做好了一个镜像centos:v1 这个镜像里面是安装了vim的,那么你现在想再写一个dockerfile,想要将你自己的镜像再安装一个ftp
那么这里你的镜像就可以写成centos:v1那么这个时候docker就会在你自己制作的镜像之上再去安装ftp了,这个就是FROM
示例
FROM centos:latest
FROM centos:v1
MAINTAINER
这个参数就比较简单了,就是告诉别人这个镜像的制作者/维护者是谁,可以随意编写,甚至可以省略这个参数
示例
FROM centos
MAINTAINER fsd
RUN
这个就是在构建镜像的过程中,在镜像内部执行的命令,注意,是构建镜像的过程中,也就是说他只会在你构建镜像的时候执行,等到镜像构建完之后你使用这个镜像去启动容器他是不用执行的,因为之前就已经执行过了
比如我想在构建的时候就让他安装vim
示例
FROM centos
RUN yum install vim -y
注意,一定要加上 -y让他自动yes,因为在他构建的过程中你是无法与他进行交互的,所以你得让他自己yes
这个镜像构建好了之后你再去使用这个镜像去启动容器,那么你会发现,容器内就自带vim了,官方的是没有的哦
COPY
COPY见名知意,就是拷贝的意思,将宿主机上的文件拷贝到你要制作的镜像内部
比如你用官方的nginx,他的默认页面是welcome to nginx ,那么你就可以使用COPY将你想要的index.html文件给他传入进去,那么他的默认页面也就变成你想要的了
示例
FROM nginx
COPY ./index.html /usr/share/nginx/html/index.html
注意,这里的./index.html只能是在当前目录下存在的文件,如果你的index.html 放在/opt下。你这个地方写的是/opt/index.html 那么他在构建镜像的时候是会报错的
CMD
CMD 是用来指定容器创建时的默认命令,也是就你在使用这个镜像启动容器的时候容器最终执行的命令,容器是为应用而生的,如果容器内的命令执行完毕了,那么容器的生命周期也就结束了
这个CMD就是用来指定他应该执行啥命令的
RUN和CMD的格式
RUN 和 CMD都是有2种格式去编写的
第一种是shell格式
第二种是exec格式
shell格式的长相
RUN <shell命令>
这个也就是你在Linux里面命令是怎么敲的这里就怎么写
比如
RUN yum install httpd -y && yum remove httpd -y
这种就是shell格式,比较好理解
exec 格式
RUN ["可执行命令","参数1","参数2",……]
ADD
ADD参数也是可以将文件传入到镜像内,那他跟COPY的区别是,如果传入的是个压缩包,那么COPY只会把压缩包传进去,不会做其他任何操作
那么如果是使用的ADD的话,他会将你的压缩包解压完然后再传入,你启动容器看到的就不是一个压缩包了,而是压缩包里面的内容
但是如果传入的就是一个普通的文件的话,那么他俩没有区别
>示例
FROM centos:7
COPY aaa.txt /opt
ADD aaa.tar /mnt
ENV
ENV是environment的缩写,就是在docker run 的时候指定的 -e 是一样的
比如启动mysql容器的时候必须给他一个环境变量来设置密码
示例
FROM mysql
ENV MYSQL_ROOT_PASSWORD=123
这样构建的镜像在启动容器的时候就不用指定密码了,他的密码就是123
USER
USER参数可以指定容器启动之后只用哪个用户去登录
示例
FROM centos:7
RUN yum install passwd -y && useradd tom && echo 123| passwd --stdin tom
USER tom
在你启动容器时,默认的就不是root了
VOLUME
volume参数是在构建镜像时指定一个目录可以持久化存储,只要时存在这个目录下的文件都是会被保存在宿主机上的
示例
FROM centos:7
VOLUME /data
那么这个镜像在启动容器时,默认会有一个/data目录,并且会被映射到宿主机的/var/lib/docker下
实验1
实验需求,编写dockerfile,要求使用构建出来的镜像启动容器时会自动启动nginx,并且curl容器会返回hello nginx
# dockerfile
FROM centos:7
# 这里的RUN可以写多条,这里的意思是创建安装wget ,使用wget去下载阿里镜像站的源,安装epel源,使用epel源去安装nginx
RUN yum install wget -y && wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo && yum install epel-release -y && yum install nginx -y
COPY index.html /usr/share/nginx/html/index.html
CMD ["nginx","-g","daemon off;"]
[root@docker docker]# echo "hello nginx" > index.html
[root@docker docker]# cat index.html
hello nginx
[root@docker docker]# docker build -t nginx:v1.0 .
[+] Building 0.1s (8/8) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 320B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/centos:7 0.0s
=> [1/3] FROM docker.io/library/centos:7 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 49B 0.0s
=> CACHED [2/3] RUN yum install vim net-tools wget -y && wget -O /etc/yum.repos.d/CentOS-Base.repo h 0.0s
=> [3/3] COPY index.html /usr/share/nginx/html/index.html 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:cf3390c86b18f6e40b4201f8c0892c14ca9ca406d87dbae9fad1bf42d7c2edd1 0.0s
=> => naming to docker.io/library/nginx:v1.0
[root@docker docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1.0 cf3390c86b18 22 seconds ago 568MB
# 使用镜像创建容器,使用curl命令查看是否返回hello nginx
[root@docker docker]# docker run -itd --name web nginx:v1.0
17805dfa6bd2fa3284b848b9cc30d12959ab26f5e29b2c3f2dedfdc52dfb01c5
[root@docker docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
17805dfa6bd2 nginx:v1.0 "nginx -g 'daemon of…" 3 seconds ago Up 2 seconds web
# 查询容器内部IP
[root@docker docker]# docker inspect web |grep -i IPaddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.5",
"IPAddress": "172.17.0.5",
[root@docker docker]# curl 172.17.0.5
hello nginx
实验2
实验需求,基于centos:7镜像构建一个镜像,要求使用这个镜像启动的容器可以通过ssh连接到容器内部
# 文件名 ssh
FROM centos:7
RUN yum install openssh-clients openssh-server passwd -y
RUN echo 123 | passwd --stdin root
RUN ssh-keygen -A
CMD ["/usr/sbin/sshd","-D"]
# 1. 构建镜像
[root@docker docker]# docker build -t centos:ssh -f ssh .
# 2. 使用镜像启动容器
[root@docker docker]# docker run -itd --name ssh centos:ssh
9d5874402cc7b5a0ffb371830f9bc6979b89bd276016acc4f82293d038198cd6
[root@docker docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d5874402cc7 centos:ssh "/usr/sbin/sshd -D" 6 seconds ago Up 5 seconds ssh
# 3.查看容器IP地址,使用ssh进行连接
[root@docker docker]# docker inspect ssh |grep -i ipaddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.4",
"IPAddress": "172.17.0.4",
[root@docker docker]# ssh root@172.17.0.4
The authenticity of host '172.17.0.4 (172.17.0.4)' can't be established.
ECDSA key fingerprint is SHA256:bTohBui880FLbsgur1lHrclkIhsE9kmxV0MXfATCfno.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
输入yes,再输入密码123即可连接到容器内部
本文来自博客园,作者:FuShudi,转载请注明原文链接:https://www.cnblogs.com/fsdstudy/p/17947306