[英]docker multi-stage build Go image - x509: certificate signed by unknown authority
I try to build go images in private corp network use docker-multi-stage-build :我尝试在私有公司网络中使用 docker -multi-stage-build构建go图像:
FROM golang:latest as builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN GO111MODULE="on" CGO_ENABLED=0 GOOS=linux go build -o main ${MAIN_PATH}
FROM alpine:latest
LABEL maintainer="Kozmo"
RUN apk add --no-cache bash
WORKDIR /app
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]
and get x509: certificate signed by unknown authority
error并获取x509: certificate signed by unknown authority
错误
Step 1/13 : FROM golang:latest as builder
---> 2421885b04da
Step 2/13 : WORKDIR /app
---> Using cache
---> 6555644dbd16
Step 3/13 : COPY go.mod go.sum ./
---> 55d45a30f492
Step 4/13 : RUN go mod download
---> Running in 88c21c6b4fab
go: github.com/dgrijalva/jwt-go/v4@v4.0.0-preview1: Get "https://proxy.golang.org/github.com/dgrijalva/jwt-go/v4/@v/v4.0.0-preview1.mod": x509: certificate signed by unknown authority
The command '/bin/sh -c go mod download' returned a non-zero code: 1
make: *** [docker] Error 1
I tried to find an answer in我试图在
X509: Certificate Signed by Unknown Authority (Running a Go App Inside a Docker Container) X509:由未知机构签署的证书(在 Docker 容器内运行 Go 应用程序)
and和
docker build: cannot get the github public repository, x509: certificate signed by unknown authority docker build:无法获取 github 公共存储库,x509:证书由未知机构签名
and和
x509 certificate signed by unknown authority - go-pingdom未知权威签署的 x509 证书 - go-pingdom
, but result is the same. ,但结果是一样的。
❗️If add -insecure
flag ❗️如果添加-insecure
标志
...
RUN go env -w GOPROXY=direct GOFLAGS="-insecure"
COPY go.mod go.sum ./
...
to Dockerfile
unrecognized import path
error wrap previous x509
error and an unreachable package change to golang.org/x/crypto
到Dockerfile
unrecognized import path
错误wrap previous x509
error and an unreachable package change to golang.org/x/crypto
go: golang.org/x/crypto@v0.0.0-20200622213623-75b288015ac9: unrecognized import path "golang.org/x/crypto": https fetch: Get "https://golang.org/x/crypto?go-get=1": x509: certificate signed by unknown authority
What is the problem❓有什么问题❓
(I understand that problem is in the certificates and authentication when git
get dependencies, but I try to make process of building images more common) (我知道问题出在git
获得依赖项时的证书和身份验证中,但我尝试使构建映像的过程更常见)
git
uses curl
to access the https
servers so you need to import the certificate into the CA store
of the system. git
使用curl
访问https
服务器,因此您需要将证书导入系统的CA store
中。
The workaround is to define the environment variable GIT_SSL_NO_VERIFY=1
on your Agent environment variables, but it doesn't work when using go get
or go mod download
😭.解决方法是在您的代理环境变量上定义环境变量GIT_SSL_NO_VERIFY=1
,但是在使用go get
或go mod download
不起作用😭。
To import the certificate on your system CA store the procedure depends on your OS you have to use openssl
.要在您的系统 CA 存储中导入证书,该过程取决于您必须使用的操作系统openssl
。
For example例如
FROM golang:latest as builder
RUN apt-get update && apt-get install -y ca-certificates openssl
ARG cert_location=/usr/local/share/ca-certificates
# Get certificate from "github.com"
RUN openssl s_client -showcerts -connect github.com:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > ${cert_location}/github.crt
# Get certificate from "proxy.golang.org"
RUN openssl s_client -showcerts -connect proxy.golang.org:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > ${cert_location}/proxy.golang.crt
# Update certificates
RUN update-ca-certificates
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN GO111MODULE="on" CGO_ENABLED=0 GOOS=linux go build -o main ${MAIN_PATH}
FROM alpine:latest
LABEL maintainer="Kozmo"
RUN apk add --no-cache bash
WORKDIR /app
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]
docker image build
output 👇🏼 docker docker image build
输出👇🏼
...
Step 5/19 : RUN openssl s_client -showcerts -connect github.com:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > ${cert_location}/github.crt
---> Running in bb797e26d4b4
Removing intermediate container bb797e26d4b4
---> 6c68ddafd884
Step 6/19 : RUN openssl s_client -showcerts -connect proxy.golang.org:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > ${cert_location}/proxy.golang.crt
---> Running in 61f59939d75e
Removing intermediate container 61f59939d75e
---> 72d2b03b11e6
Step 7/19 : RUN update-ca-certificates
---> Running in 6cf9aa248776
Updating certificates in /etc/ssl/certs...
2 added, 0 removed; done. 👈🏻 'certificates updated'
...
Step 8/18 : COPY go.mod go.sum ./
---> 436263b76050
Step 9/18 : RUN go mod download 👈🏻 'works fine'
---> Running in 2387c78147db
Removing intermediate container 2387c78147db
---> a37c05c2b531
Step 10/18 : COPY . .
---> 01b49c388f59
...
😭 Coping self certificates ( .crt
) helped 😭应对自我证书( .crt
)有帮助
1️⃣ add .crt
to required dir
1️⃣ 将.crt
添加到所需dir
.
└── backend
├── Dockerfile
├── Makefile
├── cmd
│ └── main.go
├── etc
│ ├── ssl
│ │ └── github.crt #❗️a copy of the self certificate
2️⃣ COPY
certificates to 'builder'-container 2️⃣ COPY
证书到'builder'-container
FROM golang:latest as builder
COPY etc/ssl/ /etc/ssl/certs/ #❗️add certificates to the container
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
I'll suggest a couple of things:我会建议几件事:
latest
size is ~260M, but alpine
is ~100M.你可以在这里看到latest
大小是 ~260M,但alpine
是 ~100M。scratch
, this means, your final docker images does not contain more than your own executable. Golang 非常强大的一点是,您可以在一个名为scratch
的空 docker 镜像中运行它,这意味着,您最终的 docker 镜像所包含的内容不会超过您自己的可执行文件。update-ca-certificates
so that they get included in the final file如果您需要自己的证书,则必须在代码中包含它们并在执行update-ca-certificates
之前复制它们,以便将它们包含在最终文件中Here's an example of the dockerfile with what I explained above这是我上面解释的 dockerfile 的示例
FROM golang:alpine as builder
WORKDIR /app
# This will download all certificates (ca-certificates) and builds it in a
# single file under /etc/ssl/certs/ca-certificates.crt (update-ca-certificates)
# I also add git so that we can download with `go mod download` and
# tzdata to configure timezone in final image
RUN apk --update add --no-cache ca-certificates openssl git tzdata && \
update-ca-certificates
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN GO111MODULE="on" CGO_ENABLED=0 GOOS=linux go build -o main ${MAIN_PATH}
# Golang can run in a scratch image, so that, the only thing that your docker
# image contains is your executable
FROM scratch
LABEL maintainer="Kozmo"
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
# This line will copy all certificates to final image
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
WORKDIR /app
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]
If own certificates replace first docker stage with:如果自己的证书将第一个 docker 阶段替换为:
FROM golang:alpine as builder
WORKDIR /app
RUN apk --update add --no-cache ca-certificates openssl git tzdata
COPY your/cert/path /usr/local/share/ca-certificates/your-cert-name
RUN update-ca-certificates
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN GO111MODULE="on" CGO_ENABLED=0 GOOS=linux go build -o main ${MAIN_PATH}
Because you use own certificates your final Dockerfile
will look like this:因为您使用自己的证书,所以最终的Dockerfile
将如下所示:
FROM golang:alpine as builder
WORKDIR /app
RUN apk --update add --no-cache ca-certificates openssl git tzdata
COPY your/cert/path /usr/local/share/ca-certificates/your-cert-name
RUN update-ca-certificates
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN GO111MODULE="on" CGO_ENABLED=0 GOOS=linux go build -o main ${MAIN_PATH}
FROM scratch
LABEL maintainer="Kozmo"
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
# This line will copy all certificates to final image
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
WORKDIR /app
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]
Feel free to ask me if you have any doubt :)如果您有任何疑问,请随时问我:)
From your error message从你的错误信息
Get "https://proxy.golang.org/github.com/dgrijalva/jwt-go/v4/@v/v4.0.0-preview1.mod": x509: certificate signed by unknown authority获取“https://proxy.golang.org/github.com/dgrijalva/jwt-go/v4/@v/v4.0.0-preview1.mod”:x509:由未知机构签名的证书
It looks like the CA root of proxy.golang.org is not part of the trusted root CAs in your private corp docker environment.看起来 proxy.golang.org 的 CA 根不是您的私有公司 docker 环境中受信任的根 CA 的一部分。
I'd try to install it with :我会尝试安装它:
1 - Get the certificate from proxy.golang.org : 1 - 从 proxy.golang.org 获取证书:
echo -n | openssl s_client -connect proxy.golang.org:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ./golang.cer
If you open golang.cer you should see the certificates chain如果您打开 golang.cer,您应该会看到证书链
2 - install it in your trusted root CAs : 2 - 将其安装在您信任的根 CA 中:
certutil.exe -addstore root golang.cer
...or on Mac : ...或在 Mac 上:
2a - Double click the certificate file (with ".cer" extension) 2a - 双击证书文件(带有“.cer”扩展名)
2b - Choose "System" from the keychain option. 2b - 从钥匙串选项中选择“系统”。 Then press "OK"然后按“确定”
2c - When the following window pops-up, click the "Always Trust" button. 2c - 当以下窗口弹出时,单击“始终信任”按钮。
For me, installing curl and sudo before go helped.对我来说,在 go 之前安装 curl 和 sudo 有帮助。
RUN apt-get update
# If I remove the next two lines, my build fails with the error above.
RUN apt-get -y install curl
RUN apt-get -y install sudo
RUN apt-get -y install golang-go
RUN ["go", "build", "api.go"]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.