​​​​​​​Golang 和 Docker热重载开发和生产配置 - Bartlomiej


在本节中,您将学习如何设置您的 Golang 应用程序以在您的机器上进行本地开发。开发容器的目的是保存所有依赖项(例如:第三方包,如GORM)、基础设施(例如:数据库、内存缓存等)和您的代码,以帮助和改进您的开发。

创建我们的应用程序仓库。

mkdir mullberry-backend
cd mullberry-backend
go mod init github.com/bartmika/mullberry-backend

每次要添加依赖项时,您都会关闭当前正在运行的容器并安装依赖项。按如下方式安装我们的依赖项:

go get github.com/labstack/echo/v4
go get github.com/labstack/echo/v4/middleware@v4.7.2

在项目的根目录中创建一个main.go文件,然后将以下内容复制并粘贴到其中:

package main

import (
    "net/http"
    
"os"

    
"github.com/labstack/echo/v4"
    
"github.com/labstack/echo/v4/middleware"
)

func main() {

    e := echo.New()

    e.Use(middleware.Logger())
    e.Use(middleware.Recover())

    e.GET(
"/", func(c echo.Context) error {
        return c.HTML(http.StatusOK,
"Hello, Docker! <3")
    })

    e.GET(
"/ping", func(c echo.Context) error {
        return c.JSON(http.StatusOK, struct{ Status string }{Status:
"OK"})
    })

    httpPort := os.Getenv(
"HTTP_PORT")
    if httpPort ==
"" {
        httpPort =
"8080"
    }

    e.Logger.Fatal(e.Start(
":" + httpPort))
}

请注意,上面的代码是通过他们的 Docker 文档从“构建你的 Go 映像”复制而来的。

在创建任何与 docker 相关的内容之前,请创建一个.dockerignore文件并复制并粘贴以下内容:

bin
.dockerignore
Dockerfile
docker-compose.yml
dev.Dockerfile
dev.docker-compose.yml
.env

什么是.dockerignore文件?本质上,它类似于.gitignore某些文件/文件夹不会保存到 docker 容器和图像中。

创建dev.Dockerfile文件并将以下内容复制并粘贴到其中。

FROM golang:1.18

# Copy application data into image
COPY . /go/src/bartmika/mullberry-backend
WORKDIR /go/src/bartmika/mullberry-backend

COPY go.mod ./
COPY go.sum ./
RUN go mod download

# Copy only `.go` files, if you want all files to be copied then replace `with `COPY . .` for the code below.
COPY *.go .

# Install our third-party application for hot-reloading capability.
RUN ["go", "get", "github.com/githubnemo/CompileDaemon"]
RUN [
"go", "install", "github.com/githubnemo/CompileDaemon"]

ENTRYPOINT CompileDaemon -polling -log-prefix=false -build=
"go build ." -command="./mullberry-backend" -directory="./"

如果您阅读上面的代码注释,您会注意到 的用法CompileDaemon,那是什么?本质上,这是您的热加载器!它监视目录中的文件并在文件更改时.go调用。go build例如,您在AtomIDE 中打开此项目,对main.go文件进行更改并单击Save,然后CompileDaemon将在容器中重新构建您的 Go 应用程序,以便您看到最新的构建!

创建我们的dev.docker-compose.yml文件:

version: '3.6'

services:
    api:
        container_name: mullberry-backend
        image: mullberry-backend
        ports:
            - 8000:8080
        volumes:
            - ./:/go/src/bartmika/mullberry-backend
        build:
            dockerfile: dev.Dockerfile

等等,为什么我使用dev.这些 Docker 文件名的前缀?原因是因为我想区分 Docker 文件用于生产和开发目的。

在您的终端中,使用以下命令启动开发环境:

$ docker-compose -f dev.docker-compose.yml up
确认我们可以访问它。

$ curl localhost:8000/
您应该在终端中看到以下输出:

Hello, Docker! <3   
如果你看到这个,恭喜你已经准备好开始开发了!如果您想了解更多信息,请随时通过他们的 Docker 文档查看“构建您的 Go 映像”一文。


用于生产的 Golang 和 Docker
本节的目的是让您的 Golang 应用程序容器化并准备好在生产环境中运行。

选项 1:单级
最简单的设置是单阶段构建。这个构建的问题是你的 Docker 镜像会很大!

首先,Dockerfile在您的项目根文件夹中创建一个并将以下内容复制并粘贴到其中:

FROM golang:1.18

# Copy application data into image
COPY . /go/src/bartmika/mullberry-backend
WORKDIR /go/src/bartmika/mullberry-backend

COPY go.mod ./
COPY go.sum ./
RUN go mod download

# Copy only `.go` files, if you want all files to be copied then replace `with `COPY . .` for the code below.
COPY *.go .

# Build our application.
RUN go build -o ./bin/mullberry-backend


EXPOSE 8080

# Run the application.
CMD ["./bin/mullberry-backend"]

然后运行up,你应该看到它工作:

$ docker-compose up


选项 2:多阶段
一个更复杂的设置称为磁盘空间节省的多阶段构建授予。这个想法是你想在一个容器中构建你的 Golang 应用程序,然后将它移动到另一个更小的容器中,从而留下磁盘空间沉重的容器。

如果您想尝试一下,Dockerfile请在您的项目根文件夹中创建一个并将以下内容复制并粘贴到其中:

##
## Build
##
FROM golang:1.18-alpine as dev-env

# Copy application data into image
COPY . /go/src/bartmika/mullberry-backend
WORKDIR /go/src/bartmika/mullberry-backend

COPY go.mod ./
COPY go.sum ./
RUN go mod download

# Copy only `.go` files, if you want all files to be copied then replace `with `COPY . .` for the code below.
COPY *.go .

# Build our application.
# RUN go build -o /go/src/bartmika/mullberry-backend/bin/mullberry-backend
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -gcflags "all=-N -l" -o /server

##
## Deploy
##
FROM alpine:latest
RUN mkdir /data

COPY --from=dev-env /server ./
CMD [
"./server"]

然后运行up,你应该看到它工作:

$ docker-compose up