簡體   English   中英

如何在 Dockerfile 中訪問由 docker-compose 的卷掛載的文件?

[英]How to access files mounted by docker-compose's volumes in a Dockerfile?

工作區文件夾結構(= my_application ):

 ➜ tree -L 2
.
├── Dockerfile
├── docker-compose.yml
├── configs
│     ├── configure_all.sh
│     ├── create_connections.sh
│     ├── requirements
│     └── variables.json
...

docker-compose.yml

services:
  my_service:
    build: .
    
    ...
    
    volumes:
      - .:/opt/my_application

  ...

請注意,整個工作區目錄都安裝(它必須)在/opt/my_application

最后,Dockerfile:

FROM ubuntu
USER root

RUN apt-get update \
  && apt-get install -y --no-install-recommends \
         build-essential gcc git wget unzip \
  && apt-get autoremove -yqq --purge \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*

RUN sh /opt/my_application/configs/configure_all.sh

但這引發了一個錯誤,因為/opt/my_application/在構建時尚未安裝。

我知道我可以使用類似COPY命令的東西,但它讓我每次更改(或修復) configs任何文件時都構建圖像,這真的很煩人。 我想利用的volumesdocker-compose.yml ,其中連續同步更改。

有沒有辦法做到這一點?

你不能按照你描述的方式做到這一點。 在構建映像之前,卷本質上不會被掛載。 您可以在同一個鏡像上運行多個容器,安裝可能不同(或沒有)的卷,並且鏡像不會被重建。

...每次更改(或修復) configs任何文件時都構建映像...

從幾個不同的部分考慮您的應用程序可能會有所幫助:

  1. 您擁有應用程序本身,它在重新運行時不會改變。
  2. 您的configs可能因運行而異。
  3. 您擁有應用程序在運行時生成的任何數據,這些數據可以在完成后丟棄。

您可以使用 Docker綁定安裝來注入配置,即使應用程序的其余部分已“烘焙”到映像中。

然后,我建議做的第一件事是在應用程序代碼中將 Dockerfile 更新為COPYRUN構建它所需的任何命令,並設置默認CMD以運行應用程序。 一個好的第一步是使用內置在圖像中的configs來運行它。

您的設置的一個復雜問題是注入配置的一部分是一個可運行的腳本。 由於這來自綁定安裝,因此在容器啟動之前腳本將不可用。 您可以使用入口點包裝器腳本在容器啟動時運行它:提供一個 shell 腳本,該腳本作為圖像的ENTRYPOINT運行,執行任何初始設置,然后以exec "$@"以運行圖像的CMD

#!/bin/sh
# docker-entrypoint.sh

# If the configuration includes an initialization script, run it
if [ -x ./configs/configure_all.sh ]; then
  ./configs/configure_all.sh
fi

# Run the main container CMD
exec "$@"

(因為這是一個 shell 腳本,你可以做任何一個 shell 腳本會做的事情。例如,如果腳本設置了環境變量,你可以使用.內置在包含的 shell 中設置它們;或者你可以有邏輯取決於是否設置了變量或文件是否存在;或者...)

在 Dockerfile 中,保留之前的CMD ,但將此腳本添加為ENTRYPOINT

COPY docker-entrypoint.sh .           # if a `COPY . .` doesn't already include it
ENTRYPOINT ["./docker-entrypoint.sh"] # must be JSON-array syntax
CMD the_application                   # same as before

最后,當你啟動應用程序時,使用docker run -v bind mount注入configs目錄; 不要用綁定安裝覆蓋主應用程序代碼。

volumes:
  - ./configs:/opt/my_application/configs

如果您想檢查發生了什么,啟動交互式調試外殼的ENTRYPOINT docker-compose run將替換CMD而不是ENTRYPOINT ,這意味着設置包裝器仍將運行,但隨后啟動交互式外殼而不是主應用程序。

docker-compose run my_service \
  cat /opt/my_application/etc/output_of_configure_all.sh
# ^^^ runs _after_ the setup in the entrypoint script
#     runs _instead of_ the default container CMD (or Compose command:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM