模板文件

模板一

FROM golang:1.16 as builder
  
WORKDIR /workspace

COPY go.mod go.mod

# RUN go mod download

COPY . .

RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on GOPROXY=https://goproxy.cn,direct go build -a -o server main.go

# FROM gcr.io/distroless/static:nonroot
FROM alpine:latest

WORKDIR /

COPY --from=builder /workspace/server .

# USER nonroot:nonroot

EXPOSE 18080

ENTRYPOINT ["/server"]

模板二

# build时设置版本 --build-arg GO_VERSION=1.13,默认为go1.15
ARG GO_VERSION=1.15
FROM golang:${GO_VERSION} AS builder
ENV GOPROXY="https://goproxy.cn"

ENV APP_PATH="/app/goapp"
WORKDIR "/app"

# 拷贝构建文件
COPY . .

# 编译
RUN go mod download
RUN CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -a -o ${APP_PATH} .
RUN ls 


# 构建运行镜像
FROM alpine:3.10 AS final

ENV APP_PATH="/app/goapp"
WORKDIR "/app"

# 拷贝程序,如有必要另外拷贝其他文件
COPY --from=builder ${APP_PATH} ${APP_PATH} 

# 运行程序
ENTRYPOINT ["/app/goapp"]

Dockerfile ARG指令

ARG用于传入外部参数,定义在FROM指令前,FROM后的其他指令无法使用ARG定义的环境变量,如果FROM指令后的指令要使用ARG定义的值,需要在FROM后再次定义。如果FROM不使用定义的ARG,可以直接定义到FROM后。

传递参数

定义在FROM前

ARG UBUNTU_VERSION=16.04
FROM ubuntu:${UBUNTU_VERSION}
RUN env | grep UBUNTU_VERSION

从结果可以看到FROM后的指令无法访问ARG定义的UBUNTU_VERSION。

$ docker build -t test:afterfrom .
Sending build context to Docker daemon  37.38kB
Step 1/3 : ARG UBUNTU_VERSION=16.04
Step 2/3 : FROM ubuntu:${UBUNTU_VERSION}
 ---> 4b22027ede29
Step 3/3 : RUN env | grep UBUNTU_VERSION
 ---> Running in 8e93ca5e376b
The command '/bin/sh -c env | grep UBUNTU_VERSION' returned a non-zero code: 1

定义在FROM后

ARG UBUNTU_VERSION=16.04
FROM ubuntu:${UBUNTU_VERSION}
ARG UBUNTU_VERSION
RUN env | grep UBUNTU_VERSION

从结果可以看到FROM后的指令可以访问ARG定义的UBUNTU_VERSION。

$ docker build -t test:afterfrom .
Sending build context to Docker daemon  37.38kB
Step 1/4 : ARG UBUNTU_VERSION=16.04
Step 2/4 : FROM ubuntu:${UBUNTU_VERSION}
 ---> 4b22027ede29
Step 3/4 : ARG UBUNTU_VERSION
 ---> Using cache
 ---> e3bae0875e66
Step 4/4 : RUN env | grep UBUNTU_VERSION
 ---> Running in 02438aff1f75
UBUNTU_VERSION=16.04
Removing intermediate container 02438aff1f75
 ---> 646eec496165
Successfully built 646eec496165
Successfully tagged test:afterfrom

传递多个ARG参数

ARG UBUNTU_VERSION=16.04
ARG FILE_NAME=test
FROM ubuntu:${UBUNTU_VERSION}

ARG FILE_NAME
WORKDIR /test/
RUN touch ${FILE_NAME}
RUN ls ${FILE_NAME}

传递多个参数需要多次使用--build-arg,可以看到传递的FILE_NAME=app生效了,而不是默认值。

$ docker build -t test:twoargs --build-arg UBUNTU_VERSION=18.04 --build-arg FILE_NAME=app .
Sending build context to Docker daemon  37.38kB
Step 1/7 : ARG UBUNTU_VERSION=16.04
Step 2/7 : ARG FILE_NAME=test
Step 3/7 : FROM ubuntu:${UBUNTU_VERSION}
18.04: Pulling from library/ubuntu
171857c49d0f: Pull complete
419640447d26: Pull complete
61e52f862619: Pull complete
Digest: sha256:646942475da61b4ce9cc5b3fadb42642ea90e5d0de46111458e100ff2c7031e6
Status: Downloaded newer image for ubuntu:18.04
 ---> 56def654ec22
Step 4/7 : ARG FILE_NAME
 ---> Running in bee623328f35
Removing intermediate container bee623328f35
 ---> 52f803da2959
Step 5/7 : WORKDIR /test/
 ---> Running in fa4542584af1
Removing intermediate container fa4542584af1
 ---> 5ebd782db9b8
Step 6/7 : RUN touch ${FILE_NAME}
 ---> Running in 0cd5723b744d
Removing intermediate container 0cd5723b744d
 ---> 920c6bd75bab
Step 7/7 : RUN ls ${FILE_NAME}
 ---> Running in b94a33093ddf
app
Removing intermediate container b94a33093ddf
 ---> 804bf831059a
Successfully built 804bf831059a
Successfully tagged test:twoargs