Docker -- Dockerfile

ⅰ亾dé卋堺 提交于 2020-11-19 03:50:36

Dockerfile 每一行就是一层,要避免层数过多

  • FROM
指定基础镜像
  • RUN
执行命令行
RUN shell
RUN ['可执行文件', ‘参数1’, ‘参数2’]
RUN shell_command=echo 'hello' && apt-get purge -y --auto-remove $shell_command

eg:

FROM debian:jessie
RUN buildDeps='gcc libc6-dev make' \
    && apt-get update \
    && mkdir -p /usr/src/redis \
    && apt-get purge 0y --auto-remove $buildDeps
  • COPY
COPY home? /mydir/
COPY指令将从构建上下文目录中的源路径中的文件拷贝到目的
源路径不能超过当前目录
目的路径为容器内的绝对路径
目的路径如果要用相对路径需要WORKDIR来指定
COPY会保留源文件的各种属性,如读,写权限
  • ADD
ADD home.tar /mydir/
源路径可以是URL或者TAR,感觉很灵活,但实际上它在下载下来后还设置了600权限,还需要改权限,
有时仅仅是下载个压缩包,而不需要自动解压,等等,语议不够明确,不推荐
  • CMD
shell 格式: CMD <Command>
exec 格式: CMD ["可执行文件", "参数1",...]
容器起来顺带执行的命令和参数
CMD ["nginx", "-g", "daemon off;"]
CMD ["sh", "-c", "/bin/bash"]
CMD /bin/bash
------------
docker run -it ubuntu /bin/bash
如果用exec格式,必需是双引号,因为会解析成json
  • ENTRYPOINT
<ENTRYPOINT> "<CMD>"
与CMD类似,都是容器启动时给的命令,但是它提供了
一种入参形式,它可以在docker run时输入参数 --entrypoint的形式开始
让镜像变得像命令一样

eg

FROM ubuntu:16.04
RUN apt-get update \
    && apt-get install -y curl \
    && rm -rf /var/lib/apt/lists/*
CMD ["curl", "-s", "http://ip.cn"]
----------------
docker build -t myip .
dorcker run myip
current ip is 140.207.81.26
如果想要看http头呢
docker run myip -i   # error
docker run myip curl -s https://ip.cn -i
-------------------
FROM ubuntu:16.04
RUN apt-get update \
    && apt-get install -y curl \
    && rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["curl", "-s", "http://ip.cn"]
-----------------
docker run myip -i   #ok
  • CMD与ENTRYPOINT的区别在于

  • docker run后面的参数会覆盖CMD的内容

  • docker run后面的参数不会覆盖ENTRYPOINT的内容,ENTRYPOOINT是以参数的形式跟在docker run 后面

  • 还有一点是当ENTRYPOINT是一个shell脚本时,可以入参啊,CMD做不到

  • ENV

定义环境变量
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>
ENV VERSION=1.0 NAME="terry ding"
  • ARG
与ENV一样,只是在构建时才存在,可以放到docker run --build-arg 最好在Dockerfile中定义过
  • VOLUME

如数据库会有很多动态的数据,我们又不希望放到镜像中,通常会挂载一个卷用来存放这些数据

VOLUME ["<路径1>", "<路径2>"]
VOLUMD <路径>
VOLUME /data
docker run -d -v mydata:/data ubuntu:16.04

/data指的是容器中的,而不是现实中 把mydata 挂载到容器中的/data目录中

  • EXPOSE

声明端口,但并没有太大的用处,只有在docker run -P 随机时才有用,真正有用的是下面这句

docker run -p <宿主>:<容器端口>
docker run -p 8080:80
  • WORKDIR 指定工作目录

使用WORKDIR指令可以指定工作目录,以后各层的当前目录就被改为指定的目录

RUN cd /app
RUN echo "hello">world.txt
--------------
找不到/app/world.txt, 因为docker是分层的
  • USER 改变当前用户

改变环境状态并影响后面的层,改变后面层执行命令的身份 sudo 不要用,用gosu替换

  • ONBUILD

如果基础镜像要生成很多的子镜像,此时用ONBUILD可以让子镜像执行ONBUILD的命令,基础不变

FROM node:slim
RUN mkdir /app
WORKDIR /app
ONBUILD COPY ./package.json /app
ONBUILD RUN ["npm", "install"]
ONBUILD COPY . /app/
CMD ["npm", "start"]
  • 根据Dockerfile创建镜像
dockerfile 所在目录
root@terry:~/docker/mynginx# docker build -t nginx:v2 .
Sending build context to Docker daemon 2.048 kB
Step 1/2 : FROM nginx
 ---> c82521676580
Step 2/2 : RUN echo '<h1>Hello, Docker~</h1>' > /usr/share/nginx/html/index.html
 ---> Running in 3c3a769d81f4
 ---> 60ed7221bb04
Removing intermediate container 3c3a769d81f4
Successfully built 60ed7221bb04
  • docker build [选项] <上下文路径>
docker build -t nginx:v2 .
  • docker 是一种c/s架构,本机运行的docker实际上是客户端,而真正执行是在server上执行,我们只不过是在调用remoteAPI与docker 引擎交互

  • docker build 最后一个 .非常重要,它指定了该build所包含的所有文件,并从该目录作为顶级目录,以后所有的操作都在这个目录中进行,而不得超出这个目录,最后可以不是当前目录,但你有可能把一个硬盘都传上去了,它指定的是该目录中的所有文件, docker build 命令得知这个路径后,会将路径下的所有内容打包,然后上传给Docker引擎,这样Docker 引擎收到这个上下文包后,展开就会获得镜像所需要的文件,因此如果要COPY本地文件到镜像中把文件放到上下文目录中。默认会将上下文目录下名为Dockerfile的文件作为Dockerfile,实际上这不是必需的,可以用-f参数指定Dockerfile

  • docker build https://gitbub.com/XXX.git

  • docker containers ls

参考

《Docker 入门与实践》

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!