如何在使用Docker Compose时高效地重建Go项目?

huangapple go评论73阅读模式
英文:

How to rebuild go project efficiently while using Docker Compose?

问题

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

  1. 每次我对源代码进行更改时,它都会重新构建整个容器(这需要很长时间--获取依赖项等)。这严重拖慢了我的速度。

  2. 我真的觉得我应该只需在容器上运行一个命令来重新构建并重新运行可执行文件,像这样:

docker-compose run web go build .
docker-compose run web ./app

或者

docker-compose run web go build .
docker-compose restart

这应该可以工作,因为我使用了一个卷来在主机和容器之间共享代码。不应该需要重新获取所有的依赖项。它不应该使用新构建的可执行文件吗?然而,这样做并没有反映出构建的更改,并且端口转发似乎出现了问题。

供参考,这是我的_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

我是否漏掉了什么?

英文:

This may be a stupid question, but I'm new to using Docker-compose. So far, I love it... but I'm having some long build times. I have a project with several dependencies, and I need to obviously rebuild the source every time I make a change. Right now, I'm calling docker-compose build to rebuild the container, followed by a docker-compose up. The problem is:

  1. It's rebuilding the entire container for every change I make to the source code (which takes a long time -- fetching dependencies/etc). This is significantly slowing me down.

  2. I really feel like I should just be able to run a command on the container to rebuild and then re-run the executable, like-so: <pre>
    docker-compose run web go build .
    docker-compose run web ./app</pre> or <pre>
    docker-compose run web go build .
    docker-compose restart
    </pre> This should work because I'm using a volume to share code amongst the host and container. There shouldn't be a need to refetch all the dependencies. Shouldn't it use the freshly built executable? However, this does not reflect the built changes and port forwarding appears to break.

For reference, here is my 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 [&quot;test1&quot;]
EXPOSE 3470

And my docker-compose.yml file:

version: &#39;3&#39;
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:
      - &quot;3470:3470&quot;
    depends_on:
      - postgres
      - redis

Is there something I'm missing?

答案1

得分: 12

你提出了一个很好的问题。

在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即可。

英文:

You have asked a good question.

The command's order in the Dockerfile really matters. Put first the things that don't change frequently, and later those that are most likely to change in every build:

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 [&quot;test1&quot;]
EXPOSE 3470

When a layer change regarding the previous build, docker discards the following cached layers and runs them again, sometimes wasting your time.

Pay attention to the "Using cache" sentence that docker outputs in each layer that is re-used from the previous build.

Another recommendation, for your dev work, use fresh to re-build your go app automatically every time you change the code. Just install it in the container and simply using command: fresh in your docker-compose.yml

答案2

得分: 3

如果你想改进你的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

使用多阶段构建,镜像的大小只有二进制文件的大小和一个空白镜像

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

使用多阶段构建,你可以使用一个较大的镜像来构建应用程序,然后使用一个更小的镜像来运行你的应用程序。

英文:

And if you want to improve your Docker impl, you can make a smaller image. I suggest "multi-stage builds" to do that

> 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 [&quot;test1&quot;]
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 [&quot;test1&quot;]

EXPOSE 3470

Using multi-stage builds you are using a heavy image for build the app and another really smaller for run your app.

huangapple
  • 本文由 发表于 2017年6月11日 10:28:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/44479847.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定