Docker镜像构建
一、简介
- 使用现有的容器使用docker commit 生成镜像
- 使用Dockerfile进行镜像构建
二、Dockerfile介绍
语法规则
环境变量引用
docker build命令
- -t, --tag list 指定生成镜像标签,格式为name:tag
- -f, --file string 单独指定Dockerfile文件位置
- --build-arg list 设置构建时的变量
- --no-cache 构建镜像时候不使用缓存
快速开始
mkdir /opt/demo -p
cd /opt/demo/
FROM centos:latest #指定基础镜像为centos
LABEL Author=“wd” #指明作者
RUN yum install -y yum epel-release && yum install -y nginx && echo "${HOSTNAME}-nginx server" > /usr/share/nginx/html/index.html #运行命令安装Nginx
CMD [ "/usr/sbin/nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf”] #启动容器运行的命令
[root@app51 demo]# docker build -t nginx:v1 ./
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos:latest
---> 1e1148e4cc2c
Step 2/4 : LABEL Author="wd"
---> Using cache
---> 8eb3ffcb8ba3
Step 3/4 : RUN yum install -y yum epel-release && yum install -y nginx && echo "${HOSTNAME}-nginx server" > /usr/share/nginx/html/index.html
---> Using cache
---> ac91999a716e
Step 4/4 : CMD [ "/usr/sbin/nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"]
---> Running in 323afd4ac89d
Removing intermediate container 323afd4ac89d
---> 6403c553fd04
Successfully built 6403c553fd04
Successfully tagged nginx:v1
[root@app51 demo]# docker run -d --name nginx-demo-c1 -p 8088:80 nginx:v1
08812b7def62c9ad7879dfa4182bc28a20f524e2dbc5eb6e4fe63d2b67be3cc9
[root@app51 demo]# curl http://127.0.0.1:8088
60e5de135132-nginx server #访问成功
[root@app51 demo]#
三、指令详解
FROM
FROM <repository>
FROM <repository>[:<tag>]
FROM <repository>@<digest>
FROM centos:latest
LABEL
LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例:
LABEL "com.example.vendor"="ACME Incorporated”
LABEL maintainer="SvenDowideit@home.org.au"
MAINTAINER (deprecated)
MAINTAINER <message>
MAINTAINER "wd <xxx@163.com>"
COPY
用于主机中的文件或者复制到镜像中
语法:
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
- 如果复制的src或dest中存在空格字符需使用第二种加双引号方式
- src必须是 build的上下文目录(Dockerfile同级目录或子目录),不能是父目录或者绝对路径
- 如果指定来多个src或者src中使用了通配符,则dest必须是一个目录,且必须以/结尾
COPY hom* /mydir/ #拷贝以hom开头的的所有文件
COPY hom?.txt /mydir/ #?代表占位符,可以拷贝
ADD
ADD指令类似于COPY,但是ADD比COPY更强大,支持TAR文件和URL路径
语法:
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
- 当src是URL时,如果dest不以/结尾,则src指定的文件将被下载并且被创建为dest,如果dest以/结尾,则src指定下载的文件会保存在dest目录下。
- 当src是一个本地目录的一个tar压缩格式文件,其在容器中会被展开为目录,类型与tar -x命令,通过URL下载的tar文件则不会被解压。
- 如果指定来多个src或者src中使用了通配符,则dest必须是一个目录,且必须以/结尾,多个文件一同被复制在dest目录下
ADD hom* /mydir/
ADD hom?.txt /mydir/
WORKDIR
WORKDIR dirpath
示例:
WORKDIR /usr/local
ENV
用于为镜像定义所需的环境变量,并可被Dockfile中位于其以后的指令所调用,如ADD、COPY、RUN等调用格式为$variable_name或者${variable_name},此外在启动容器时候这些变量也是存在的。
语法:
ENV <key> <value>
ENV <key>=<value> ...
- 第一种格式中key之后的所有值会被作为value,因此一次只能设置一个变量
- 第二种格式可一次性设置多个变量,每个变量为一个key=value的键值对,如果value种包含空格,可以用反斜线(\)转义,也可以通过对value加引号进行标识,此外反斜线也可用于续行,多个变量时候建议使用。
示例:
ENV myName="John Doe” \
myDog=Rex \
myCat=fluffy
ENV myCat fluffy
RUN
用于在build过程中运行的程序,可以是任何指令,可以指定多个RUN
语法:
RUN <command> #shell 格式默认linux采用/bin/sh -c,windows采用cmd /S /C
RUN ["executable", "param1", "param2”] #可执行程序格式
示例:
RUN yum install -y nginx
RUN ["/bin/bash", "-c", "echo hello"]
EXPOSE
用于为容器暴露端口到外部,用于实现通讯,类似于docker run的-p选项
语法:
EXPOSE <port> [<port>/<protocol>...]
EXPOSE 8080
EXPOSE 8080/udp 8088/tcp
VOLUME
用于在image中创建一个挂载目录,以挂载宿主机上的目录
语法:
VOLUME <path>
VOLUME ["path"]
VOLUME ["/var/log/“]
VOLUME /myvol
CMD
CMD command param1 param2 #shell格式,含有shell环境
CMD ["executable","param1","param2”] #可执行程序格式
CMD ["param1","param2”] #第三种用于为ENTRYPOINT提供默认参数
注意:
- 在第一种格式中command 通常是一个shell命令,且默认以/bin/sh -c来运行它,这意味着此进程在容器的的PID不为1,不能接受unix信号,因此使用docker stop <container>命令停止容器时,此进程接受不到SIGTERM信号。
- 第二种格式是可执行程序运行方式,不会以"/bin/sh -c”来发起,无shell环境,所有shell变量不能引用,但是可以用"/bin/bash -c”作为启动命令达到第一种格式效果
- 第三种格式需要结合ENTRYPOINT使用,作用是为其提供默认参数
ENTRYPOINT
ENTRYPOINT <command>
ENTRYPOINT ["<executable>", "<param1>", "<param2>"]
- 与CMD类似,第一种方式默认会以/bin/sh -c 启动,而第二种则不会,也就意味着没有shell环境
- 通常ENTRPOINT用于使用ENTRPOINT脚本启动
- 当CMD与ENTRYPOINT同时存在时,CMD的参数为ENTRYPOINT提供
示例:
[“nginx”,"-g","daemon off"]
USER
USER <user>[:<group>]
USER <UID>[:<GID>]
- 指定的USER或者GROUP必须在容器中存在,否则指令会运行失败
USER nginx
STOPSIGNAL
语法:
STOPSIGNAL signal
示例:
STOPSIGNAL SIGKILL
- 向容器发送信号只能被PID=1的进程所接收,当PID=1进程不是应用进程时候,应用进程收不到终止信号。
HEALTHCHECK
HEALTHCHECK [OPTIONS] CMD command
其中OPTIONS有如下选项:
- --interval=DURATION 检查间隔(默认: 30s)
- --timeout=DURATION 超时时间(默认t: 30s)
- --start-period=DURATION 等待检查的时间,默认0s代表一启动就检查 (默认: 0s)
- --retries=N (default: 3) 重试次数
示例:
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
SHELL
将可执行程序运行为shell环境,默认以/bin/sh -c运行
语法:
SHELL ["executable", "parameters"]
示例:
SHELL ["echo", “hello"] #等价于 RUN echo hello
ARG
ARG <name>[=<default value>]
FROM nginx
ARG CONF="/tmp/nginx.conf"
LABEL Author=wd
RUN touch "${CONF}"
构建镜像:
[root@app51 ~]# docker build --build-arg CONF='/etc/test.conf' -t nginx:v15.2 ./
Sending build context to Docker daemon 225.6MB
Step 1/4 : FROM nginx
---> f09fe80eb0e7
Step 2/4 : ARG CONF="/tmp/nginx.conf"
---> Using cache
---> ac081589c644
Step 3/4 : LABEL Author=wd
---> Using cache
---> 53b9b0ba4460
Step 4/4 : RUN touch "${CONF}"
---> Running in 50debe96f876
Removing intermediate container 50debe96f876
---> d8680a2433bc
Successfully built d8680a2433bc
Successfully tagged nginx:v15.2
运行容器查看:
[root@app51 ~]# docker run --rm nginx:v15.2 ls /etc/test.conf -l
-rw-r--r-- 1 root root 0 Feb 27 11:18 /etc/test.conf
ONBULD
用于在Dockerfile中定义一个触发器,当制作出来的镜像被别人用于基础镜像时候自动触发。
语法:
ONBUILD [INSTRUCTION]
- ONBUILD不会触发FROM指令。
- 在镜像标签中应明确指出onbuild关键字,以标记使用其基础镜像会触发其他指令
示例:
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
四、使用multi-stage
FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
命名stage
默认情况下,stage未命名,可以通过整数来引用它们,第一个stage表示0,第二个表1以此类推。 但是,当有多个stage时候,这样会显得麻烦,Docker提供AS 语法可以为stage命名:
FROM golang:1.7.3 as builder
然后在另一个stage中使用:
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
使用本地stage
除了可以使用Dockerfile中的stage外,构建镜像时候还可以直接使用本地已存在的环境和产物,例如:
COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf
构建镜像建议
- 基础镜像尽量选择比体积较小的镜像,如每个官方发行的alpine镜像。虽然这版本镜像比较小,但是与之带来的是利用该类镜像运行的容器中排错的命令很少;
- 使用RUN指令时候,尽量把多个RUN指令合并为一个,通常做法是使用&&符号;
- 通过multi-stage方法减少一些不必要使用的环境来减小镜像;
- 安装完成软件同时删除一些不需要的文件或目录;
Docker镜像构建的更多相关文章
- Docker镜像构建(五)
Docker 镜像介绍 Docker镜像构建分为两种,一种是手动构建,另一种是Dockerfile(自动构建) 手动构建docker镜像 案例:我们基于centos镜像进行构建,制作自己的nginx镜 ...
- 4、Docker 镜像构建
Docker 镜像构建 构建分为两种 手动构建 自动构建dockerfile 手动构建 首先启动一个Centos 容器,然后在容器中安装一个nginx [root@node ~]# docker ru ...
- Docker镜像构建原理解析(不装docker也能构建镜像)
在devops流程里面 构建镜像是一个非常重要的过程,一般构建镜像是写dockerfile文件然后通过docker client来构建的image. docker client 会先检查本地有没有im ...
- Docker镜像构建的两种方式
关于Docker里面的几个主要概念 这里用个不太恰当的比方来说明. 大家肯定安装过ghost系统,镜像就像是ghost文件,容器就像是ghost系统.你可以拿别人的ghost文件安装系统(使用镜像运行 ...
- Docker-通过docker-maven-plugin插件实现docker镜像构建并自动发布到远程docker服务器
我们知道,docker能实现应用打包隔离,实现快速部署和迁移.如果我们开发应用使用了spring cloud + spring boot架构,那么,通过docker-maven-plugin实现快速构 ...
- Docker镜像构建的两种方式(六)--技术流ken
镜像构建介绍 在什么情况下我们需要自己构建镜像那? (1)当我们找不到现有的镜像,比如自己开发的应用程序 (2)需要在镜像中加入特定的功能 docker构建镜像有两种方式:docker commit命 ...
- (转)Docker镜像构建上下文(Context)
镜像构建上下文(Context) Docker在构建镜像时,如果注意,会看到 docker build 命令最后有一个 ... 表示当前目录,而 Dockerfile 就在当前目录,因此不少初学者以为 ...
- sqler sql 转rest api 的docker 镜像构建(续)使用源码编译
sqler 在社区的响应还是很不错的,已经添加了好多数据库的连接,就在早上项目的包管理还没有写明确, 下午就已经有go mod 构建的支持了,同时也调整下docker 镜像的构建,直接使用git cl ...
- Docker镜像构建上下文(Context)
镜像构建上下文(Context) Dicker在构建镜像时,如果注意,会看到 docker build 命令最后有一个 ... 表示当前目录,而 Dockerfile 就在当前目录,因此不少初学者以为 ...
随机推荐
- Python_记一次网站数据定向爬取实现
记一次网站数据定向爬取实现 by:授客 QQ:1033553122 测试环境: Python版本:Python 3.4 Win7 请勿用于商业及非法用途,仅供学习研究用,否则后果自负 数据爬取场景 如 ...
- loadrunner 脚本优化-事务时间简介
脚本优化-事务时间简介 by:授客 QQ:1033553122 事务概念 事务是指用户在客户端做一种或多种业务所需要的操作集(actions),通过事务开始和结束函数可以标记完成该业务所需要的操作内容 ...
- IIS做反向代理重定向到NodeJS服务器
1. 安装ARR 2. 建立虚拟目录并配置URL Rewrite 3. 启动ARR
- 不需要再手写 onSaveInstanceState 了,因为你的时间非常值钱
如果你是一个有经验的 Android 程序员,那么你肯定手写过许多 onSaveInstanceState 以及 onRestoreInstanceState 方法用来保持 Activity 的状态, ...
- Linux平台下RMAN异机恢复总结
下面总结.整理一下RMAN异机恢复这方面的知识点,这篇笔记在个人笔记里面躺了几年了,直到最近偶然被翻看到,遂整理.总结一下.如下所示,个人将整个RMAN异机恢复分为准备工作和操作步骤两大部分.当然,准 ...
- Greenplum源码安装(CentOS 7)
最近在看GP,在安装集群的时候遇到了很多问题,在此记录下来. 目录 1 安装环境及软件版本 2 安装准备工作 2.1 修改hosts(所有机器) 2.2 修改系统内核配置(所有机器) 2.3 关闭 ...
- c/c++线性队列
线性队列 队列是先进先出,和栈相反. 不循环的队列就是浪费空间,如果tail到了最大值后,即使前面出队了,有空的位置,也不能再入队. seqqueue.h #ifndef __SEQQUEUE__ # ...
- php中jpgraph库的使用
用Jpgraph,只要了解它的一些内置函数,可以轻松得画出折线图.柱形图.饼状图等图表. 首先要保证PHP打开了Gd2的扩展: 打开PHP.ini,定位到extension=php_gd2.dll,把 ...
- LeetCode算法题-Reverse String(Java实现)
这是悦乐书的第205次更新,第217篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第73题(顺位题号是344).编写一个以字符串作为输入并返回字符串的函数.例如: 输入: ...
- Python语法基础-函数,类以及调试处理
[TOC] 1. 函数的定义 python中函数有两种: python自带的函数 用户定义函数 返回多个值 原来返回值是一个tuple!但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同 ...