Dockerfile参数详解

ADD与COPY的区别

ADD
1、若源路径是个文件,且目标路径是以/结尾,则docker会把目标路径当作一个目录,会把源文件拷贝到该目录下,若目标路径不存在,则会自动创建目标路径
2、若源路径是个文件,且目标路径不以/结尾,则docker会把目标路径当作一个文件,若目标路径不存在,则会以目标路径为名创建一个文件,内容同源文件
若目标文件存在,会用源文件覆盖,但只是内容覆盖,文件名还是目标文件
若目标文件是个目录,则源文件会拷贝到该目录下,注意这种情况最好以/结尾,以避免混淆
3、若原路径是个目录,且目标路径不存在,则docker会自动以目标路径创建一个目录,将原路径目录下的文件拷贝进来
若目标路径已存在,则docker会把源路径目录下的文件拷贝到该目录下
4、若源文件是个归档文件,则docker会自动解压
COPY
COPY只有ADD的部分功能,只复制文件或目录

多段FROM

FROM
该指令主要是拉取基础镜像,从docker17.05以后可以在Dockerfile里编写多个FROM指令,这种新的特性叫做多阶段构建
example1:

FROM muninn/glide:alpine AS build-env
ADD . /go/src/app
WORKDIR /go/src/app
RUN glide install
RUN go build -v -o /go/src/app/app-server

FROM alpine
RUN apk add -U tzdata
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime
COPY --from=build-env /go/src/app/app-server /usr/local/bin/app-server
EXPOSE 80
CMD ["app-server"]

第一个个FROM将代码编译生成执行文件,第二个FROM将生成的执行文件拷贝到当前镜像执行

再来一个例子
阶段构建 Go 程序
example2:

FROM golang:1.13-alpine3.10 AS builder
RUN  apk --update --no-cache add git mercurial subversion bzr ca-certificates 
ENV  GOPROXY=https://[YOUR-USER]:[YOUR-PASSWORD]@proxy.yourcompany.com,direct
WORKDIR /app
COPY . .
RUN go build -o main

FROM alpine:3.10
WORKDIR /app
COPY --from=builder /app/main /usr/local/bin
ENTRYPOINT [ "main" ]

把多个项目编译出来的文件都放到一个镜像里
example3:

# 第一阶段
from debian as build-essential
arg APT_MIRROR
run apt-get update
run apt-get install -y make gcc
workdir /src

# 第二阶段
from build-essential as foo
copy src1 .            # 当前工作目录为src,生成bin1
run make  

# 第三阶段
from build-essential as bar
copy src2 .             # 当前工作目录为src,生成bin2
run make

# 第四阶段
from alpine
copy --from=foo bin1 .   
copy --from=bar bin2 .
cmd ...

ENV

该参数主要是方便在容器内部设置环境变量,这笔使用export要方便许多
给出一个例子

ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV PATH $JAVA_HOME/bin:$PATH