【问题标题】:How to rebuild go project efficiently while using Docker Compose?如何在使用 Docker Compose 的同时高效地重建 go 项目?
【发布时间】:2017-06-11 02:28:46
【问题描述】:

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

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

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

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

作为参考,这是我的Dockerfile

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

我有什么遗漏吗?

【问题讨论】:

  • 您可以尝试加快构建速度的另一件事是使用COPY --from 从以前的 Docker 构建中复制中间构建工件。你可以看看我关于Efficient Docker builds for large monorepos 的文章,其中还介绍了使用多阶段构建减小图像大小,以及充分利用 Docker 构建缓存。

标签: docker go build docker-compose build-time


【解决方案1】:

你问了一个很好的问题。

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 在每个层中输出的“使用缓存”语句,该语句是从先前构建中重用的。

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

【讨论】:

  • 我看到了这条关于新鲜的评论。你能详细说明你将如何设置新鲜吗?
【解决方案2】:

如果你想改进你的 Docker 实现,你可以制作一个更小的镜像。我建议“多阶段构建”来做到这一点

此构建的图像大小约为 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

使用多阶段构建,图像权重是二进制的大小和一个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

使用多阶段构建,您将使用一个重映像来构建应用程序,而另一个非常小的映像来运行您的应用程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 2018-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    相关资源
    最近更新 更多