Dockerfile 快速入门

311 阅读1分钟

1、指令说明

  • FROM.../FROM…AS…: FROM centos:7 表示以 centos:7 作为基础镜像进行构建;FROM…AS…是Docker 17.05及以上版本新出来的指令,其实就是给这个阶段的镜像起个别名:FROM ...(基础镜像) AS ...(别名),在后面引用这个阶段的镜像时直接使用别名就可以了
FROM gradle:jdk8 AS builder
FROM centos:7
  • RUN:可以看出RUN后面跟的其实就是一些shell命令,通过&&将这些脚本连接在了一行执行,这么做的原因是为了减少镜像的层数,每多一行RUN都会给镜像增加一层,所以这里选择将所有命令联结在一起执行以减少层数
RUN gradle build
  • ENV:可以看出这个指令的作用是在shell中设置一些环境变量(其实就是export)
ENV ADMIN_HOME /home/admin
  • COPY:用来来回复制文件的,COPY . /root/workspace/agent表示将当前文件夹(.表示当前文件夹,即Dockerfile所在文件夹)的所以文件拷贝到容器的/root/workspace/agent文件夹中。通过--from参数也可以从前面阶段的镜像中拷贝文件过来,比如--from=builder表示文件来源不是本地文件系统,而是前面阶段别名为builder的容器
COPY ./ ${ADMIN_HOME}
  • ADD:将主机的文件复制到镜像中,跟COPY一样,限制条件和使用方式都一样,但是ADD会对压缩文件(tar, gzip, bzip2)做提取和解压操作
ADD application.yml /etc/service-provider/
  • WORKDIR:在执行RUN后面的shell命令前会先cd进WORKDIR后面的目录
WORKDIR /opt/code
  • ENTRYPOINT:这个参数表示镜像的“入口”,镜像打包完成之后,使用docker run命令运行这个镜像时,其实就是执行这个ENTRYPOINT后面的可执行文件(一般是一个shell脚本文件),也可以通过["可执行文件", "参数1", "参数2"]这种方式来赋予可执行文件的执行参数,这个“入口”执行的工作目录也是WORKDIR后面的那个目录
ENTRYPOINT ["java","-jar","app.jar"]
  • CMD:容器启动时需要执行的命令,当有多个CMD的时候,只有最后一个生效
CMD /bin/bash
CMD ["/bin/bash"]

注意 :作用和用法和ENTRYPOINT一模一样,区别是CMD的命令会被 docker run 的命令覆盖而ENTRYPOINT不会 如使用CMD ["/bin/bash"]或ENTRYPOINT ["/bin/bash"]后,再使用docker run -ti image启动容器,它会自动进入容器内部的交互终端,如同使用 docker run -ti image /bin/bash 但是如果启动镜像的命令为docker run -ti image /bin/ps,使用CMD后面的命令就会被覆盖转而执行bin/ps命令,而ENTRYPOINT的则不会,而是会把docker run 后面的命令当做ENTRYPOINT执行命令的参数。 以下例子比较容易理解 Dockerfile中为例子:

ENTRYPOINT ["/user/sbin/nginx"]

然后通过启动build之后的容器

docker run -ti image -g "daemon off"

此时-g "daemon off"会被当成参数传递给ENTRYPOINT,最终的命令变成了

/user/sbin/nginx -g "daemon off"

CMD和ENTRYPOINT都存在时 CMD和ENTRYPOINT都存在时,CMD的指令变成了ENTRYPOINT的参数,并且此CMD提供的参数会被 docker run 后面的命令覆盖,如:

ENTRYPOINT ["echo","hello","i am"]
CMD ["docker"]

之后启动构建之后的容器

  • 使用docker run -ti image 输出“hello i am docker”

  • 使用docker run -ti image world 输出“hello i am world”

  • MAINTAINER: 指明该镜像的作者和其电子邮件

MAINTAINER 企业级分布式应用服务智慧案场研发团队 <chendh03@mingyuanyun.com>
  • EXPOSE:暴露镜像的端口供主机做映射,启动镜像时,使用-P参数来讲镜像端口与宿主机的随机端口做映射
EXPOSE 9000
  • USER: 指定该镜像以什么样的用户去执行
USER www
  • VOLUME:用来向基于镜像创建的容器添加卷,比如你可以将mongodb镜像中存储数据的data文件指定为主机的某个文件。(容器内部建议不要存储任何数据)
VOLUME /data/db /data/configdb

2、Docker基本操作

  • 执行Dockerfile生成镜像,命令格式:docker build -t 镜像名称:镜像标签(版本号) Dockerfile所在位置
docker build -t mingyuanyun/service-provider:v1.0.1 .
  • 查看镜像
docker images|grep provider或者docker image list|grep provider
  • 创建镜像实例
docker run -d --name=service-provider -p 8080:9000 镜像ID

-p物理机跟docker容器端口映射 -v物理机与docker容器目录挂载

  • 查看容器实例
#查看正在运行的容器实例
docker ps|grep provider
#查看所有容器实例,包括已停止运行的
docker ps -a|grep provider
  • 删除容器实例
docker rm -f 容器ID

-f 强制删除

  • 删除镜像 docker rmi 镜像ID

  • 查看日志 docker logs -f 容器ID

3、项目Dockerfile说明

FROM gradle:jdk8 AS builder
ENV PROJECT "provider-example"
WORKDIR /$PROJECT
COPY ./ /$PROJECT
RUN gradle build


FROM openjdk:8-alpine
MAINTAINER 企业级分布式应用服务智慧案场研发团队 <chendh03@mingyuanyun.com>
# 准备 JDK/Tomcat 系统变量
ENV ADMIN_HOME /home/admin
ENV PROJECT "provider-example"
ENV APP_FILE provider-example-0.0.1-SNAPSHOT.jar
# 下载部署 EDAS 演示 JAR 包
RUN mkdir -p $ADMIN_HOME/app/
#拷贝上面打包阶段builder拷贝应用jar过来
COPY --from=builder /$PROJECT/build/libs/$APP_FILE  $ADMIN_HOME/app/app.jar
# 增加容器内中⽂支持
ENV LANG="en_US.UTF-8"
# 增强 Webshell 使⽤体验
ENV TERM=xterm
# 将启动命令写入启动脚本 start.sh
RUN echo 'java -jar $CATALINA_OPTS $ADMIN_HOME/app/app.jar'> $ADMIN_HOME/start.sh && chmod +x $ADMIN_HOME/start.sh
WORKDIR $ADMIN_HOME
#启动应用程序
CMD ["/bin/sh", "$ADMIN_HOME/start.sh"]