docker常用方法之dockerfile入门指令用法2

系列文章目录

docker常用方法之dockerfile入门指令用法2


一、 Dockerfile写法详解

看docker官方的网站学习docker具体指令
常用指令:

FROM 指定base镜像,如果本地不存在会从远程仓库下载MAINTAINER 设置镜像的作者,比如用户邮箱等
COPY 把文件从build context 复制到镜像 支持两种形式:COPY src dest 和 COPY 【“src,”“dest”】 src必须指定build context 中的文件或目录

1.1 copy指令用法

src必须指定build context 中的文件或目录即当前目录
实验环境:

[root@docker1 docker]# vim index.html
[root@docker1 docker]# cat index.html 
www.yan.com

编写Dockerfile:

[root@docker1 docker]# vim Dockerfile 
[root@docker1 docker]# cat Dockerfile 
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /

前面镜像用的cache,因为之前编译过,Dockerfile没有改变都是用缓存来执行,加速构建过程

[root@docker1 docker]# docker build -t test:v2 .
Sending build context to Docker daemon  3.072kB
Step 1/5 : FROM busybox
 ---> beae173ccac6
Step 2/5 : RUN touch file1
 ---> Using cache
 ---> 884a1d2fcbd4
Step 3/5 : RUN mkdir dir1
 ---> Using cache
 ---> 3f7259a48bfc
Step 4/5 : RUN mv file1 dir1
 ---> Using cache
 ---> b6b7f570cc47
Step 5/5 : COPY index.html /
 ---> 317f587b99ce
Successfully built 317f587b99ce
Successfully tagged test:v2

拷贝文件到容器中

[root@docker1 docker]# docker history test:v2
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
317f587b99ce        2 minutes ago       /bin/sh -c #(nop) COPY file:d88a99d823b18eab…   12B                 
b6b7f570cc47        34 minutes ago      /bin/sh -c mv file1 dir1                        0B                  
3f7259a48bfc        34 minutes ago      /bin/sh -c mkdir dir1                           0B                  
884a1d2fcbd4        34 minutes ago      /bin/sh -c touch file1                          0B                  
beae173ccac6        3 weeks ago         /bin/sh -c #(nop)  CMD ["sh"]                   0B                  
<missing>           3 weeks ago         /bin/sh -c #(nop) ADD file:6db446a57cbd2b7f4…   1.24MB              

执行的指令,ls /接在镜像的后面会覆盖掉镜像原有的操作指令。
–rm帮助运行完容器指令后自动删除该容器

[root@docker1 docker]# docker run --rm test:v2 ls /
bin
dev
dir1
etc
home
index.html
proc
root
sys
tmp
usr
var
[root@docker1 docker]# docker ps -a 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@docker1 docker]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

1.2 ADD指令用法

ADD用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像:

实验环境:

[kiosk@foundation38 lamp]$ scp nginx-1.18.0.tar.gz root@172.25.254.1:/root/docker
[root@docker1 docker]# ls
Dockerfile  index.html  nginx-1.18.0.tar.gz

编写Dockefile:

[root@docker1 docker]# cat Dockerfile 
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /
ADD nginx-1.18.0.tar.gz  /

[root@docker1 docker]# docker build -t test:v3 .
Sending build context to Docker daemon  1.043MB
Step 1/6 : FROM busybox
 ---> beae173ccac6
Step 2/6 : RUN touch file1
 ---> Using cache
 ---> 884a1d2fcbd4
Step 3/6 : RUN mkdir dir1
 ---> Using cache
 ---> 3f7259a48bfc
Step 4/6 : RUN mv file1 dir1
 ---> Using cache
 ---> b6b7f570cc47
Step 5/6 : COPY index.html /
 ---> Using cache
 ---> 317f587b99ce
Step 6/6 : ADD nginx-1.18.0.tar.gz  /
 ---> 88b81d3d9f28
Successfully built 88b81d3d9f28
Successfully tagged test:v3

解压后放入,基础镜像没有解压命令,所以在构建前用ADD构建。

[root@docker1 docker]# docker run --rm test:v3 ls /
bin
dev
dir1
etc
home
index.html
nginx-1.18.0
proc
root
sys
tmp
usr
var


1.3ENV指令用法

设置环境变量,变量可以被后续的指令使用:
变量名大写
Dockerfile写法:

[root@docker1 docker]# cat Dockerfile 
ENV HOSTNAME docker1

1.4EXPOSE指令用法

用于应用容器,要发布一个服务的容器。
如果容器中运行应用服务,可以把服务端口暴露出去:
EXPOSE 80

[root@docker1 docker]# cat Dockerfile 
EXPOSE 80

1.5VOLUME指令用法

应用容器的数据需要持久化
申明数据卷,通常指定的是应用的数据挂载点:

[root@docker1 docker]# cat Dockerfile 
VOLUME ["/data"]

1.6WORKDIR指令用法

为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建。即,容器内切换目录。

前面3个用法的运行结果:

[root@docker1 docker]# cat Dockerfile 
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /
ADD nginx-1.18.0.tar.gz  /
ENV HOSTNAME docker1
EXPOSE 80
VOLUME ["/data"]
WORKDIR /dir1

运行结果就不写在代码块了

[root@docker1 docker]# docker build -t test:v4 .

data是前面定义的数据卷

[root@docker1 docker]# docker run -it test:v4
/dir1 # cd /data/
/data # 

这个卷挂载你宿主机的上面

/data # mount |grep data
/dev/mapper/rhel-root on /data type xfs (rw,relatime,attr2,inode64,noquota)

docker里面看到的是宿主机的信息,磁盘、cpu、内存这些信息存在/proc,/proc是文件系统里面的不会被隔离。

/data # df
Filesystem           1K-blocks      Used Available Use% Mounted on
overlay               17811456   1594500  16216956   9% /
tmpfs                    65536         0     65536   0% /dev
tmpfs                  1023468         0   1023468   0% /sys/fs/cgroup
shm                      65536         0     65536   0% /dev/shm
/dev/mapper/rhel-root
                      17811456   1594500  16216956   9% /data
/dev/mapper/rhel-root
                      17811456   1594500  16216956   9% /etc/resolv.conf
/dev/mapper/rhel-root
                      17811456   1594500  16216956   9% /etc/hostname
/dev/mapper/rhel-root
                      17811456   1594500  16216956   9% /etc/hosts
tmpfs                  1023468         0   1023468   0% /proc/asound
tmpfs                  1023468         0   1023468   0% /proc/acpi
tmpfs                    65536         0     65536   0% /proc/kcore
tmpfs                    65536         0     65536   0% /proc/keys
tmpfs                    65536         0     65536   0% /proc/timer_list
tmpfs                    65536         0     65536   0% /proc/timer_stats
tmpfs                    65536         0     65536   0% /proc/sched_debug
tmpfs                  1023468         0   1023468   0% /proc/scsi
tmpfs                  1023468         0   1023468   0% /sys/firmware

docker运行的主机:

[root@docker1 ~]# df
Filesystem            1K-blocks    Used Available Use% Mounted on
/dev/mapper/rhel-root  17811456 1594500  16216956   9% /
devtmpfs                1011400       0   1011400   0% /dev
tmpfs                   1023468       0   1023468   0% /dev/shm
tmpfs                   1023468   17076   1006392   2% /run
tmpfs                   1023468       0   1023468   0% /sys/fs/cgroup
/dev/vda1               1038336  135172    903164  14% /boot
tmpfs                    204696       0    204696   0% /run/user/0
overlay                17811456 1594500  16216956   9% /var/lib/docker/overlay2/0d9fe361ffa5bec1667b38b2dc660e093a1dd319d69a23a6e498683163971fc5/merged

这个便是容器挂载在宿主机上面的卷

/dev/mapper/rhel-root  17811456 1594500  16216956   9% /

查看一下该容器的具体信息
docker inspect 后面可以加容器也可以镜像

[root@docker1 ~]# docker ps -a 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                            PORTS               NAMES
4c626bd8688f        test:v4             "sh"                14 seconds ago      Up 13 seconds                     80/tcp              romantic_bhabha
999fd34ca89f        test:v4             "sh"                4 hours ago         Exited (255) About a minute ago   80/tcp              peaceful_wing
[root@docker1 ~]# docker inspect 4c626bd8688f

inspect查询部分信息:
Gateway是宿主机上面的地址,docker 0的地址。所以容器会通过桥接的模式到达宿主机的网关
所有容器的数据会放在宿主机的/var/lib/docker,如果把这个删掉,所有的镜像容器全没了。

[root@docker1 docker]# ls
builder  buildkit  containers  image  network  overlay2  plugins  runtimes  swarm  tmp  trust  volumes

容器的卷的目录在/var/lib/docker/volumes

  "Gateway": "172.17.0.1"
  "IPAddress": "172.17.0.2",
       "Mounts": [
            {
                "Type": "volume",
                "Name": "a780ebed1de6be544711f18a254682fc4f018ce2f7058b0a23f6f16a3eb73171",
                "Source": "/var/lib/docker/volumes/a780ebed1de6be544711f18a254682fc4f018ce2f7058b0a23f6f16a3eb73171/_data",
                "Destination": "/data",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ]

这个路径就被挂载在容器的目录里面

"Source": "/var/lib/docker/volumes/a780ebed1de6be544711f18a254682fc4f018ce2f7058b0a23f6f16a3eb73171/_data",

容器里面:

/data # touch file1
/data # ls
file1

宿主机上:

[root@docker1 ~]# cd /var/lib/docker/volumes/a780ebed1de6be544711f18a254682fc4f018ce2f7058b0a23f6f16a3eb73171/_data
[root@docker1 _data]# ls
file1

宿主机docker0的地址:

[root@docker1 ~]# ip addr | grep 172.17.0.1
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0

容器里面查询ip的结果:

/dir1 # ip addr 
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0

1.7将数据存入宿主机原因

1.容器的文件系统性能比宿主机差
2.数据过大放在容器不合适,不小心删掉容器,数据就丢失了

同理存在宿主机上面:
宿主机删掉该数据,容器里面的数据就没有了
宿主机:

[root@docker1 ~]# cd /var/lib/docker/volumes/a780ebed1de6be544711f18a254682fc4f018ce2f7058b0a23f6f16a3eb73171/_data
[root@docker1 _data]# ls
file1
[root@docker1 _data]# rm -fr file1 

容器里面:

/data # ls
file1
/data # ls
/data # 

1.8RUN指令的用法

在容器中运行命令并创建新的镜像层,常用于安装软件包:
RUN yum install -y vim


1.9CMD与ENTRYPOINT指令的用法

这两个指令都是用于设置容器后执行的命令,但CMD会被docker run 后面的命令行覆盖(比如docker run -it /ls会覆盖掉),而ENTRYPOINT不会被忽略,一定会被执行
docker run 后面的参数可以传递给ENTRYPOINT指令当作参数
Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效

CMD当用户进入后自动执行的指令,像busybox这个镜像第二层,意思就是当用户进去后,自动执行sh
官方推荐CMD用exec格式写

[root@docker1 docker]# docker history test:v1
beae173ccac6        3 weeks ago         /bin/sh -c #(nop)  CMD ["sh"]                   0B                  

1.10Shell 和exec格式的区别

Shell格式底层会调用/bin/sh -c来执行命令,可以解析变量,而exec格式不会
而用exec格式写的话:[“/bin/sh”,“-c”,“echo $变量名”]

Shell格式:

[root@docker1 docker]# vim Dockerfile 
[root@docker1 docker]# cat Dockerfile 
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /
ADD nginx-1.18.0.tar.gz  /
ENV HOSTNAME docker1
EXPOSE 80
VOLUME ["/data"]
WORKDIR /dir1
CMD echo $HOSTNAME
[root@docker1 docker]# docker build -t test:v5 .
[root@docker1 docker]# docker run --rm test:v5
docker1

exec格式:

[root@docker1 docker]# vim Dockerfile 
[root@docker1 docker]# cat Dockerfile 
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /
ADD nginx-1.18.0.tar.gz  /
ENV HOSTNAME docker1
EXPOSE 80
VOLUME ["/data"]
WORKDIR /dir1
CMD ["echo $HOSTNAME"]
[root@docker1 docker]# docker build -t test:v6 .
[root@docker1 docker]# docker run --rm test:v6
docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "echo $HOSTNAME": executable file not found in $PATH: unknown.
[root@docker1 docker]# docker rmi test:v6
[root@docker1 docker]# vim Dockerfile 
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /
ADD nginx-1.18.0.tar.gz  /
ENV HOSTNAME docker1
EXPOSE 80
VOLUME ["/data"]
WORKDIR /dir1
CMD ["/bin/echo","echo $HOSTNAME"]
[root@docker1 docker]# docker build -t test:v6 .
[root@docker1 docker]# docker run --rm test:v6
echo $HOSTNAME

用exec格式写:

[root@docker1 docker]# vim Dockerfile 
[root@docker1 docker]# cat Dockerfile 
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /
ADD nginx-1.18.0.tar.gz  /
ENV HOSTNAME docker1
EXPOSE 80
VOLUME ["/data"]
WORKDIR /dir1
CMD ["/bin/echo","-c","echo $HOSTNAME"]
[root@docker1 docker]# docker build -t test:v7 .
[root@docker1 docker]# docker run --rm test:v7
docker1

Exec格式时,ENTRYPOINT可以通过CMD提供额外的参数,CMD的额外参数可以在容器启动时动态替换。在shell格式时ENTRYPOINT会忽略任何CMD或docker run提供的参数。即ENTRYPOINT与CMD混合使用

1.11ENTRYPOINT与CMD混合使用

[root@docker1 docker]# vim Dockerfile 
[root@docker1 docker]# cat Dockerfile 
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /
ADD nginx-1.18.0.tar.gz  /
ENV HOSTNAME docker1
EXPOSE 80
VOLUME ["/data"]
WORKDIR /dir1
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world"]
[root@docker1 docker]# docker build -t test:v8 .
[root@docker1 docker]# docker run --rm test:v8
hello world
[root@docker1 docker]# docker run --rm test:v8 linux
hello linux
[root@docker1 docker]# docker run --rm test:v8 yan
hello yan

END

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
docker-compose 是一个用于定义和运行多个容器的工具,而 Dockerfile 是用于构建 Docker 镜像的文件。在使用 docker-compose 运行多个容器时,可以通过 Dockerfile 来定义每个容器所需的镜像。 以下是使用 docker-compose 结合 Dockerfile 的基本步骤: 1. 创建一个新的目录,并在该目录中创建一个名为 `docker-compose.yml` 的文件,用于定义容器组成和配置。 2. 在同一目录中,为每个容器创建一个文件夹,并在每个文件夹中创建一个 Dockerfile,用于构建该容器的镜像。可以根据需要,在 Dockerfile 中指定所需的基础镜像、软件包安装、文件复制等操作。 3. 在 `docker-compose.yml` 文件中定义每个容器的配置。使用 `services` 关键字来定义每个服务,并指定该服务使用的镜像和其他配置项。可以参考下面的示例: ```yaml version: "3" services: web: build: ./web # 指定构建 web 服务的 Dockerfile 所在路径 ports: - "8000:8000" # 指定端口映射 volumes: - ./app:/app # 挂载本地目录到容器内部 db: image: mysql:latest environment: - MYSQL_ROOT_PASSWORD=secret - MYSQL_DATABASE=mydatabase ``` 在上述示例中,定义了两个服务:`web` 和 `db`。`web` 服务使用 `./web` 目录中的 Dockerfile 构建镜像,映射本地端口 8000 到容器内部的 8000 端口,并挂载 `./app` 目录到容器内部。 `db` 服务使用官方的 `mysql:latest` 镜像,并设置了环境变量。 4. 运行 `docker-compose up` 命令来启动容器docker-compose 会根据 `docker-compose.yml` 文件中的配置构建并启动容器组。 使用 docker-compose 结合 Dockerfile 可以更方便地定义和管理多个相关的容器,提高开发和部署的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值