2017-07-28 20 views
0

我正在我的dockfile中下載1.6 GB的二進制壓縮文件,然後使用gunzip將其解壓縮,從而導致存儲3.6 GB文件。我不希望它會一直重複,因爲它需要很長時間。它是一個靜態文件,所以每次使用Jenkins/docker將更改部署到服務器時都不應下載它。但是,每次下載時,我都會進行更改,然後運行Jenkins來部署它們。如何避免Dockerfile中的大型二進制文件緩存失效(Python_Onbuild)

這裏是我的搬運工文件:

FROM python:2.7.13-onbuild 

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

ARG DEBIAN_FRONTEND=noninteractive 
RUN apt-get update && apt-get install --assume-yes apt-utils 
RUN apt-get update && apt-get install -y curl 
RUN apt-get update && apt-get install -y unzip 
RUN curl -o - https://s3.amazonaws.com/dl4j-distribution/GoogleNews-vectors-negative300.bin.gz \ 
| gunzip > /usr/src/app/GoogleNews-vectors-negative300.bin 

UPDATE: 我改變了dockfile到一個簡單的下面給出:

FROM python:2.7.13-onbuild 

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

RUN echo "Test Cache" 

CMD /usr/local/bin/gunicorn -t 240 -k gevent -w 1 -b 0.0.0.0:8000 --reload src.wsgi:app 

現在,如果我不改變代碼或任何其他文件,這工作正常,所以命令echo "test cache"不重複。但是,只要我對源文件夾中的任何文件進行了任何更改,就會重複執行以下步驟後的所有命令,我認爲它們將源代碼複製到了docker目錄中。這不應該發生在這個階段,因爲這意味着我做任何提交後,所有的命令都會重複。

下面是當我沒有對代碼做任何更改,並且第二次運行生成的輸出:

Sending build context to Docker daemon 239.1kB 
Step 1/6 : FROM python:2.7.13-onbuild 
# Executing 3 build triggers... 
Step 1/1 : COPY requirements.txt /usr/src/app/ 
---> Using cache 
Step 1/1 : RUN pip install --no-cache-dir -r requirements.txt 
---> Using cache 


Step 1/1 : COPY . /usr/src/app 
    ---> Using cache 
    ---> 1911c6dc9fce 

Step 2/6 : RUN mkdir -p /usr/src/app 
---> Using cache 
---> 4019b029d05c 
Step 3/6 : WORKDIR /usr/src/app 
---> Using cache 
---> 1a99833e908c 
Step 4/6 : RUN echo "Test Cache" 
---> Using cache 
---> 488a62aa1b09 

這裏就是我做一個切換到一個源文件和輸出你可以看到回聲「測試緩存」重複。

Sending build context to Docker daemon 239.1kB 
Step 1/6 : FROM python:2.7.13-onbuild 
# Executing 3 build triggers... 
Step 1/1 : COPY requirements.txt /usr/src/app/ 
---> Using cache 
Step 1/1 : RUN pip install --no-cache-dir -r requirements.txt 
---> Using cache 


Step 1/1 : COPY . /usr/src/app 
    ---> 6fd1003e246a 
    Removing intermediate container f25a4d2910cf 
    Step 2/6 : RUN mkdir -p /usr/src/app 
    ---> Running in ff324f381875 
    ---> 3694086a2b6a 
    Removing intermediate container ff324f381875 
    Step 3/6 : WORKDIR /usr/src/app 
    ---> 5f23ab9a15df 
    Removing intermediate container 0b0d796f97d0 
    Step 4/6 : RUN echo "Test Cache" 
    ---> Running in 296d2f141015 
    Test Cache 
    ---> f90c7708d9eb 
+0

可以粘貼您的構建日誌在這裏? –

+0

@WassimDhif我不能把所有的日誌,在這裏,因爲這將是太多,但我只是把一個有關這個特定的命令。更新了問題。 – utengr

回答

2

所有我的命令被重複因爲我用python:2.7.13-onbuild爲基本圖像。這是docker-file看起來像這樣:

FROM python:2.7 

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

ONBUILD COPY requirements.txt /usr/src/app/ 
ONBUILD RUN pip install --no-cache-dir -r requirements.txt 

ONBUILD COPY . /usr/src/app 

當我用這個作爲基礎鏡像,複製命令是在我的搬運工文件中的命令之前執行這個複製命令每次我做任何改變的時間變化的背景下源代碼。

我建議使用Python:2.7作爲基礎圖像直接所以具有高於這個複製操作更多的控制。我的新碼頭文件如下,最後的複製命令解決了問題。

FROM python:2.7 

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

ARG DEBIAN_FRONTEND=noninteractive 
RUN apt-get update && apt-get install --assume-yes apt-utils 
RUN apt-get update && apt-get install -y curl 
RUN apt-get update && apt-get install -y unzip 
RUN curl -o - https://s3.amazonaws.com/dl4j-distribution/GoogleNews-vectors-negative300.bin.gz \ 
| gunzip > /usr/src/app/GoogleNews-vectors-negative300.bin 

COPY requirements.txt /usr/src/app/ 
RUN pip install --no-cache-dir -r requirements.txt 

COPY . /usr/src/app 

根據這個documentation,通常不鼓勵使用Python_onbuild圖像。

這種解釋是由我在同一個問題的其他問題的答案啓發: Which Python variant to use as a base image in dockerfiles?

0

的問題來自於對上下文元數據文件在每個版本的變化,因爲你是在詹金斯管道運行它的事實。因此,docker build命令無法使用其緩存。

你可以嘗試做的是把這個大文件放在Jenkins機器上,然後在Dockerfile中引用本地文件。這樣您就不必在每次構建時重新下載它。

+0

不知道這是否是一種好的做法,因爲這樣我可以將文件放到我的生產服務器上,並且可以避免下載它。這也意味着我每次運行構建過程時都會重複所有docker文件命令。是不是有一個解決方法,因爲它有點讓整個緩存概念在詹金斯無用。 – utengr

+0

你能確認你所有的Dockerfile指令都沒有使用緩存嗎?在開始時嘗試一個虛擬的,像'RUN echo'cache test''來檢查這個。如果它不使用緩存,那麼問題來自Jenkins構建系統,正如我前面所說的。我不知道任何解決方法,但我會盡量檢查。 –

+0

看到我的答案是重複的主要原因。 – utengr

0

使用運行apt-get更新& &易於得到安裝-y確保您的Dockerfile安裝,沒有進一步的編碼或人工干預的最新版本的包。這種技術被稱爲「緩存破壞」。您也可以通過指定軟件包版本來實現緩存清除。

您的安裝指示會按照Best practices for dockerfiles中所述解除緩存。任何不是高速緩存的指令都會導致所有其他指令再次執行。

確保您的指令不會失效,除非必要,並將所有不會使緩存失效的指令儘可能放在dockerfile中。在你的情況下,把curl放在dockerfile中更高,你應該沒問題。

希望有所幫助。

---- UPDATE

由於您更新了問題,我會更新我的答案。

  • 緩存未命中後的每個操作都將在構建期間執行。將導致緩存未命中的操作儘可能放在dockerfile中。
  • 將文件複製到你的容器,如果他們改變了

WORKDIR /usr/src/app操作是一個造成問題,因爲它直接複製該文件夾中的所有文件會導致緩存未命中。儘可能低地移動該操作,並重復其他操作導致問題。

+0

那就對了。但是,我需要在我的下載命令使用curl和gunzip之前安裝curl和unzip。有什麼可以替代的? – utengr

+0

使用捲曲的基礎圖像。或者改變命令,使其不再緩存破壞(我認爲如果你不更新它不會破壞緩存)。您也可以手動複製二進制 – herm

+0

安裝捲曲或者你可以創建在其中安裝捲曲等,並基於該圖像上做下載在另一dockerfile一個新的基本映像。 – herm