【问题标题】:How to connect 2 running containers to each other in docker-compose?如何在 docker-compose 中将 2 个正在运行的容器相互连接?
【发布时间】:2020-05-25 03:42:43
【问题描述】:

所以我有了这个简单的 Python Flask 应用程序,其中有 2 个服务:应用程序和数据库。我希望应用程序(Flask 应用程序)连接到数据库服务(PostgreSQL)。

现在,当我注释掉应用程序服务并运行 docker-compose up 时,它会启动在端口 5432 上公开的数据库服务。然后当我在本地运行 Flask 应用程序并尝试连接时,它就可以工作了。

现在我取消注释应用程序服务并运行docker-compose up --build。它构建并启动这两个服务。但是当我访问http://localhost:5000 时,应用程序由于连接错误(被拒绝)而崩溃

docker-compose.yml

version: '3.7'
services:
  application:
    depends_on:
      - database
    build: ./core
    restart: always
    networks:
      - cbr-open-data
    ports:
      - 5000:5000
    environment:
      FLASK_ENV: development
    volumes:
      - ./core:/app

  database:
    image: postgres
    restart: always
    networks:
      - cbr-open-data
    environment: 
      POSTGRES_USER:      ${DATABASE_USER}
      POSTGRES_PASSWORD:  ${DATABASE_PASSWORD}
      POSTGRES_DB:        ${DATABASE_NAME}
    ports:
      - 5432:5432
    volumes:
      - ./database:/var/lib/postgresql/data

networks:
  cbr-open-data:
    driver: bridge

config/connection.py

​​>
import psycopg2
import pandas

connection = psycopg2.connect(
    host = 'localhost',
    database = '...',
    user = '...',
    password = '...',
    port='5432'
)

users = pandas.read_sql('SELECT * FROM users', connection)

app.py

​​>
from flask import Flask, render_template
from config.connection import users

app = Flask(__name__)

@app.route('/')
def index():
    print(users)
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=True)

错误

➜  cbr-open-data git:(master) ✗ docker-compose up
Creating network "cbr-open-data_cbr-open-data" with driver "bridge"
Creating cbr-open-data_database_1 ... done
Creating cbr-open-data_application_1 ... done
Attaching to cbr-open-data_database_1, cbr-open-data_application_1
application_1  |  * Environment: development
application_1  |  * Debug mode: on
application_1  |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
application_1  |  * Restarting with stat
application_1  |  * Debugger is active!
application_1  |  * Debugger PIN: 159-218-115
database_1     | 
database_1     | PostgreSQL Database directory appears to contain a database; Skipping initialization
database_1     | 
database_1     | 2020-02-09 18:10:37.188 UTC [1] LOG:  starting PostgreSQL 12.1 (Debian 12.1-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
database_1     | 2020-02-09 18:10:37.189 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
database_1     | 2020-02-09 18:10:37.189 UTC [1] LOG:  listening on IPv6 address "::", port 5432
database_1     | 2020-02-09 18:10:37.192 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
database_1     | 2020-02-09 18:10:37.303 UTC [27] LOG:  database system was shut down at 2020-02-09 13:21:34 UTC
database_1     | 2020-02-09 18:10:37.330 UTC [1] LOG:  database system is ready to accept connections

THIS IS WHEN I VISIT THE FLASK APP ON 5000.

application_1  | 172.28.0.1 - - [09/Feb/2020 18:10:41] "GET / HTTP/1.1" 500 -
application_1  | Traceback (most recent call last):
application_1  |   File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
application_1  |     raise value
application_1  |   File "/app/app.py", line 2, in <module>
application_1  |     from config.connection import users
application_1  |   File "/app/config/connection.py", line 9, in <module>
application_1  |     port='5432'
application_1  |   File "/usr/local/lib/python3.7/site-packages/psycopg2/__init__.py", line 126, in connect
application_1  |     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
application_1  | psycopg2.OperationalError: could not connect to server: Connection refused
application_1  |        Is the server running on host "localhost" (127.0.0.1) and accepting
application_1  |        TCP/IP connections on port 5432?
application_1  | could not connect to server: Cannot assign requested address
application_1  |        Is the server running on host "localhost" (::1) and accepting
application_1  |        TCP/IP connections on port 5432?
application_1  | 172.28.0.1 - - [09/Feb/2020 18:10:41] "GET /?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 200 -
application_1  | 172.28.0.1 - - [09/Feb/2020 18:10:41] "GET /?__debugger__=yes&cmd=resource&f=debugger.js HTTP/1.1" 200 -
application_1  | 172.28.0.1 - - [09/Feb/2020 18:10:41] "GET /?__debugger__=yes&cmd=resource&f=jquery.js HTTP/1.1" 200 -
application_1  | 172.28.0.1 - - [09/Feb/2020 18:10:42] "GET /?__debugger__=yes&cmd=resource&f=ubuntu.ttf HTTP/1.1" 200 -
application_1  | 172.28.0.1 - - [09/Feb/2020 18:10:42] "GET /?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -

有人可以解释为什么数据库服务拒绝来自应用程序服务的连接,但当我在本地运行应用程序时接受连接?我想更好地理解,绝对是为了将来的实践。

我已经尝试过的

  • 将这两项服务添加到自建网络 (cbr-open-data)。但仍然没有解决方案。
  • 看到link 是可能的,但 docker 不推荐它,因为它可能会从未来的更新中删除。

非常感谢所有帮助!提前致谢。

【问题讨论】:

    标签: python postgresql docker flask docker-compose


    【解决方案1】:

    postgres 容器未在 localhost 上运行。应用程序容器的localhost 是应用程序容器本身。

    您需要使用 docker 网络(您的两个容器都属于该网络)上的 postgres 容器的 IP。

    您可以使用 docker-compose 内置 DNS 来获取 IP。 只需替换:

    connection = psycopg2.connect(
        host = 'localhost',
        database = '...',
        user = '...',
        password = '...',
        port='5432'
    )
    

    与:

    connection = psycopg2.connect(
        host = 'database',
        database = '...',
        user = '...',
        password = '...',
        port='5432'
    )
    

    您的compose文件中的服务名称database,通过compose映射到容器IP。

    【讨论】:

    • 感谢您的快速回复。当我修改它时,我得到一个我也不明白的新错误。 psycopg2.OperationalError: FATAL: the database system is starting up。我用过depends_on为什么不先建库呢?
    • Docker 不知道 postgres 何时完成启动 - 它只知道容器本身何时启动(postgres 在此之后完成启动)。您应该在应用程序代码中添加一些等待和重试。
    • 谢谢你!我在connection.py中添加了等待并重试。现在可以了!
    猜你喜欢
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 2019-07-26
    • 2016-01-06
    相关资源
    最近更新 更多