Wie kann ich von einem Host-Rechner aus eine Verbindung zu Postgres im Docker herstellen?
docker-compose.yml
version: '2'
networks:
database:
driver: bridge
services:
app:
build:
context: .
dockerfile: Application.Dockerfile
env_file:
- docker/Application/env_files/main.env
ports:
- "8060:80"
networks:
- database
depends_on:
- appdb
appdb:
image: postdock/postgres:1.9-postgres-extended95-repmgr32
environment:
POSTGRES_PASSWORD: app_pass
POSTGRES_USER: www-data
POSTGRES_DB: app_db
CLUSTER_NODE_NETWORK_NAME: appdb
NODE_ID: 1
NODE_NAME: node1
ports:
- "5432:5432"
networks:
database:
aliases:
- database
docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------------------------------
appname_app_1 /bin/sh -c /app/start.sh Up 0.0.0.0:8060->80/tcp
appname_appdb_1 docker-entrypoint.sh /usr/ ... Up 22/tcp, 0.0.0.0:5432->5432/tcp
Vom Container kann ich mich erfolgreich verbinden. Sowohl aus dem App-Container als auch aus dem Db-Container.
Liste der Datenbanken und Benutzer, die psql im Container ausführen:
# psql -U postgres
psql (9.5.13)
Type "help" for help.
postgres=# \du
List of roles
Role name | Attributes | Member of
------------------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
replication_user | Superuser, Create role, Create DB, Replication | {}
www-data | Superuser | {}
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
----------------+------------------+----------+------------+------------+-----------------------
app_db | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
replication_db | replication_user | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
(5 rows)
DB-Image ist kein offizielles Postgres-Image. Aber Dockerfile in GitHub sieht gut aus.
cat /var/lib/postgresql/data/pg_hba.conf aus dem DB-Container:
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
Host all all 127.0.0.1/32 trust
# IPv6 local connections:
Host all all ::1/128 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local replication postgres trust
#Host replication postgres 127.0.0.1/32 trust
#Host replication postgres ::1/128 trust
Host all all all md5
Host replication replication_user 0.0.0.0/0 md5
Ich habe beide Benutzer ohne Erfolg ausprobiert
$ psql -U postgres -h localhost
psql: FATAL: role "postgres" does not exist
$ psql -h localhost -U www-data appdb -W
Password for user www-data:
psql: FATAL: role "www-data" does not exist
Es sieht so aus, als ob auf meinem Host-Rechner bereits PSQL auf diesem Port läuft. Wie kann ich das überprüfen?
Ich lief dies auf Ubuntu 16.04
$ psql -h localhost -U www-data app_db
Password for user www-data:
psql (9.5.13)
Type "help" for help.
app_db=# \du
List of roles
Role name | Attributes | Member of
------------------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
replication_user | Superuser, Create role, Create DB, Replication | {}
www-data | Superuser | {}
Und weiter unten von meinem Mac zu dem VM, in dem das Docker ausgeführt wurde (192.168.33.100 ist die IP-Adresse der Docker-VM).
$ psql -h 192.168.33.100 -U www-data app_db
Password for user www-data:
psql (9.6.9, server 9.5.13)
Type "help" for help.
app_db=# \du
List of roles
Role name | Attributes | Member of
------------------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
replication_user | Superuser, Create role, Create DB, Replication | {}
www-data | Superuser | {}
Sie arbeiten beide für mich.
PSQL-Version auf VM
$ psql --version
psql (PostgreSQL) 9.5.13
PSQL-Version auf Mac
$ psql --version
psql (PostgreSQL) 9.6.9
Ich glaube, Sie haben ein Problem mit pg_hba.conf
. Hier haben Sie 1 Host angegeben, der Zugriff hat - 127.0.0.1/32.
Sie können es so ändern:
# IPv4 local connections:
Host all all 0.0.0.0/0 md5
Dadurch wird sichergestellt, dass sich Ihr Host (eine völlig andere IP-Adresse) verbinden kann.
Um zu überprüfen, ob bereits eine Instanz von postgresql ausgeführt wird, können Sie netstat -plnt | grep 5432
ausführen. Wenn Sie daraus ein Ergebnis erhalten, können Sie die PID abrufen und den Prozess selbst überprüfen.
Ich hatte das gleiche Problem auf elementarem OS 5.0, während Postgres 10 als offizieller Docker-Container ausgeführt wurde. Ich konnte eine Verbindung vom Host über die IP des laufenden Containers herstellen.
Sudo docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name/id
Testen Sie nach Erhalt der IP-Adresse: Psql -h 172.17.0.2 -U postgres
Ich glaube, das Problem ist, dass Postgres auf dem lokalen Computer an Port 5432 ausgeführt werden. Das Problem kann gelöst werden, indem Port 5432 des Docker-Containers einem anderen Port in der Host-Maschine zugeordnet wird. Dies kann durch eine Änderung von docker-compose.yml erreicht werden
Veränderung
"5432:5432"
zu
"5433:5432"
Starten Sie Docker-Compose neu
Jetzt läuft der Docker-Container-Postgres auf 5433. (Lokal installierte Postgres ist auf 5432) Sie können versuchen, eine Verbindung zum Docker-Container herzustellen.
psql -p 5433 -d db_name -U user -h localhost
Ich habe ein relativ ähnliches Setup und das Folgende funktioniert für mich, um eine psql
-Sitzung auf dem Host-Computer in der Docker-Postgres-Instanz zu öffnen: docker-compose run --rm db psql -h db -U postgres -d app_development
Woher:
db
ist der Name des Containerspostgres
ist der Name des Benutzersapp_development
ist der Name der DatenbankFür Sie würde es also docker-compose run --rm appdb psql -h appdb -U www-data -d app_db
aussehen.
Da Sie es unter OSX ausführen, können Sie immer die vorinstallierte App Network Utility verwenden, um einen Port Scan auf Ihrem Host auszuführen und festzustellen, ob der Postgres-Server (und if.) ja, an welchem Port).
Aber ich glaube nicht, dass Sie einen Host auf Ihrem Host haben. Das Problem ist, dass Postgres standardmäßig auf
5432
ausgeführt wird und diedocker-compose
-Datei, die Sie ausführen möchten, den DB-Container am selben Port, d. H.5432
, verfügbar macht. Wenn der Postgres-Server bereits auf Ihrem Host ausgeführt wird, hätte Docker versucht, einen Container für einen bereits verwendeten Port freizugeben, was zu einem Fehler führt.
Eine andere mögliche Lösung:
Wie Sie in dieser answer sehen können, öffnet mysql
einen Unix-Socket mit localhost
und keinen TCP-Socket. Vielleicht passiert hier etwas Ähnliches.
Verwenden Sie 127.0.0.1
anstelle von localhost
, während Sie eine Verbindung zum Server im Container herstellen.