【问题标题】:Docker-compose environment variablesDocker-compose 环境变量
【发布时间】:2015-06-17 07:34:38
【问题描述】:

我正在尝试设置一个 postgres 容器并希望使用以下命令设置 postgres 登录:

POSTGRES_USER: docker
POSTGRES_PASSWORD: docker

所以我像这样创建了 docker-compose.yml

web:
  build: .
  ports:
    - "62576:62576"
  links:
   - redis
   - db
db:
  image: postgres
  environment:
    POSTGRES_PASSWORD: docker
    POSTGRES_USER: docker

redis:
   image: redis

我还尝试了环境变量的其他语法,将 db 部分声明为:

db:
  image: postgres
  environment:
   - POSTGRES_PASSWORD=docker
   - POSTGRES_USER=docker

但是,这些选项似乎都不起作用,因为无论出于何种原因,每当我尝试使用各种连接字符串连接到 postgres 数据库时:

postgres://postgres:postgres@db:5432/users
postgres://postgres:docker@db:5432/users
postgres://docker:docker@db:5432/users

他们都给了我身份验证失败,而不是抱怨没有用户数据库。

【问题讨论】:

  • @db 表示远程连接,没有任何迹象表明您在postgresql.confpg_hba.conf 中允许它们,尤其是最后一个。在这个问题中不直接包含 auth 错误消息是没有意义的。
  • 我遇到了一个非常相似的问题。我已经在pg_hba.conf 中进行了必要的更改以允许远程连接。问题似乎是docker-compose 忽略了环境变量POSTGRES_PASSWORD

标签: postgresql docker docker-compose


【解决方案1】:

您遇到的身份验证错误将有很大帮助!

我用你的论点启动了 postgres 图像:

docker run --name db -d -e POSTGRES_PASSWORD=docker -e POSTGRES_USER=docker postgres

然后我执行了:

docker exec -it db psql -U docker user
psql: FATAL:  database "user" does not exist

我收到您期望的错误消息,因为我有信任身份验证:

docker exec -it db cat /var/lib/postgresql/data/pg_hba.conf | grep -v '^#'

local   all             all                                     trust
host    all             all             127.0.0.1/32            trust
host    all             all             ::1/128                 trust
host all all 0.0.0.0/0 md5

为了模拟您的 Web 容器,我将运行另一个 postgres 容器实例并链接 db 容器,然后连接回 db 容器:

core@ku1 /tmp/i $ docker run --rm --name web --link db:db -it postgres psql -h db -Udocker user
Password for user docker: 
psql: FATAL:  password authentication failed for user "docker"

如果我输入了错误的密码,我会收到验证错误。但是,如果我输入正确的密码:

core@ku1 /tmp/i $ docker run --rm --name web --link db:db -it postgres psql -h db -Udocker user
Password for user docker: 
psql: FATAL:  database "user" does not exist

似乎一切正常。我把它全部放在一个 yaml 文件中,并以这种方式进行了测试:

web:
  image: postgres
  command: sleep 999
  ports:
    - "62576:62576"
  links:
   - db
db:
  image: postgres
  environment:
    POSTGRES_PASSWORD: docker
    POSTGRES_USER: docker

然后用 docker-compose 启动它:

core@ku1 /tmp/i $ docker-compose -f dc.yaml up
Creating i_db_1...
Creating i_web_1...
Attaching to i_db_1, i_web_1
db_1  | ok
db_1  | creating template1 database in /var/lib/postgresql/data/base/1 ... ok
db_1  | initializing pg_authid ... ok
db_1  | initializing dependencies ... ok
db_1  | creating system views ... ok
db_1  | loading system objects' descriptions ... ok
db_1  | creating collations ... ok
db_1  | creating conversions ... ok
db_1  | creating dictionaries ... ok
db_1  | setting privileges on built-in objects ... ok
db_1  | creating information schema ... ok
db_1  | loading PL/pgSQL server-side language ... ok
db_1  | vacuuming database template1 ... ok
db_1  | copying template1 to template0 ... ok
db_1  | copying template1 to postgres ... ok
db_1  | syncing data to disk ... ok
db_1  | 
db_1  | WARNING: enabling "trust" authentication for local connections
db_1  | You can change this by editing pg_hba.conf or using the option -A, or
db_1  | --auth-local and --auth-host, the next time you run initdb.
db_1  | 
db_1  | Success. You can now start the database server using:
db_1  | 
db_1  |     postgres -D /var/lib/postgresql/data
db_1  | or
db_1  |     pg_ctl -D /var/lib/postgresql/data -l logfile start
db_1  | 
db_1  | 
db_1  | PostgreSQL stand-alone backend 9.4.1
db_1  | backend> statement: CREATE DATABASE "docker" ;
db_1  | 
db_1  | backend> 
db_1  | 
db_1  | PostgreSQL stand-alone backend 9.4.1
db_1  | backend> statement: CREATE USER "docker" WITH SUPERUSER PASSWORD 'docker' ;
db_1  | 
db_1  | backend> 
db_1  | LOG:  database system was shut down at 2015-04-12 22:01:12 UTC
db_1  | LOG:  database system is ready to accept connections
db_1  | LOG:  autovacuum launcher started
^Z
[1]+  Stopped                 docker-compose -f dc.yaml up
core@ku1 /tmp/i $ bg

您可以看到用户和密码已创建。我执行:

core@ku1 /tmp/i $ docker exec -it i_web_1 psql -Udocker -h db user
Password for user docker: 
psql: FATAL:  password authentication failed for user "docker"
core@ku1 /tmp/i $
db_1  | FATAL:  password authentication failed for user "docker"
db_1  | DETAIL:  Connection matched pg_hba.conf line 95: "host all all 0.0.0.0/0 md5"

core@ku1 /tmp/i $ docker exec -it i_web_1 psql -Udocker -h db user
Password for user docker: 
psql: FATAL:  database "user" does not exist
db_1  | FATAL:  database "user" does not exist

所以我唯一能想到的就是您尝试从您的主机连接到数据库,而不是 Web 容器?或者您的 Web 容器没有使用“db”作为连接的主机?您对 Web 容器的定义不包含我可以看到的任何错误。

【讨论】:

  • 感谢您的帮助,原来在第一次创建图像时发生了一些奇怪的事情,导致我看到了身份验证问题。执行 docker-compose rm 然后 docker-compose up 修复它
【解决方案2】:

我为此苦苦挣扎了一段时间,并没有得到接受的答案,我终于通过移除容器来让它工作:

docker-compose rm postgres

然后是音量

docker volume rm myapp_postgres

然后,当我执行新的docker-compose up 时,我看到CREATE ROLE 飞过,我假设 是最初的up 错过的。


原因在 here 中详细说明,在 Git repo for the Docker official image for postgres。

【讨论】:

  • 这是否意味着环境变量仅在第一次运行时被读取,而在以后的所有运行中都被忽略?如果是这样,最好在第一次运行后手动忽略这些变量和这些值
  • 是的@wotanii 看来这就是原因。您的洞察力使我找到了this corresponding issue。我也会更新答案以引用它。谢谢!
  • 哇,非常感谢@dukedave。你的回答让我很开心!
  • 在找到这个答案之前花了一天多的时间。谢谢!
  • 为了docker-compose rm 解决这个问题,我浪费了这么多时间......这就像 Drupal 清除缓存,两次......
【解决方案3】:

我也遇到过类似的情况。根据@Greg 的回答,我做了一个 docker-compose up,它获取了环境变量。

在此之前,我一直在使用 docker-compose run 并且它没有通过运行 docker-compose exec task env 来获取环境变量.奇怪的是,docker-compose run task env 显示了我期待的环境变量。

【讨论】:

    【解决方案4】:

    我遇到了同样的问题,在我的情况下,问题是通过一个命令解决的:

    docker-compose up --force-recreate
    

    【讨论】:

    • 我试过这个选项,但后来我得到这个错误:来自守护进程的错误响应:重复的安装点:/var/lib/postgresql/data
    【解决方案5】:

    如果您使用的是 Docker

    尝试检查您的本地数据库是否处于活动状态,因为它主要与 Docker 冲突,如果是,您可以停用它或更改端口号或卸载它以避免冲突。

    【讨论】:

    • 天哪,我有 3 名工程师在最后一整天试图找出问题所在。然后有人指出了这个评论。原来有人在很久以前安装了本地 postgres 来测试它,我们试图连接到错误的 postgres -_-。杀死了 Windows 服务,现在就像一个魅力。谢谢!
    • 很高兴听到这有帮助
    • @FatalCatharsis 我觉得你谢谢 Abdel
    • 我浪费了一整天才看到这个。非常感谢。希望我能投票两次
    • 我猜 Docker 日志没有显示任何失败的登录尝试应该敲响了警钟。我公开了一个不同的端口,并且可以同时运行两个实例 - 谢谢!
    【解决方案6】:

    感谢 Bryan docker-compose exec containername env 我发现还需要删除卷。因为对于docker-compose volume rm volumename,您需要知道确切的名称,因此删除所有内容更容易:

    docker-compose down --volumes
    

    【讨论】:

      【解决方案7】:

      这对我有帮助

      docker stop $(docker ps -qa) && docker system prune -af --volumes && docker compose up
      

      【讨论】:

        【解决方案8】:

        在我的情况下,在 Windows 10 WSL2 中运行 postgres:13-alpine,上述解决方案都没有成功。

        我的错误是我使用的 docker network 名称与另一个项目共享。假设我有项目 A 和 B,都具有以下结构:

        myappfolder
          - docker-compose.yml
            - services
                - app
                    - depends on db
                - db
        

        默认情况下,docker-compose 会从 docker-compose.yml 文件的父目录名称中获取 network 名称。因此,A 和 B 两个项目都试图连接到同一个网络:myappfolder_default

        解决这个问题:

        1. 确保网络名称在项目中是唯一的:

          一个。要么将根文件夹的名称更改为唯一的

          b.或编辑您docker-compose.yml 以设置明确的网络名称

        2. docker-compose down -v 这将重置您在网络中定义的所有可能的数据库>确保在继续之前进行psql转储

        3. docker-compose up

        更多网络文档在这里:https://docs.docker.com/compose/networking/

        【讨论】:

        • Esto funciona para mi , gracias
        猜你喜欢
        • 1970-01-01
        • 2022-01-01
        • 2018-02-03
        • 2019-02-25
        • 2022-06-11
        • 2019-07-26
        • 1970-01-01
        • 2019-01-07
        • 2020-07-16
        相关资源
        最近更新 更多