2 回答

TA貢獻1798條經驗 獲得超3個贊
我個人使用govendor。根據 golang 供應商約定,它將您的依賴項保存在項目內的供應商目錄中。這仍然需要在構建時復制到您的 docker 映像中。
但是有很好的理由不供應商。例如,當您構建 pkg 時,您不應該供應商。當您有不同的 pkg 使用不同版本的依賴項時,事情會變得混亂。這可以通過僅供應可執行文件來解決。
因此,如果您有充分的理由不供應商,您可以分開幾個步驟。將它們按正確的順序排列將加快速度。
您可以創建一個 shell 腳本 ( get.sh),其中包含一些go get依賴項命令。(你可以把這些放在你的 Dockerfile 中,但它們有一個行限制)
go get github.com/golang/protobuf/proto
go get github.com/pborman/uuid
go get golang.org/x/net/context
go get golang.org/x/net/http2
go get golang.org/x/net/http2/hpack
然后在您的 Dockerfile 中,您首先復制并執行 shell 腳本。每次更新 get.sh 時,它都會完全重建。它仍然運行got get ./...以確保所有依賴項都存在。但是,如果所有內容都添加到get.sh腳本中,您將獲得不錯的速度提升。
FROM golang:1.6
RUN mkdir -p /go/src/app
COPY get.sh /go/src/app
WORKDIR /go/src/app
RUN bash get.sh
COPY . /go/src/app
RUN go get ./...
CMD go test -v
一般的想法是,您在 Dockerfile 中保持經常更改的內容較低,而頂部的內容則相當穩定。即使您必須添加另一個或兩個命令。Docker 將逐行執行,直到找到需要重建的內容,然后也將執行之后的每一行。

TA貢獻1946條經驗 獲得超3個贊
我一直在尋找您問題的答案,但具有諷刺意味的是,我發現了一個我有答案的問題(如何快速運行 docker 測試)。如果您真的想要快速測試,那么理想情況下,您應該在運行它們時完全避免重建容器。但是等等,如何將新的源代碼放到容器中?卷我的朋友,卷。這是我的設置方式:
碼頭工人-compose.dev.yml:
backend-test:
volumes:
- .:/path/to/myapp
其中 /path/to/myapp 是圖像中的路徑,當然。您必須明確地將此圖像傳遞給開發人員:
docker-compose up -f docker-compose.dev.yml
但是現在,當您運行測試時,您將不再使用 docker-compose,而是將使用 docker exec:
docker exec -it backend-test go test
如果你做對了,你在后端測試容器中的 src 目錄將永遠是最新的,因為它實際上是一個掛載的卷。附加到正在運行的容器并運行測試應該證明比每次都啟動一個新容器要快得多。
編輯:評論者正確地指出,這只會在您的依賴項沒有改變(不需要go get)時避免重建圖像。好處是它不僅避免了重建,而且還避免了重新啟動。當我像這樣進行測試并添加依賴項時,我通常只是go get直接從我的測試控制臺。在容器中工作可能有點棘手,但一種方法是通過掛載 SSH_AUTH_SOCKgo get將 ssh 代理轉發到容器. 遺憾的是,您無法在構建期間掛載卷,因此如果您希望構建目標能夠在運行測試之前提取新的依賴項,則可能需要在映像中包含某種部署密鑰。但是,我的回答的要點是將構建和測試分開,以避免在您準備好生成最終工件之前進行完整構建。
也就是說,我想我可能理解我沒有按照您提出的方式回答問題。在 ruby 中,答案就像復制 Gemfile 和 Gemfile.lock 并運行一樣簡單bundle install --deploy,然后再復制您更改的代碼。就我個人而言,我不介意添加依賴項時的重建成本,因為我的 99% 的更改仍然不會涉及重建。也就是說,您可能會考慮使用受 golang 啟發的新 Bundler 依賴管理器:dep。安裝了 dep 后,我很確定你可以將你的Gopkg.tomland復制Gopkg.lock到你的工作目錄中,運行dep ensure,然后復制您的代碼。這只會在更新 Gopkg 時提取依賴項 - 否則 docker 將能夠重用緩存層并安裝您以前的依賴項。很抱歉長時間的編輯!
- 2 回答
- 0 關注
- 310 瀏覽
添加回答
舉報