我怎样才能有一个Docker容器链接到另一个Docker容器中的postgres数据库?

这是我docker-compose.yml

 version: '2' services: postgres: image: "postgres:9.4" ports: - "5432:5432" 

我用它来像这样调出postgres数据库:

 docker-compose up 

现在我可以在本地连接到数据库:

 > psql postgres://postgres:postgres@docker-machine:5432 psql (9.6.4, server 9.4.13) Type "help" for help. postgres=# 

我的应用程序是连接到postgres数据库的Ruby / Sinatra应用程序。

当我直接启动应用程序,使用bin/server脚本,应用程序启动并连接到数据库就好了。

这是我如何构build和运行dockerized应用程序:

 docker build -t my_app . docker run \ -p 3001:3001 \ -e DATABASE_URI="postgres://postgres:postgres@docker-machine:5432" \ my_app bin/server 

当我通过这样的Docker运行应用程序,它无法连接到数据库,并打印此错误:

 Sequel::DatabaseConnectionError: PG::ConnectionBad: could not connect to server: Connection refused Is the server running on host "docker-machine" (127.0.0.1) and accepting TCP/IP connections on port 5432? 

我怎样才能让我的dockerized应用程序连接到提供的URI的postgres数据库?

你可以做以下其中一项:

  1. 同时使用相同的docker-compose fil调出两个容器

  2. 您可以使用一个名称服务器,这将允许您为您的数据库容器使用一个名称,以便从您的应用程序容器中可见

  3. 您可以使用数据库容器IP地址,但是,如果数据库容器崩溃并重新启动它将有一个不同的IP地址,这将使您的应用程序容器制动。

你的应用程序容器试图连接到localhost(在容器内部),当然它不能运行Postgres。

由于错误状态docker机未find。 虽然这将在主机上工作,因为它不会在容器中。 你可以像传入一个环境variables一样传递主机名

docker run .. -e HOST_HOSTNAME=hostname ..

然后在连接string中使用该variables

Docker Compose默认为版本2+撰写文件创build用户定义的networking 。

用户定义的networking带有一个embedded式DNS服务器 ,可以响应本地容器名称。 在这种情况下,服务名称postgres将parsing为用户定义的networking上创build的数据库的IP。

要将您的应用程序连接到同一networking,请修改现有的撰写文件,或使用您的应用程序详细信息在同一目录中创build一个新的撰写文件。

 version: '2' services: postgres: image: "postgres:9.4" ports: - "5432:5432" my_app: build: . image: my/app ports: - '3001:3001' environment: DATABASE_URI: 'postgres://postgres:postgres@postgres:5432' command: 'bin/server' 

然后每个容器的IP将通过其service名称可用。