Dockerfile与小案例

制作镜像的方式

容器-> 镜像

​ 功能性受限 (无法封装新的启动命令)

Dockerfile build镜像

​ 优点: 1 docker官方做的镜像制作工具

​ 2 基础镜像可以不具备前台启动进程

Dockerfile语法

特性

关键字 必须大写

编写一个Dockerfile文件

[root@localhost ~]# vim Dockerfile

FROM centos:centos7.9.2009                       
MAINTAINER joe xin_2018@163.com
# COPY ./myapp /root/
RUN touch /root/img
RUN echo "HelloDocker" > /root/img
docker build -t joe/centos:v0.1   .	  #docker 自动制作镜像
Sending build context to Docker daemon 920.5 MB
Step 1/2 : FROM centos:centos7.9.2009
 ---> eeb6ee3f44bd
Step 2/2 : MAINTAINER joe xin_2018@163.com
 ---> Running in 2d986cba8b45
 ---> 807a531fca57
Removing intermediate container 2d986cba8b45
Successfully built 807a531fca57



[root@localhost aa]# docker build -t joe/centos:v0.2 /root/aa/
Sending build context to Docker daemon 2.048 kB
Step 1/2 : FROM centos:centos7.9.2009
 ---> eeb6ee3f44bd
Step 2/2 : MAINTAINER joe xin_2018@163.com
 ---> Using cache # 镜像重用 , 制作步骤和之前相同
 ---> 807a531fca57
Successfully built 807a531fca57





[root@localhost aa]# docker build -t joe/centos:v0.2 /root/aa/
Sending build context to Docker daemon   901 MB
Step 1/3 : FROM centos:centos7.9.2009
 ---> eeb6ee3f44bd
Step 2/3 : MAINTAINER joe xin_2018@163.com
 ---> Using cache
 ---> 807a531fca57
Step 3/3 : COPY ./myapp /root/
 ---> 8c577c2cdbca
Removing intermediate container 123b2503f6ad
Successfully built 8c577c2cdbca

# 状态为create
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                        NAMES
123b2503f6ad        807a531fca57        "/bin/sh -c '#(nop..."   10 seconds ago      Created                                          inspiring_allen
d4cc8d902878        joe/nginx:v0.1      "/usr/bin/supervisord"   About an hour ago   Up About an hour    22/tcp, 0.0.0.0:80->80/tcp   nginx

关键字

FROM(指向基础image)

建议使用官方镜像 ,必须放在Dockerfile文件中指令的最前面 , 后续的指令都依赖于该指令指定的image , FROM 指向的基础镜像 , 可以是远程的官方仓库中的 , 也可以是本地仓库中的

一般情况下只有一个FROM 关键字

FROM  (也可以跟镜像ID)

MAINTAINER(著作名)

查看

[root@localhost aa]# docker inspect joe/centos:v0.2|grep joe
            "joe/centos:v0.2"
        "Author": "joe xin_2018@163.com",

ADD(从 src 复制文件到 container 的 dest 路径)

ADD <src> <dest>  
		<src> 是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件 url;
		<dest> 是 container 中的绝对路径

会自动解压 会访问远程url 也可以本地路径

COPY (从 src 复制文件到 container 的 dest 路径)

COPY <src> <dest> 

不会自动解压 不能访问远程url

LABEL(标签)

元数据信息都具备继承性 , 如果构建的新镜像中没有指定元数据信息 , 那么它会继承基础镜像的元数据信息 , 如果构建的镜像 指定了元数据信息 ,如果指定的元数据信息 ,和 基础镜像冲突 ,那么会替换 ,如果不冲突(什么是冲突 key 相同value 不同) ,那么新增

RUN()

[root@localhost aa]# docker run joe/centos:v0.2 cat /root/img
HelloDocker

存储驱动引擎

​ DM

​ overlay

​ v1 Docker 中做了限制 , 分层层级不能超过128 层

​ v2 overlay v2 本身做了限制 分层层级 不能超过128 层

所以Dockerfile 指令层级不能超过128 级

在构建LAMP环境时

RUN tar -xf apache
RUn cd apache
RUN ./configure
RUN make
RUN make install
RUN tar -xvf mysql
RUN ......



#可以写成
RUN tar -xf apache && cd apache && ./configure && make && make install
#为了便于维护 和便于共享(可重用性下降) ,如下图 img1 可重用性要明显高于img2

USER(设置container 容器的用户)

ELF 不能在root用户下执行, 默认就会报错

EXPOSE(指定当前容器需要映射的端口)

docker run --name wordpress -d wordpress 
# name(如果不指定 , 系统会默认创建一个随机name)





[root@localhost aa]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS                        NAMES
174e1e4dc9ee        wordpress           "docker-entrypoint..."   7 minutes ago       Up 7 minutes                80/tcp                       wordpress
a76f11fde9d7        joe/centos:v0.2     "cat /root/img"          28 minutes ago      Exited (0) 28 minutes ago                                pensive_nightingale
d4cc8d902878        joe/nginx:v0.1      "/usr/bin/supervisord"   2 hours ago         Up 2 hours                  22/tcp, 0.0.0.0:80->80/tcp   nginx

注意port 不代表只有这些端口 ,也不代表有这些端口 (是镜像制作的时候做的提醒  这就是EXPOSE的作用)

# EXPOSE 是信息级别的, 告知作用
EXPOSE 80
EXPOSE 443

ENV(用于设置环境变量)

在profile中不就可以设置了吗 ,为什么要用一个专门的命令呢

# 容器的中服务的启动命令 与传统的启动命令不同
# 容器中并没有systemd 这个进程 ,所以写入profile 并不生效

ARG (设置变量)

起作用的时机

  • ARG 是在 build 的时候存在的, 可以在 Dockerfile 中当做变量来使用
  • ENV 是容器构建好之后, 系统中存在环境变量, 不能在 Dockerfile 中当参数使用
# Dockerfile
FROM redis:3.2-alpine

LABEL maintainer="wangyanglinux@163.com"

ARG REDIS_SET_PASSWORD=developer
ENV REDIS_PASSWORD ${REDIS_SET_PASSWORD}

VOLUME /data

EXPOSE 6379

CMD ["sh", "-c", "exec redis-server --requirepass \"$REDIS_PASSWORD\""]

WORKDIR

进入容器后 ,自动切换至指定目录

设置指令,可以多次切换(相当于cd命令),对RUN,CMD,ENTRYPOINT生效

WORKDIR /usr/local/nginx

WORKDIR /p1 WORKDIR p2 RUN vim a.txt

CMD(设置 container 启动时执行的操作)

设置指令,用于 container 启动时指定的操作。该操作可以是执行自定义脚本,也可以是执行系统命令。该指令只能在文件中存在一次,如果有多个,则只执行最后一条

CMD echo “Hello, World!” 

posted on 2022-02-08 23:45  joe_HelloWorld  阅读(56)  评论(0编辑  收藏  举报

导航