Docker file

基本概念

是什么

Docker为我们提供的一个用于自定义构建镜像的配置文件,描述如何构建一个对象。
利用Docker提供的build命令,指定Dockerfile文件,就可以按照配置的内容将镜像构建出来。

为什么需要

  1. 作为开发者需要将自己开发好的项目打包成Docker镜像,便于后面直接作为Docker容器运行
  2. 作为运维人员需要构建更精简的基础设施服务镜像,满足公司的需求以及尽可能减少冗余的功能占用过多的资源

能干什么

  1. 可以自定义镜像内容
  2. 构建公共基础镜像减少其他镜像配置
  3. 开源程序的快速部署
  4. 实现企业内部项目的快速交付

构建镜像

commit(少用)

基于一个现有的容器,构建一个新的镜像
命令:

docker commit -a "作者名字" -m "描述信息" <容器名字> <构建的镜像名字>

例:

  1. 运行一个容器
docker run --rm -d -p 80:80 --name nginx_commit nginx

img
2. 进入容器,修改index文件

[root@localhost ~]# docker exec -it nginx_commit /bin/bash
root@0d4ac55e5959:/# cd /usr/share/nginx/html/
root@0d4ac55e5959:/usr/share/nginx/html# ls
50x.html  index.html
root@0d4ac55e5959:/usr/share/nginx/html# echo '<h1>my nginx</h1>' > index.html 
root@0d4ac55e5959:/usr/share/nginx/html# cat index.html 
<h1>my nginx</h1>
root@0d4ac55e5959:/usr/share/nginx/html# exit
exit

img
3. 使用commit命令构建一个新的镜像

docker commit -a "xdn" -m "my nginx container" nginx_commit mynginx:1

img
4. 查看镜像

docker images

img
5. 验证,停止原先运行的容器,使用刚构建的镜像运行新的容器,浏览器访问

[root@localhost ~]# docker stop nginx_commit 
nginx_commit
[root@localhost ~]# docker run --rm -d -p 80:80 --name mynginx mynginx:1 
5ba7007969c6865cdf505ea632730962394268aab93062a0e470aafdac57fb63
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                               NAMES
5ba7007969c6   mynginx:1   "/docker-entrypoint.…"   7 seconds ago   Up 3 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   mynginx

img
img

build(常用)

docker build -t <镜像名字:版本> <dockerfile路径> 
# -t 表示要基于文件来构建镜像

Spring Boot镜像

例:
dockerfile内容:

# 关联基础镜像 => jdk
FROM openjdk:8

# 将项目 jar 包拷贝到容器中
ADD *.jar app.jar

#配置项目环境变量
ENV APP_OPTS=""

# JVM环境变量
ENV JVM_OPTS="-Duser.timezone=Asia/Shanghai -Xms128m -Xmx128m"

# 暴露端口
EXPOSE 8888

# 设置启动时的命令
ENTRYPOINT ["sh","-c","java $JVM_OPTS -jar /spp.jar $APP_OPT"]

Tomcat镜像

例:

FROM tomcat:9.0
WORKDIR /usr/local/tomcat/webapps
ADD *.war ROOT.war
ENTRTPOINT ["sh","-c","../bin/catalina.sh run"]

Nginx镜像

例:

# 设置基础镜像
FROM centos:7

# 维护者信息
MAINTAINER xdn<xiaodunan.cn>

# 加入构建镜像所需的文件
ADD pcre-8.38.tar.gz /usr/local/src
ADD nginx-1.14.2.tar.gz /usr/local/src

# 安装 c++ 源码编译的基础工具
RUN yum install -y wget gcc gcc-c++ make openssl-devel

# 创建 www 用户作为 nginx 启动用户
RUN useradd -s /sbin/nologin -M www  #nologin指定用户不能登录

# 进入 nginx 解压后的源码目录
WORKDIR /usr/local/src/nginx-1.14.2

# nginx 编译安装
RUN ./configure --prefix=/usr/local/nginx --user=www --group=www -with-http_ssl_module --with-http_stub_status_module --with-pcre=/usr/local/src/pcre-8.38
RUN make && make install

# 关闭 nginx 后台运行
RUN echo 'daemon off;' >> /usr/local/nginx/conf/nginx.conf

# 创建 nginx 命令快速访问的环境变量
# ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/nginx   (软连接方式)
ENV PATH /usr/local/nginx/sbin:$PATH   #环境变量方式

# 用自己自定义的首页模板替换 nginx 原本的首页模板
ADD index.html /usr/local/nginx/html

# 暴露端口
EXPOSE 80

# 容器启动命令
CMD ["nginx"]

常用命令

FROM

指定当前镜像的基础镜像是什么
例:

FROM openjdk:8

MAINTAINER

描述镜像的作者,以及联系方式(可选)
例:

MAINTAINER xdn<xiaodunan.com>

LABEL(可选)

为镜像设置标签,一个Dockerfile中可以配置多个label
例:

LABEL version="1.0"
LABEL description="这是我的第一个Dockerfile"

ENV

设置容器的环境变量,可以设置多个
例:

ENV JAVA_ENV dev
ENV APP_NAME test-dockerfile 

ENV JAVA_ENV=dev APP_NAME=test-dockerfile
# 两种语法的区别为第一种一次只能设置一个环境变量,第二种可以一次设置多个

RUN

在构建镜像时,需要执行的shell命令
例:

RUN ls -al
RUN mkdir /www/test/dockerfile/test

ADD

将主机中的指定文件复制到容器的目标位置,可以简单理解为cp命令
例:

ADD /var/run/test /etc/hosts
#把主机的/var/run/test 拷贝到容器的/etc/hosts

ADD ["/var/run/test /","/etc/hosts"]

WORKDIR

设置容器的工作目录,如果该目录不存在会自己创建
例:

WORKDIR /app
#在设置完工作目录后执行pwd命令,打印的目录就是 /app,相当于cd命令
RUN pwd

VOLUME

镜像数据卷绑定,将主机中的指定目录挂载到容器中
例:

VOLUME ["/www/wolfcode.cn"]

EXPOSE

设置容器启动后要暴露的端口,仅仅只是在容器内暴露这个端口,跟主机没有关联
例:

EXPOSE 8080

CMD 和 ENTRYPOINT

选择其一即可,作用是描述镜像构建完成后,启动容器时默认执行的脚本,只能设置一次,如果写了多次则只有最后一次生效
区别:

  • ENTRYPOINT不会被运行容器时所指定的命令所覆盖,而CMD会
  • 如果同时设置了这两个指令,且CMD仅仅是选项而不是参数,CMD中的内容会作为ENTRYPOINT的参数(一般不这么做)
  • 如果两个都是完整命令,那么只会执行最后一条
    ENRYPOINT非json则以ENRYPOINT为准,如果ENRYPOINT和CMD都是JSON则ENRYPOINT+CMD拼接成shell
    例:
CMD ping 127.0.0.1
CMD ["sh","-c","ping 127.0.0.1"]  #sh 表示使用shell脚本

ENTRYPOINT ping 127.0.0.1
ENTRYPOINT ["sh","-c","ping 127.0.0.1"]

拓展指令

ARG

设置变量,在镜像中定义一个变量,当使用docker build命令构建镜像时,带上--build-arg <name>=<value>来指定参数值,如果该变量名在Dockerfile中不存在则会抛出一个警告。
语法

ARG <name>[=<default value>]

例:

ARG jdk=8
FROM openjdk:$jdk

USER

设置容器的用户,可以是用户名或UID,如果容器设置了以daemon用户去运行,那么RUN.CMD和ENTRTPOINT都会以这个用户运行,一定要先确定容器中有这个用户,并且拥有对应的操作权限。
语法:

USER <username>
USER <PID>

例:

RUN useradd wolfcode
#提前添加好用户
USER wolfcode
#表示后续容器中所有执行命令的操作都是以 wolfcode 这个用户操作的

ONBUILD

表示在构建镜像时做某操作,不过不对当前Dockerfile的镜像生效,而是对以当前Dockerfile镜像作为基础镜像的子镜像生效
语法:

ONBUILD [INSTRUCTION]

例:
当前镜像为A,设置了如下指令

ONBUILD RUN ls -al

镜像B:
FROM 镜像A
....
构建镜像B时,会执行la -al命令

STOPSIGNAL

STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。此信号可以是与内核的系统调用表中的位置匹配的有效无符号数。

HEALTHCHECK

容器健康状况检查,可以指定周期检查容器当前的健康状况,该命令只能出现一次,如果有多次则只有最后一次生效。
语法:

HEALTHCHECK [OPTION] CMD command
HEALTHCHECK NONE
#第一种:在容器内部按照指定周期运行指定命令来检测容器健康状况
#第二种:取消在基础镜像

返回参数:
0 健康
1 不健康
2 保留值,不确定成功还是失败

例:

健康检查,每隔10秒钟检查容器是否正常,每次不超过3秒钟,并且如果失败了,最多不能超过5次
HEALTHCHECK --interval=10 --timeout=3 --retries=5 CMD ps -ef | grep java || exit 1
posted @ 2023-05-18 10:46  小肚腩吖  阅读(28)  评论(0编辑  收藏  举报