如何在使用 Docker Compose 的同时有效地重建 go 项目?

How to rebuild go project efficiently while using Docker Compose?

这可能是一个愚蠢的问题,但我是使用 Docker-compose 的新手。到目前为止,我喜欢它……但是我的构建时间很长。我有一个具有多个依赖项的项目,显然每次进行更改时我都需要重建源代码。现在,我正在调用 docker-compose build 来重建容器,然后调用 docker-compose up。问题是:

  1. 它正在为我对源代码所做的每一次更改重建整个容器(这需要很长时间——获取 dependencies/etc)。这大大减慢了我的速度。

  2. 我真的觉得我应该能够 运行 容器上的命令进行重建,然后重新 运行 可执行文件,就像这样:

    docker-compose run web go build .
    docker-compose run web ./app
    docker-compose run web go build .
    docker-compose restart
    
    这应该可以工作,因为我正在使用卷在主机和容器之间共享代码。不需要重新获取所有依赖项。它不应该使用新构建的可执行文件吗?但是,这并没有反映出内置的更改,端口转发似乎中断了。

作为参考,这是我的Docker文件:

FROM golang:1.8

COPY . /go/src/github.com/codeblooded/test1
WORKDIR /go/src/github.com/codeblooded/test1

RUN echo $PATH
RUN go get -d -v ./...
RUN go install -v ./...

RUN go build -o test1 .
CMD ["test1"]
EXPOSE 3470

还有我的docker-compose.yml文件:

version: '3'
services:
  postgres:
    image: postgres
    volumes:
      - ./db/data/psql:/var/lib/postgresql/data
      - ./db/schema:/db/schema
  redis:
    image: redis
    volumes:
      - ./db/data/redis:/data
  server:
    build: .
    command: test1
    volumes:
      - .:/go/src/github.com/codeblooded/test1
    ports:
      - "3470:3470"
    depends_on:
      - postgres
      - redis

有什么我遗漏的吗?

你问得好。

命令在 Dockerfile 中的顺序非常重要。先放那些不经常变化的东西,然后放那些在每次构建中最有可能变化的东西:

FROM golang:1.8

RUN go get -d -v ./...
RUN go install -v ./...

COPY . /go/src/github.com/codeblooded/test1
WORKDIR /go/src/github.com/codeblooded/test1

RUN echo $PATH

RUN go build -o test1 .
CMD ["test1"]
EXPOSE 3470

当一个层改变关于先前构建的层时,docker 丢弃以下缓存层并再次运行它们,有时会浪费您的时间。

注意docker在每一层输出的“Using cache”语句,它是从以前的构建中重新使用的。

另一个建议,对于您的开发工作,每次更改代码时使用 fresh 自动重新构建您的 go 应用程序。只需将它安装在容器中,然后在 docker-compose.yml

中使用 command: fresh

如果您想改进您的 Docker 实现,您可以制作较小的图像。我建议 "multi-stage builds" 这样做

The image size for this build is like 600mb

FROM golang:1.8

RUN go get -d -v ./...
RUN go install -v ./...

COPY . /go/src/github.com/codeblooded/test1
WORKDIR /go/src/github.com/codeblooded/test1

RUN echo $PATH

RUN go build -o test1 .
CMD ["test1"]
EXPOSE 3470

Using multi-stage builds, the image weight is the size of the binary and a scratch

FROM golang:1.8 as builder

RUN go get -d -v ./...
RUN go install -v ./...

COPY . /go/src/github.com/codeblooded/test1

WORKDIR /go/src/github.com/codeblooded/test1

RUN echo $PATH
RUN CGO_ENABLED=0 GOOS=linux go build -o test1 .


FROM alpine:latest

RUN apk --no-cache add ca-certificates

WORKDIR /go/src/github.com/codeblooded/

COPY --from=builder /go/src/github.com/codeblooded/test1 .

CMD ["test1"]

EXPOSE 3470

使用多阶段构建,您正在使用一个沉重的图像来构建应用程序,而另一个非常小的图像用于 运行 您的应用程序。