簡體   English   中英

為什么在docker-compose.yml中使用多個env_files時變量替換不起作用?

[英]Why does variables substitution not work when using multiple env_files in docker-compose.yml?

我正在嘗試使用多個.env文件來獲取.env -compose文件,而且我沒有運氣。 我正在嘗試設置三個.env文件:

  • 所有容器實例中的全局設置相同
  • 特定於環境的設置(僅用於測試或開發的東西)
  • 本地設置 - 開發人員可能需要更改的可覆蓋的東西,以防它們與端口號發生沖突

docker-compose.yml文件如下所示:

version: '2'
services:
  db:
    env_file:
      - ./.env
      - ./.env.${ENV}
      - ./.env.local
    image: postgres
    ports:
      - ${POSTGRES_PORT}:5432

.env看起來像這樣:

POSTGRES_USER=myapp

.env.development看起來像這樣:

POSTGRES_PASSWORD=supersecretpassword
POSTGRES_HOST=localhost
POSTGRES_PORT=25432
POSTGRES_DB=myapp_development

在這種情況下,不存在.env.local

運行ENV=development docker-compose up ,我收到以下輸出:

$ ENV=development docker-compose up
WARNING: The POSTGRES_PASSWORD variable is not set. Defaulting to a blank string.
WARNING: The POSTGRES_DB variable is not set. Defaulting to a blank string.
WARNING: The POSTGRES_PORT variable is not set. Defaulting to a blank string.
ERROR: The Compose file './docker-compose.yml' is invalid because:
services.db.ports is invalid: Invalid port ":5432", should be [[remote_ip:]remote_port[-remote_port]:]port[/protocol]

從該錯誤消息,看起來我的環境變量都沒有被使用。 我剛剛升級到最新的可用docker-compose - 同樣的錯誤:

$ docker-compose --version
docker-compose version 1.8.0-rc1, build 9bf6bc6

這里有什么想法? 擁有一個可以跨多個環境工作docker-compose.yml會很不錯。

請記住,您有兩種不同的環境來定義變量。 執行docker-compose命令的主機和容器本身(在您的情況下運行db服務)。

docker-compose.yml文件可以訪問主機的環境變量。 因此ENV可以從.env docker-compose命令訪問,但不能在.env文件中訪問。

相反, ENV的值在容器內是不可達的,但.env文件中定義的所有變量.env

我不知道你是否真的需要你的db容器來訪問.env.development定義的變量。 但至少看起來你的主機需要擁有該文件的內容,所以當調用docker-compose命令時,會定義POSTGRES_PORT變量。

要修復您的特定問題,您還需要在主機上定義環境變量,而不僅僅是容器。 你可以這樣做:

#Set for host
ENV=development

#Also sets the variables on the host 
source ./.env.$ENV

#POSTGRES_PORT defined in .env.development is used here
docker-compose up

#since env_file also contains .env.development, the variables will be reachable from the container.

希望有所幫助。

為了根據運行環境應用不同的/多個env_files,例如開發/登台/制作,我認為docker-compose更好的方法是使用多個docker-compose yml文件。

例如:

1.從定義服務的規范配置的基本文件開始。

docker-compose.yml

web:
  image: example/my_web_app:latest
  env_file:
    - .env

2.添加用於開發的覆蓋文件,顧名思義,可以包含現有服務或全新服務的配置覆蓋。

泊塢窗,compose.override.yml

web:
  build: .
  volumes:
    - '.:/code'
  ports:
    - 8883:80
  env_file:
    - .env.dev

當你運行docker-compose up它會自動讀取覆蓋。

3.為生產環境創建另一個覆蓋文件。

泊塢窗,compose.prod.yml

web:
  ports:
    - 80:80
  env_file:
    - .env.prod

要使用此生產Compose文件進行部署,您可以運行

docker-compose -f docker-compose.yml -f docker-compose.prod.yml up

注意

我的Docker版本:

$ docker -v
Docker version 18.06.1-ce, build e68fc7a

$ docker-compose -v
docker-compose version 1.22.0, build f46880fe

參考: https//docs.docker.com/compose/extends/

閱讀本頁時: https//docs.docker.com/compose/environment-variables/

根據我的理解,你應該做以下事情:

對於全局變量(不應該更改)創建一個像這樣的env文件:

VAR1=VALUE1
VAR2=VALUE2

對於其他人(可能會改變),你應該在docker-compose.yml的環境下添加他們的名字,如下所示:

environment:
    - VAR1
    - VAR2

這將從正在運行docker-compose的shell中獲取VAR1和VAR2值。

我希望這有幫助。

關於.env文件和docker-compose.yml中的env_file選項存在誤解,因為它非常模糊。 Shin在github問題中非常好地指出它docker-compose不使用env_file 我將引用他的總結:

  • docker-compose.yml文件中的變量替換將從shell的環境和.env文件中提取(按優先級降序排列)。

  • 容器中可用的變量是env_file文件中找到的值和服務的環境部分中描述的值的組合。

  • 這是兩組完全獨立的功能。

暫無
暫無

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

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