web-dev-qa-db-ja.com

Dockerコンテナがローカル/ホストのpostgresデータベースに接続できるようにします

私は最近DockerとQGISで遊んでいて、 このチュートリアル の指示に従ってコンテナをインストールしました。

すべてがうまく機能しますが、すべてのGISデータを含むローカルホストのpostgresデータベースに接続できません。これは、私のpostgresデータベースがリモート接続を受け入れるように構成されておらず、 この記事 の手順を使用してリモート接続を許可するようにpostgres confファイルを編集しているためです。

DockerでQGISを実行しているデータベースに接続しようとすると、エラーメッセージが表示されます:サーバーに接続できませんでした:Connection refused Is the server running on Host "localhost" (::1) and accepting TCP/IP connections to port 5433? postgresサーバーが実行されており、pg_hbaを編集しましたIPアドレスの範囲(172.17.0.0/32)からの接続を許可する.confファイル。以前にdocker psを使用してdockerコンテナーのIPアドレスを照会しましたが、IPアドレスは変更されますが、これまでは常に172.17.0.xの範囲でした。

このデータベースに接続できない理由はありますか?おそらく私が想像する非常にシンプルなものです!

Ubuntu 14.04を実行しています。 Postgres 9.3

89
marty_c

TL; DR

  1. IPアドレス範囲として172.17.0.0/16ではなく、172.17.0.0/32を使用します。
  2. localhostを使用してホスト上のPostgreSQLデータベースに接続するのではなく、ホストのIPを使用してください。コンテナの移植性を維持するには、--add-Host=database:<Host-ip>フラグでコンテナを起動し、databaseをPostgreSQLに接続するためのホスト名として使用します。
  3. localhostだけでなく、すべてのIPアドレスで接続をリッスンするようにPostreSQLが構成されていることを確認してください。 PostgreSQLの設定ファイルで、通常listen_addresses(@DazmoNortonのクレジット)にある/etc/postgresql/9.3/main/postgresql.confの設定を探します。

ロングバージョン

172.17.0.0/32は、IPアドレスの範囲ではなく、単一のアドレス(名前は172.17.0.0)です。 Dockerコンテナは、そのアドレスが割り当てられることはありません。これは、Dockerブリッジ(docker0)インターフェースのネットワークアドレスだからです。

Dockerが起動すると、新しいブリッジネットワークインターフェイスが作成され、ip aを呼び出したときに簡単に確認できます。

$ ip a
...
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever

ご覧のとおり、私の場合、docker0インターフェイスのIPアドレスは172.17.42.1で、ネットマスクは/16(または255.255.0.0)です。これは、ネットワークアドレスが172.17.0.0/16であることを意味します。

IPアドレスはランダムに割り当てられますが、追加設定なしで、常に172.17.0.0/16ネットワーク内にあります。 Dockerコンテナごとに、その範囲のランダムなアドレスが割り当てられます。

つまり、可能なすべてのコンテナからデータベースへのアクセスを許可する場合は、172.17.0.0/16を使用します。

106
helmbert

Docker for Macソリューション

17.06以降

@Birchlabsのコメントのおかげで、これで何トンも簡単になりました 特別なMacのみのDNS名が利用可能

docker run -e DB_PORT=5432 -e DB_Host=docker.for.mac.Host.internal

17.12.0-cd-mac46以降では、docker.for.mac.Host.internalの代わりにdocker.for.mac.localhostを使用する必要があります。詳細については、 リリースノート を参照してください。

古いバージョン

@helmbertの答えは問題をよく説明しています。しかし、Mac用Docker ブリッジネットワークを公開しない なので、制限を回避するにはこのトリックを実行する必要がありました。

$ Sudo ifconfig lo0 alias 10.200.10.1/24

/usr/local/var/postgres/pg_hba.confを開き、次の行を追加します。

Host    all             all             10.200.10.1/24            trust

/usr/local/var/postgres/postgresql.confを開き、変更listen_addressesを編集します。

listen_addresses = '*'

サービスをリロードして、コンテナを起動します。

$ PGDATA=/usr/local/var/postgres pg_ctl reload
$ docker run -e DB_PORT=5432 -e DB_Host=10.200.10.1 my_app 

この回避策は、基本的に@helmbertの回答と同じですが、lo0ネットワークインターフェイスの代わりにdocker0に接続されているIPアドレスを使用します。

44
baxang

Mac用のシンプルなソリューション:

Dockerの最新バージョン(18.03)は、組み込みのポート転送ソリューションを提供します。 Dockerコンテナ内で、db HostをHost.docker.internalに設定するだけです。これは、Dockerコンテナが実行されているホストに転送されます。

これに関するドキュメントはこちらです https://docs.docker.com/docker-for-mac/networking/#per-container-ip-addressing-is-not-possible

17
Chris

シンプルなソリューション

--network=Hostdocker runに追加するだけです。それで全部です!

この方法でコンテナはホストのネットワークを使用するため、localhost127.0.0.1はホストを指します(デフォルトではコンテナを指します)。例:

docker run -d --network=Host \
  -e "DB_DBNAME=your_db" \
  -e "DB_PORT=5432" \
  -e "DB_USER=your_db_user" \
  -e "DB_PASS=your_db_password" \
  -e "DB_Host=127.0.0.1" \
  --name foobar foo/bar
2
Max Malysh

セットアップに必要なもう1つのことは、

172.17.0.1  localhost

/etc/hosts

そのため、DockerはDBホスト名として172.17.0.1をポイントし、外部IPの変更に依存せずにDBを検索します。これがこの問題で他の誰かを助けることを願っています!

1
Mikko Pöri

Ubuntuの場合:

まず、次のコマンドを使用して、システムでDockerデータベースポートが使用可能であることを確認する必要があります-

Sudo iptables -L -n

サンプル出力:

Chain DOCKER (1 references)
target     prot opt source               destination         
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.2           tcp dpt:3306
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.3           tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.3           tcp dpt:22

ここで3306は172.17.0.2 IPのDockerデータベースポートとして使用されます。このポートが使用できない場合は、次のコマンドを実行します-

Sudo iptables -A INPUT -p tcp --dport 3306 -j ACCEPT

これで、次の構成により、ローカルシステムからDockerデータベースに簡単にアクセスできます。

  Host: 172.17.0.2 
  adapter: mysql
  database: DATABASE_NAME
  port: 3307
  username: DATABASE_USER
  password: DATABASE_PASSWORD
  encoding: utf8

CentOSの場合:

まず、次のコマンドを使用して、ファイアウォールでDockerデータベースポートが使用可能であることを確認する必要があります-

Sudo firewall-cmd --list-all

サンプル出力:

  target: default
  icmp-block-inversion: no
  interfaces: eno79841677
  sources: 
  services: dhcpv6-client ssh
  **ports: 3307/tcp**
  protocols: 
  masquerade: no
  forward-ports: 
  sourceports: 
  icmp-blocks: 
  rich rules:

ここで3307は172.17.0.2 IPのDockerデータベースポートとして使用されます。このポートが使用できない場合は、次のコマンドを実行します-

Sudo firewall-cmd --zone=public --add-port=3307/tcp

サーバーでは、ポートを永続的に追加できます

Sudo firewall-cmd --permanent --add-port=3307/tcp
Sudo firewall-cmd --reload

上記の設定により、ローカルシステムからDockerデータベースに簡単にアクセスできるようになりました。

1
Sanaulla

docker-composeの場合は、追加してみてください

network_mode: "Host"

例:

version: '2'
services:
  feedx:
    build: web
    ports:
    - "127.0.0.1:8000:8000"
    network_mode: "Host"

https://docs.docker.com/compose/compose-file/#network_mode

0
Sarath Ak