docker打包golang應(yīng)用的過(guò)程分析
一、錯(cuò)誤的打包方式
在本地環(huán)境編譯,然后將可執(zhí)行程序放入 alpine(docker.io/alpine:latest)
1.準(zhǔn)備web程序
package main
import (
"fmt"
"net/http"
)
func main() {
server := &http.Server{
Addr: ":8888",
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "hello world")
})
fmt.Println("server startup...")
if err := server.ListenAndServe(); err != nil {
fmt.Printf("server startup failed, err:%v\n", err)
}
}go build hello.go
2.dockerfile
FROM docker.io/alpine:latest MAINTAINER demo <juest a demo> #alpine內(nèi)的包管理 RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/main" > /etc/apk/repositories #安裝bash RUN apk add --update bash && rm -rf /var/cache/apk/* RUN mkdir -p /data/go COPY hello /data/go EXPOSE 8888 ENTRYPOINT ["/data/go/hello"]
3.構(gòu)建鏡像
docker build -t demo/go-hello:1.0 -f dockerfile .
4.將在本地生成將demo/go-hello:1.o鏡像

5.創(chuàng)建并運(yùn)行容器

原因:編譯的hello二進(jìn)制程序不是存靜態(tài)程序,還依賴一些庫(kù),但這些庫(kù)在alpine鏡像中找不到。
二、正確的打包流程
需要放入alpine鏡像里運(yùn)行的go程序,可以直接使用golang:alpine來(lái)編譯,但我們?cè)趃olang:alpine基礎(chǔ)上再構(gòu)建一個(gè)鏡像,這個(gè)鏡像中包含bash、GO111MODULE、GOPROXY等環(huán)境變量。
1.dockerfile
FROM docker.io/golang:alpine
RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/main" > /etc/apk/repositories
RUN apk add --update bash && rm -rf /var/cache/apk/*
# 為我們的鏡像設(shè)置必要的環(huán)境變量
ENV GO111MODULE=on \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64\
GOPROXY=https://goproxy.cn,direct2.構(gòu)建自己的go編譯鏡像
docker build -t go-build:1.0 -f dockerfile .

3.運(yùn)行g(shù)o-build:1.0 鏡像,編譯go項(xiàng)目代碼:
#xxx為本地go代碼路徑 docker run -it --rm -v xxx:/data/go demo/go-build:1.0 /bin/bash cd /data/go go build hello.go
生成了hello可執(zhí)行文件,且為純靜態(tài)的。

將編譯得到的hello二進(jìn)制打入alpine:latest
dockerfile2
FROM docker.io/alpine:latest MAINTAINER demo <juest a demo> #alpine內(nèi)的包管理 RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/main" > /etc/apk/repositories #安裝bash RUN apk add --update bash && rm -rf /var/cache/apk/* RUN mkdir -p /data/go COPY hello /data/go EXPOSE 8888 ENTRYPOINT ["/data/go/hello"]
5.打包
docker build -t demo/go-hello:1.0 -f dockerfile2 .
6.運(yùn)行demo/go-hello:1.0

三、使用scratch構(gòu)建鏡像
scratch為空鏡像,適合那些沒(méi)有任何外部依賴的程序,剛好前面的hello程序沒(méi)有任何依賴!
1.dockerfile3
FROM scratch MAINTAINER demo <juest a demo> COPY hello / EXPOSE 8888 ENTRYPOINT ["/hello"]
2.構(gòu)建
docker build -t demo/go-hello:2.0 -f dockerfile3 .
3.以scratch為基礎(chǔ)構(gòu)建出來(lái)的鏡像是最小的

運(yùn)行

四、參考以太坊的打包
目錄結(jié)構(gòu)

dockerfile
# Support setting various labels on the final image
ARG COMMIT=""
ARG VERSION=""
ARG BUILDNUM=""
# Build Geth in a stock Go builder container
FROM golang:alpine as builder
RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/main" > /etc/apk/repositories
RUN apk add --no-cache gcc musl-dev linux-headers git
ENV GO111MODULE=on \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64\
GOPROXY=https://goproxy.cn,direct
# Get dependencies - will also be cached if we won't change go.mod/go.sum
COPY go.mod /web/
COPY go.sum /web/
RUN cd /web && go mod download
ADD . /web
RUN cd /web && go build -o ./cmd/app main.go
# Pull Geth into a second stage deploy alpine container
FROM alpine:latest
RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/main" > /etc/apk/repositories
RUN apk add --no-cache ca-certificates
COPY --from=builder /web/cmd/app /usr/local/bin/
EXPOSE 8080
ENTRYPOINT ["app"]
# Add some metadata labels to help programatic image consumption
ARG COMMIT=""
ARG VERSION=""
ARG BUILDNUM=""
LABEL commit="$COMMIT" version="$VERSION" buildnum="$BUILDNUM"
到此這篇關(guān)于docker打包golang應(yīng)用的文章就介紹到這了,更多相關(guān)docker打包golang應(yīng)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
docker安裝java環(huán)境的實(shí)現(xiàn)步驟
這篇文章主要介紹了docker安裝java環(huán)境的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
docker寫(xiě)一個(gè)Dockerfile文件的實(shí)現(xiàn)
Dockerfile 是一個(gè)用來(lái)構(gòu)建鏡像的文本文件,文本內(nèi)容包含了一條條構(gòu)建鏡像所需的指令和說(shuō)明,本文主要介紹了docker寫(xiě)一個(gè)Dockerfile文件的實(shí)現(xiàn)2024-01-01
Docker部署Kafka以及Spring Kafka實(shí)現(xiàn)
這篇文章主要介紹了Docker部署Kafka以及Spring Kafka實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
詳解docker pull 下來(lái)的鏡像文件存放的位置
本篇文章主要介紹了詳解docker pull 下來(lái)的鏡像文件存放的位置,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-04-04

