Docker-Compose:使用需要相对导入的Dockerfile进行组合

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

Docker-Compose: Composing with Dockerfiles that need relative imports

问题

开始,这是我的项目层次结构:

myproj/
    - commons1/
        - com1_file1.go
        - ...
    - commons2/
        - com2_file1.go
        - ...
    - module1/
        - mod1_file1.go
        - Dockerfile
        - ...
    - module2/
        - mod2_file1.go
        - Dockerfile
        - ...
    - docker-compose.yml

我想要的是,当 module1module2 容器启动时,它们各自在其 GOPATH 中都有 commonsN 目录的副本,以便每个容器都可以访问 commonsN 目录中公共库。

例如,我希望在 module1 容器中看到类似于以下内容:

/go/
    - src/
        - commons1/
            - com1_file1.go
            - ...
        - commons2/
            - com2_file1.go
            - ...
        - module1/
            - mod1_file1.go
            - ...

原因是这基本上是我的本地 GOPATH 的样子(当然还有其他模块的添加),这样我就可以在我的源文件中做类似于以下的事情:

package main

import(
    "fmt"
    "myproj/commons1"
)

func main() {
    fmt.Println("Some thing from common library :", commons1.SomethingFromCommons)
}

根据我对 Docker 的初步了解,似乎我不允许修改我的 Dockerfile 来执行类似于 COPY ../commons1 /go/src/commons1 的操作,所以我想知道如何实现这一点?

我强烈不希望使用 Github 的方法,因为源代码都在公司的代理服务器后面,我想象配置所有这些可能比简单复制一些目录要花费更长的时间。

编辑
根据 barat 的建议,我已经更新了我的 docker-compose.yml 文件,大致如下:

version: '2'

services:
    module1:
        volumes:
            - ./commons1:/go/src/myproj/commons1
        build: module1/

module1 的 Dockerfile 如下:

FROM golang:1.8.0

RUN mkdir -p /go/src/app
WORKDIR /go/src/app

COPY . /go/src/app
RUN go get -d -v
RUN go install -v

ENTRYPOINT /go/bin/app

EXPOSE 8080

docker-compose buildgo get -d -v 步骤失败,报错信息为:

>package myproj/commons1: unrecognized import path "myproj/commons1" (import path does not begin with hostname)

如果 myproj/commons1 被复制到 /go/src/ 中,那么这个问题就不应该存在,对吗?我猜这个目录还没有被复制过来?

英文:

To begin, this is my project hierarchy:

myproj/
    - commons1/
        - com1_file1.go
        - ...
    - commons2/
        - com2_file1.go
        - ...
    - module1/
        - mod1_file1.go
        - Dockerfile
        - ...
    - module2/
        - mod2_file1.go
        - Dockerfile
        - ...
    - docker-compose.yml

What I'd like to do is that when module1 and module2 containers start up, they each have a copy of all the commonsN directories in their GOPATH's so that each can access the common libraries exposed by each of the commonsN directories.

For example, I would like to see something like this in the container for module1:

/go/
    - src/
        - commons1/
            - com1_file1.go
            - ...
        - commons2/
            - com2_file1.go
            - ...
        - module1/
            - mod1_file1.go
            - ...

Reason being is that this is basically how my local GOPATH looks (with the addition of the other modules of course) so that I can do something like this in my source files:

package main

import(
    "fmt"
    "myproj/commons1"
)

func main() {
    fmt.Println("Some thing from common library :", commons1.SomethingFromCommons)
}

From my naive understanding of Docker, it appears I'm not allowed to modify my Dockerfiles to do something along the lines of COPY ../commons1 /go/src/commons1, so I'm wondering how I would go about accomplishing this?

I would strongly prefer to not go the Github route since the source code is all behind company proxies and whatnot and I'm imagining configuring all that is going to take way longer than simply copying some directories.

Edit
I have updated my docker-compose.yml file to look something like this per suggestion from barat:

version: '2'

services:
    module1:
        volumes:
            - ./commons1:/go/src/myproj/commons1
        build: module1/

Dockerfile for module1 looks like this:

FROM golang:1.8.0

RUN mkdir -p /go/src/app
WORKDIR /go/src/app

COPY . /go/src/app
RUN go get -d -v
RUN go install -v

ENTRYPOINT /go/bin/app

EXPOSE 8080

docker-compose build fails on the go get -d -v with error:

>package myproj/commons1: unrecognized import path "myproj/commons1" (import path does not begin with hostname)

If myproj/commons1 was copied into /go/src/, then this shouldn't be an issue right? I'm guessing then it hasn't been copied over then?

答案1

得分: 2

你可以构建一个包含commons1commons2的镜像,其他镜像都是基于它们构建的。

FROM golang:1.8.0
RUN mkdir -p /go/src/myproj/commons1 && mkdir -p /go/src/myproj/commons2
COPY commons1/ /go/src/myproj/commons1/
COPY commons2/ /go/src/myproj/commons2/

不过这种方法的缺点是,每当你更新其中一个公共项目时,都需要进行外部构建步骤:

docker build -t me/myproj:commons .

然后,你的组合应用程序可以依赖于commons镜像,而不是golang镜像,并且可以像正常构建一样进行构建,而无需使用卷。

FROM me/myproj:commons
...
英文:

You could build an image including commons1 and commons2 that your other images are based on.

FROM golang:1.8.0
RUN mkdir -p /go/src/myproj/commons1 && mkdir -p /go/src/myproj/commons2
COPY commons1/ /go/src/myproj/commons1/
COPY commons2/ /go/src/myproj/commons2/

The downside is this requires an external build step whenever you update one of the common projects:

docker build -t me/myproj:commons .

Then your compose apps can rely on the commons image instead of golang and build as normal without the volumes.

FROM me/myproj:commons
...

答案2

得分: 0

问题出在go get -d -v命令上,因为它抱怨myproj/commons1没有安装在$GOPATH/src中。我怀疑这是因为Docker Compose在运行docker-compose build之前没有挂载我之前提到的卷。所以我在我的docker-compose.yml中做了一个变通的解决方法,但是这远非优雅:

version: '2'

services:
    module1:
        volumes:
            - ./commons1:/go/src/myproj/commons1
        build: module1/
        ports:
            - "8080:8080"
        command: bash -c "go get -d -v && go install -v && /go/bin/app"

显然,这远非理想,因为每次我运行docker-compose up时,我的Go二进制文件都会被重新构建,而不管我是否运行了docker-compose build

这也是有问题的,因为我想在某些容器中使用dockerize,以等待另一个容器完全启动,现在我觉得这变得非常混乱。

英文:

So problem was the go get -d -v command since it was complaining myproj/commons1 wasn't installed in $GOPATH/src basically. This I of course suspect was because Docker Compose wasn't mounting the volumes I mentioned before it ran the go get on docker-compose build so I made a work around in my docker-compose.yml but it is far from elegant:

version: '2'

services:
    module1:
        volumes:
            - ./commons1:/go/src/myproj/commons1
        build: module1/
        ports:
            - "8080:8080"
        command: bash -c "go get -d -v && go install -v && /go/bin/app

This is obviously far from ideal because my Go binary is rebuilt every time I do a docker-compose up regardless of whether or not I ran docker-compose build.

This is also problematic because I wanted to use dockerize for certain containers to wait until another container has started up completely and it becomes quite messy now I think.

huangapple
  • 本文由 发表于 2017年3月6日 06:12:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/42614704.html
匿名

发表评论

匿名网友

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

确定