在Docker和VSCode上搭建Go环境(支持热加载)

首先 / 先从…(说起) / 开始时 / 起初

最近因为个人开发,我开始频繁地使用Go语言。在使用Go语言进行开发时,我有了以下的感受:

    • Dockerで動かしたい

 

    • ホットリロード機能が欲しい

 

    • 開発用・本番用でコンテナを分けたい

 

    開発時は、VSCode上でコンテナ内とリモート接続して作業したい

我根据许多人的Docker环境创建了一个用于Go的Docker环境。
如果方便的话,请参考一下。

主机环境

    • Docker: ver.19.03.8

 

    • docker-compose: ver.1.25.4

 

    VSCode: ver.1.43.0

热加载

在研究Go语言进行热加载时,我发现了一个信息。

    • fresh

 

    realize

我了解到了有这样的情况存在。
可是,作者意识到实现部分出现错误(错误:返回了非零代码:1),因此无法进行go get操作。

我们试图启动一个容器,并在容器内执行”go get”命令,但是无法解决问题。

因此,今次我們將使用「新鮮」。

操作步骤

    1. 创建Dockerfile(用于开发和生产)+ docker-compose.yml

 

    1. 配置远程容器

 

    1. 配置热重载

 

    1. 启动开发环境

 

    1. 确认开发环境运行正常

 

    启动生产环境

软件开发环境

首先,我们会创建一个工作目录。

# 作業ディレクトリ作成
$ mkdir go-work
# 作業ディレクトリへ移動
$ cd go-work

创建 Dockerfile(开发版&生产版) + docker-compose.yml

接下来,我们将编写Dockerfile和docker-compose.yml文件。
请使用以下命令创建文件。

$ touch docker-compose.yml
$ mkdir -p docker/golang
$ touch docker/golang/Dockerfile.dev
$ touch docker/golang/Dockerfile.dep

※ Dockerfile的语言支持

由于VSCode并没有对Dockerfile.dev(.dep)进行语言支持,因此需要添加设置。
如果您已经进行了相应的设置,请跳过此步骤。

    1. [代碼] -> [基礎設置] -> [設定]

文件:檔案關聯在搜尋

透過 settings.json 進行編輯

{
  "files.associations": { 
    "Dockerfile.dev": "dockerfile",
    "Dockerfile.dep": "dockerfile"
  }
}

Docker 和 docker-compose 的配置。

    開発用Dockerfile
FROM golang:1.14.0-alpine3.11

SHELL ["/bin/ash", "-c"]
WORKDIR /go/src/app
COPY ./app ./
EXPOSE 8080
ENV GO111MODULE=on

RUN apk add --no-cache alpine-sdk

# Golang ホットリロード(freshのインストール)
RUN go get github.com/pilu/fresh

# Golang 環境構築(任意)
RUN go get github.com/go-delve/delve/cmd/dlv \
    github.com/rogpeppe/godef \ 
    golang.org/x/tools/cmd/goimports \
    golang.org/x/tools/cmd/gorename \
    sourcegraph.com/sqs/goreturns \
    github.com/ramya-rao-a/go-outline \
    golang.org/x/tools/gopls@latest
    本番用Dockerfile
FROM golang:1.14.0-alpine3.11 as builder

WORKDIR /go/src/app
COPY ./app ./
ENV GO111MODULE=on 
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o /go/bin/app

FROM alpine:latest

RUN apk --no-cache add ca-certificates
COPY --from=builder /go/bin/app /go/bin/app
ENTRYPOINT [ "/go/bin/app" ]
EXPOSE 8080
    docker-compose
version: '3.7'

services:
  app:
    container_name: go-app
    build:
      context: .
      # Remote Containerが立ち上がるまで待機
      dockerfile: docker/golang/Dockerfile.dev
    ports:
      - 8080:8080
    volumes:
      - ./app:/go/src/app:cached
    command: /bin/ash -c "while sleep 1000; do :; done"

2. 远程容器的配置

安装

如果您没有安装,请从 Remote-Containers 进行安装。

筹备或准备

01-icon.png
02-remote-containers.png

请从 ‘docker-compose.yml’ 中进行选择。

03-remote-containers.png

选择后,将创建.devcontainer目录并存储配置文件。

设定

.devcontainer
    ├── devcontainer.json
    └── docker-compose.yml

首先,由于docker-compose.yml已经被创建,所以请删除.devcontainer内的docker-compose.yml文件。

请执行以下命令以删除文件。

$ rm .devcontainer/docker-compose.yml

接下来,我们要编辑devcontainer.json文件。

{
  "name": "go",
  "dockerComposeFile": [
    "../docker-compose.yml"
  ],
  "service": "app",
  "workspaceFolder": "/go/src/app",
  "settings": { 
    "terminal.integrated.shell.linux": "/bin/ash",
    "go.gopath": "/go"
  },
  "extensions": [
    "ms-vscode.go",
  ],
  "shutdownAction": "stopCompose"
}

3. 热重载的配置

備妥

首先,创建一个用于开发Go应用程序的工作目录。
然后,创建一个用于热重载的fresh配置文件。

顺便说一句,您无需创建配置文件,这是可选的!

请执行下面的命令。

$ mkdir app
$ cd app
# /go-work/app
$ touch .fresh.conf

设定

root:              .
tmp_path:          ./tmp
build_name:        runner-build
build_log:         runner-build-errors.log
valid_ext:         .go, .tpl, .tmpl, .html
no_rebuild_ext:    .tpl, .tmpl, .html
ignored:           assets, tmp
build_delay:       600
colors:            1
log_color_main:    cyan
log_color_build:   yellow
log_color_runner:  green
log_color_watcher: magenta
log_color_app:

上述的设定是从模板中引用的。
细节设定则是可选的!

4. 启动开发环境

好了,现在我们终于要启动容器了。
请从VSCode中点击左下角的图标。

01-icon.png

然后,打开命令面板,然后搜索并选择”在容器中重新打开”。

04-remote-containers.png

然后,屏幕将切换。
在此时,Docker镜像将被创建,并且容器将自动启动。
启动可能需要一些时间,请稍等…

过了一会儿,容器就会与远程主机连接并切换到工作目录。

05-remote-containers.png

在VSCode左下角的图标应该也发生了变化。
在VSCode上打开终端时,会切换到容器内的终端。

/go/src/app #

5. 确认开发环境的运行情况

我們將在容器內進行工作。
為了確認熱重載的運作,我們將開發一個Go程式。

创建 main.go

创建用于开发的文件。

touch main.go
go mod init main

接下来我们将在main.go文件中创建一个简单的Web服务器。

// ...省略
func init() {
  http.HandleFunc("/", index)
}

func index(w http.ResponseWriter, r *http.Request) {
  fmt.Fprint(w, "Hello World")
}

func main() {
  fmt.Print("Server Start")
  if err := http.ListenAndServe(":8080", nil); err != nil {
    panic(err)
  }
}

执行

我将运行main.go,但这次将使用fresh来执行。
虽然可以在VSCode容器内执行,但是由于我想在开发时使用它,所以这次我会在另一个终端中执行。

在另一个终端中进入容器,并启动热重载功能。

$ docker exec -it go-app /bin/ash

# コンテナ内: /go/src/app
fresh -c .fresh.conf

由于 main.go 被执行,我们开始确认工作。

确定

确认可以在浏览器或终端中进行确认。

    • ブラウザの場合は、http://localhost:8080 にアクセス

 

    ターミナルの場合は、curl http://localhost:8080 を実行

如果收到“Hello World”,说明已成功启动。

改变

请继续保持 fresh 的运行状态,然后返回到 VSCode,以确认热重载是否正常启动。

请在VSCode上修改并保存main.go文件。

func index(w http.ResponseWriter, r *http.Request) {
  - fmt.Fprint(w, "Hello World")
  + fmt.Fprint(w, "Hello Golang")
}

保存后,请再次进行确认工作。
如果返回了Hello Golang,那么热重载已成功启动。

6. 启动正式环境

只需要构建和运行Docker容器即可在生产环境中使用。

建立形象

$ docker build -t go-app -f ./docker/golang/Dockerfile.dep .

容器运行

$ docker run --name go-app go-app -p 8080:8080 -d . /bin/ash
广告
将在 10 秒后关闭
bannerAds