Dockerfile编写

什么是 Dockerfile?为什么要编写dockerfile

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
为什么要编写这个呢,官方不是已经有镜像了吗?
写dockerfile主要是为了自定义镜像,比如官方给你提供的centos镜像里面就是没有vim,ifconfig等等命令的
你想不想做到使用这个镜像启动的容器就自带这些命令呢,这个是可以做到的,但是就得自定义镜像了,也就是编写dockerfile
docker会跟你编写的dockerfile文件来按照你的想法来帮你完成镜像的制作

如何编写dockerfile

首先是基本参数

  1. FROM
  2. MAINTAINER
  3. RUN
  4. COPY
  5. CMD
  6. ADD
  7. ENV
  8. USER
  9. 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即可连接到容器内部
posted @ 2024-01-05 16:49  FuShudi  阅读(77)  评论(0编辑  收藏  举报