docker-go
package main
import (
"fmt"
"html"
"log"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
})
http.HandleFunc("/hi", func(w http.ResponseWriter, r *http.Request){
fmt.Fprintf(w, "Hi")
})
log.Fatal(http.ListenAndServe(":8083", nil))
}
进入全屏模式 退出全屏模式
如果我们想运行这个 go run main.go ,它将在http://localhost:8083上启动服务器。
写Dockerfile
## We specify the base image we need for our
## go application
FROM golang:1.16-alpine
## We create an /app directory within our
## image that will hold our application source
## files
RUN mkdir /app
## We copy everything in the root directory
## into our /app directory
ADD . /app
## We specify that we now wish to execute
## any further commands inside our /app
## directory
WORKDIR /app
## we run go build to compile the binary
## executable of our Go program
RUN go build -o main .
## Our start command which kicks off
## our newly created binary executable
CMD ["/app/main"]
进入全屏模式 退出全屏模式
运行以下命令以创建 docker 映像
码头工人建造-t码头工人去。
它将构建代码并在您的终端中显示以下输出
C:\work\latest\docker-go>docker build -t docker-go .
[+] Building 38.4s (10/10) FINISHED
=> [internal] load build definition from Dockerfile 0.2s
=> => transferring dockerfile: 643B 0.0s
=> [internal] load .dockerignore 0.2s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/golang:1.12.0-alpine3.9 3.2s
=> [1/5] FROM docker.io/library/golang:1.12.0-alpine3.9@sha256:6c143f415448f883ed034529162b3dc1c85bb2967fdd1579a8735 29.4s
=> => resolve docker.io/library/golang:1.12.0-alpine3.9@sha256:6c143f415448f883ed034529162b3dc1c85bb2967fdd1579a87356 0.1s
=> => sha256:69371d496b2b4e99120216fa3c5057b0c5468411370ab24ea99cd87d7b1d9203 1.36kB / 1.36kB 0.0s
=> => sha256:2205a315f9c751a8c205aa42f29ad0ff29918c40d85c8ddaabac99e0cb46b5d8 3.80kB / 3.80kB 0.0s
=> => sha256:6c143f415448f883ed034529162b3dc1c85bb2967fdd1579a873567b22bcb790 2.37kB / 2.37kB 0.0s
=> => sha256:8e402f1a9c577ded051c1ef10e9fe4492890459522089959988a4852dee8ab2c 2.75MB / 2.75MB 0.7s
=> => sha256:de1a1e452942df2228b914d2ce9be43f18b137f4ebc3dce9491bc08c2630a2ea 154B / 154B 0.7s
=> => sha256:ce7779d8bfe3415e27ec3bf5950b2ab67a854c608595f0f2e49066fb5806fd12 301.88kB / 301.88kB 0.8s
=> => extracting sha256:8e402f1a9c577ded051c1ef10e9fe4492890459522089959988a4852dee8ab2c 0.7s
=> => sha256:a8c461e224a623234c9f2ff60e4249678c9e6847add7152ac80239b13d14df4c 126B / 126B 1.0s
=> => sha256:1bdc943bc000449a960c5121688afe0a9b51837407bf0478391b6bad6642d36f 124.28MB / 124.28MB 15.7s
=> => extracting sha256:ce7779d8bfe3415e27ec3bf5950b2ab67a854c608595f0f2e49066fb5806fd12 0.5s
=> => extracting sha256:de1a1e452942df2228b914d2ce9be43f18b137f4ebc3dce9491bc08c2630a2ea 0.0s
=> => extracting sha256:1bdc943bc000449a960c5121688afe0a9b51837407bf0478391b6bad6642d36f 11.8s
=> => extracting sha256:a8c461e224a623234c9f2ff60e4249678c9e6847add7152ac80239b13d14df4c 0.0s
=> [internal] load build context 0.2s
=> => transferring context: 1.06kB 0.1s
=> [2/5] RUN mkdir /app 1.7s
=> [3/5] ADD . /app 0.3s
=> [4/5] WORKDIR /app 0.2s
=> [5/5] RUN go build -o main . 2.1s
=> exporting to image 0.6s
=> => exporting layers 0.5s
=> => writing image sha256:9bbcb2070c03ab1affa9f2dc62292f1cea589a60c05d4796c4490c0fa31afedb 0.0s
=> => naming to docker.io/library/docker-go
进入全屏模式 退出全屏模式
我们现在可以通过输入 docker images 来验证我们的图像是否存在于我们的机器上:
docker images
进入全屏模式 退出全屏模式
docker-go
为了运行这个新创建的镜像,我们可以使用 docker run 命令并传入我们想要映射到的端口和我们希望运行的镜像。
docker run -p 8083:8083 -it docker-go
进入全屏模式 退出全屏模式
-
p 8083:8083 - 这暴露了我们的应用程序,该应用程序在我们本地机器上的http://localhost:8083上的容器内的端口 8083 上运行。
-
it - 此标志指定我们希望以交互模式运行此映像,并为此容器进程提供一个 tty。
-
docker-go - 这是我们要在容器中运行的映像的名称。
如果我们在浏览器中打开http://localhost:8083,我们应该看到我们的应用程序成功响应了 Hello, "/"。
当我看到 docker 图像大小时,它大约需要 800MB 大小。这对于较小的 go 应用程序来说绝对是巨大的。如果您想减少这种情况,请执行以下步骤
一个简单的多阶段 Dockerfile
为了了解多阶段 Dockerfile 为何有用,我们将创建一个简单的 Dockerfile,其中一个阶段用于构建和运行我们的应用程序,另一个 Dockerfile 具有构建阶段和生产阶段。
一旦我们创建了这两个不同的 Dockerfile,我们应该能够比较它们,并希望自己看到多阶段 Dockerfile 比它们更简单的对应物更受欢迎!
所以,上面的 dockerfile,我们创建了一个非常简单的 Docker 镜像,我们的 Go 应用程序在其中构建和运行。
您应该希望注意到最后一列指出此图像的大小为 800MB。对于构建和运行一个非常简单的 Go 应用程序的东西来说,这绝对是巨大的。
在这个镜像中将包含编译和运行我们的 Go 应用程序所需的所有包和依赖项。使用多阶段 dockerfile,我们实际上可以通过将内容分成两个不同的阶段来显着减小这些图像的大小。
让我们看看我们如何定义一个真正的多阶段 Dockerfile,它将首先编译我们的应用程序,然后在轻量级 Docker alpine 映像中运行我们的应用程序。
接下来,我们将在与上面的 main.go 文件相同的目录中创建一个 Dockerfile。这将包含一个构建器阶段和一个生产阶段,它们将由两个不同的基础映像构建:
## We'll choose the incredibly lightweight
## Go alpine image to work with
FROM golang:1.16-alpine AS builder
## We create an /app directory in which
## we'll put all of our project code
RUN mkdir /app
ADD . /app
WORKDIR /app
## We want to build our application's binary executable
RUN CGO_ENABLED=0 GOOS=linux go build -o main ./...
## the lightweight scratch image we'll
## run our application within
FROM alpine:latest AS production
## We have to copy the output from our
## builder stage to our production stage
COPY --from=builder /app .
## we can then kick off our newly compiled
## binary exectuable!!
CMD ["./main"]
进入全屏模式 退出全屏模式
现在我们已经定义了这个多阶段 Dockerfile,我们可以使用标准的 docker build 命令继续构建它:
docker build -t go-multi-stage .
进入全屏模式 退出全屏模式
现在,当我们将简单图像的大小与多阶段图像进行比较时,我们应该会看到大小的显着差异。我们之前的 docker-go 镜像大小约为 800MB,而这个多阶段镜像的大小约为 1/80。
如果我们想尝试运行它来验证它是否正常工作,我们可以使用以下 docker run 命令来实现:
docker run -d -p 8083:8083 go-multi-stage
进入全屏模式 退出全屏模式
如果我们在浏览器中打开http://localhost:8083,我们应该看到我们的应用程序成功响应了 Hello, "/"。