2017-09-15 67 views
0

這裏是碼頭工人的新手。我按照here的指示爲我的Go項目製作了一個纖細的&裝飾容器。我不完全理解它在做什麼,希望有人能夠啓發我。這個Docker命令如何生成一個小GoLang容器?

具體來說有兩個步驟來生成這個碼頭集裝箱。

  1. docker run --rm -it -v "$GOPATH":/gopath -v "$(pwd)":/app -e "GOPATH=/gopath" -w /app golang:1.8 sh -c 'CGO_ENABLED=0 go build -a --installsuffix cgo --ldflags="-s" -o hello'
  2. docker build -t myDockerImageName .

的DockerFile本身只包含

FROM iron/base 
WORKDIR /app 
COPY hello /app/ 
ENTRYPOINT ["./hello"] 

我理解(廣義上的)的第一個步驟是編譯圍棋程序和靜態鏈接C依賴關係(並在一個未命名的docker容器中完成所有這些)。第二步根據DockerFile中的指令生成Docker鏡像。

我不明白爲什麼第一個命令是以docker run開頭的(爲什麼它需要在Docker容器中運行?爲什麼我們不只是在它外面生成Go二進制文件,然後將其複製進來? )

如果它在Docker容器中運行,Docker容器中的二進制文件如何在我的本地機器的文件系統上丟失?(例如,爲什麼我需要將二進制文件複製回映像 - 就像它似乎在DockerFile的第3行上做什麼?)

+0

你安裝你的本地目錄,用'-v'標誌卷。參見docker run --help輸出。另外,沒有C依賴關係,你有'CGO_ENABLED = 0'。 – JimB

+0

任何你知道爲什麼需要CGO_ENABLED = 0標誌的機會呢?(在能夠最小化最終碼頭容器輸出的情況下) – nciao

+0

'CGO_ENABLED = 0'和'-a --installsuffix'確保_nothing_是使用cgo構建的,以便生成的二進制文件不被鏈接到任何特定版本的libc。 – JimB

回答

2

你實際上使用了2個不同的docker容器,每個docker容器都有不同的圖像。第一個容器只在編譯期間...它使用圖像golang:1.8。你正在做的是將你當前的工作目錄加載到該圖像中,並使用圖像中包含的GO版本進行編譯。

第二個命令會生成使用熨斗/基礎圖像作爲其基礎的自定義圖像。然後,您將構建的應用程序複製到該映像中並運行它。

+0

你知道我們爲什麼需要使用一個臨時碼頭容器進行編譯嗎? (而不是僅僅編譯它 - 沒有臨時的docker容器)? – nciao

+0

@nciao:你不知道。這只是一個例子。 – JimB

1

使用golang容器構建二進制,則通常用於構建過程的可重複性,即:

  • 它可以確保始終使用相同的圍棋版本,
  • 彙編發生在一個送花兒給人清潔的環境,
  • 和構建主機不需要去安裝在所有的,或者可以有不同的版本,

這種方式,打造的「你好」圖像CA所需的全部零件n在版本控制系統中被跟蹤。

但是,這個例子裝載了整個本地GOPATH,擊敗了上述目的。構建容器必須具有相關性,例如,通過售賣他們。也許作者認爲他的示例超出了範圍。

(注:這應該是一個評論,但我的名譽不允許)

+0

是的,你只需要潛伏一段時間,然後oyu獲得足夠的評論。看到這裏就代表提示:https://meta.stackexchange.com/questions/139661/how-to-get-initial-reputation-on-stack-overflow-with-the-new-user-restrictions-i – jdv

+0

是它可以把所有的音量安裝(或者,只是拉我的滑翔依賴)和建設步入DockerFile本身? (所以構建Docker鏡像也會在其內部構建Go二進制文件)? – nciao

+0

的構建步驟是,但安裝沒有。 Dockerfile VOLUME命令僅在容器內創建裝載點。但是你可以使用泊塢窗,撰寫了點。 – AleGra

相關問題