如何设置database.yml连接到Postgres Docker容器?

San*_*ndy 8 postgresql ruby-on-rails docker docker-compose

我有一个Rails应用程序.在开发和测试环境中,我希望Rails应用程序连接到dockerized Postgres.Rails应用程序本身不会在容器中 - 只是Postgres.

我的database.yml应该是什么样的?

我有一台码头default机正在运行.我创建了docker-compose.yml:

postgres:
  image: postgres
  ports:
    - "5432:5432"
  environment:
    - POSTGRES_USER=timbuktu
    - POSTGRES_PASSWORD=mysecretpassword
Run Code Online (Sandbox Code Playgroud)

我跑去docker-compose up让Postgres跑.

然后我跑去docker-machine ip default获取Docker虚拟机的IP地址,并相应地更新了database.yml:

...
development: 
  adapter: postgresql
  host: 192.168.99.100
  port: 5432
  database: timbuktu_development
  username: timbuktu
  password: mysecretpassword
  encoding: unicode
  pool: 5
...
Run Code Online (Sandbox Code Playgroud)

所以一切都很好,我可以在其容器中连接到Postgres.

但是,如果其他人拉回购,他们将无法使用我的database.yml连接到Postgres,因为他们的Docker默认机器的IP地址将与我的不同.

那么如何更改我的database.yml来解决这个问题呢?

我的一个想法是让他们通过运行获取Docker默认机器的IP地址docker-machine env default,并将env DOCKER_HOST行粘贴到他们的bash_rc中.例如,

export DOCKER_HOST="tcp://192.168.99.100:2376"
Run Code Online (Sandbox Code Playgroud)

然后我的database.yml主机可以包含该行

host: <%= ENV['DOCKER_HOST'].match(/tcp:\/\/(.+):\d{3,}/)[1] %>
Run Code Online (Sandbox Code Playgroud)

但这感到丑陋和黑客.有没有更好的办法?

Von*_*onC 3

2015:您可以先设置一个正确的环境变量,然后从您的database.yml

host: <%= ENV['POSTGRES_IP'] %>
Run Code Online (Sandbox Code Playgroud)

使用类似 bashrc (使用bash 子字符串删除):

export DOCKER_HOST=$(docker-machine env default)
export POSTGRES_IP=${DOCKER_HOST#tcp://}
Run Code Online (Sandbox Code Playgroud)

2023:提醒一下,该docker machine命令原本是 Docker Machine 工具的一部分,已被Docker Desktop的内置功能和Docker Compose所取代。
Docker Machine 主要用于在虚拟环境中配置和管理 Docker 主机(或机器)。

docker-machine env default命令用于设置 shell 环境,以便与特定的 Docker 机器(default在本例中命名)进行交互。当管理多个 Docker 主机或使用在虚拟机上运行的 Docker 时,该命令特别有用。

在现代 Docker 生态系统中,尤其是 Docker Desktop,对此类命令的需求大大减少。Docker Desktop 直接在主机(Windows 或 macOS)上运行 Docker,无需单独的虚拟机来托管 Docker。因此,Docker 客户端默认配置为与 Docker Desktop 的守护进程通信,无需额外的环境设置。

但是,如果您希望复制 Docker 在虚拟机或远程主机中运行的类似设置,则需要配置 Docker 客户端以与该 Docker 守护进程进行通信。这通常是通过环境变量完成的,特别是DOCKER_HOSTDOCKER_CERT_PATHDOCKER_TLS_VERIFY

您需要:

  • 手动设置环境变量:
    确定远程 Docker 守护程序的 IP 地址和端口。
    设置DOCKER_HOST环境变量,如有必要,DOCKER_CERT_PATH以及DOCKER_TLS_VERIFY.

    host: <%= ENV['POSTGRES_IP'] %>
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用 SSH 连接到远程 docker:
    Docker 还支持使用 SSH 连接到远程 Docker 守护进程。

    export DOCKER_HOST=$(docker-machine env default)
    export POSTGRES_IP=${DOCKER_HOST#tcp://}
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用Docker 上下文
    Docker 上下文可用于管理不同的 Docker 端点。
    为远程 Docker 守护进程创建一个新的上下文:

    export DOCKER_HOST="tcp://[IP_ADDRESS]:[PORT]"
    export DOCKER_CERT_PATH="[path/to/cert]"
    export DOCKER_TLS_VERIFY=1
    
    Run Code Online (Sandbox Code Playgroud)

    并使用上下文:

    export DOCKER_HOST="ssh://user@remote-host"
    
    Run Code Online (Sandbox Code Playgroud)

同样,在现代设置中,尤其是对于本地开发,Docker Desktop 消除了对大部分配置的需要。
如果您在远程或专门环境中使用 Docker,则上述步骤更为相关。然而,随着 Docker 生态系统的发展,尤其是 Docker Desktop 和 Docker Compose 的增强,Docker Machine 的功能变得多余且不那么重要。

Docker Desktop 现在包含的功能涵盖了 Docker Machine 的大多数用例。它允许您管理 Docker 容器、映像、网络和卷,以及构建和运行使用 Docker Compose 定义的多容器应用程序。Docker Desktop 与云提供商的集成及其处理本地 Kubernetes 集群的能力进一步扩展了其功能,超出了 Docker Machine 提供的范围。