I've done a docker-compose up and been able to run my web service attached to a postgresql image. Problem is, I can't view the data on postico when I try to access the database. The name of the image is db and when i try to specify hostname to be "db" on postico before i connect, i get an error saying hostname not found. I've entered my credentials, port and database name the same way i keyed them in my docker-compose file.
Does anybody know how i can find the correct setup to connect to within the container?
version: '3.6'
services:
phoenix:
# tell docker-compose which Dockerfile it needs to build
build:
context: .
dockerfile: Dockerfile.phoenix.development
# map the port of phoenix to the local dev port
ports:
- 4000:4000
# mount the code folder inside the running container for easy development
volumes:
- ./my_app:/app
# make sure we start mongodb when we start this service
# links:
# - db
depends_on:
- db
- redis
environment:
GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET}
FACEBOOK_CLIENT_ID: ${FACEBOOK_CLIENT_ID}
FACEBOOK_CLIENT_SECRET: ${FACEBOOK_CLIENT_SECRET}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_USER: ${POSTGRES_USER}
go:
build:
context: .
dockerfile: Dockerfile.go.development
ports:
- 8080:8080
volumes:
- ./genesys-api:/go/src/github.com/sc4224/genesys-api
depends_on:
- db
- redis
- phoenix
db:
container_name: db
image: postgres:latest
ports:
- "5432:5432"
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_USER: ${POSTGRES_USER}
volumes:
- ./data/db:/data/db
restart: always
redis:
container_name: redis
image: redis:latest
ports:
- "6379:6379"
volumes:
- ./data/redis:/data/redis
entrypoint: redis-server
restart: always
use hostname as localhost.
You can't use the hostname db outside the internal docker network. That would work in the applications running in the same network.
Since you exposed the db to run on port 5432, it's exposed via 0.0.0.0:5432->5432/tcp and therefore is accessible with localhost as host and port 5432
Related
I have set up the following docker-compose.yml file to set up and run PostgreSQL and PgAdmin.
version: '3.1'
services:
db:
image: postgres:latest
container_name: postgres-dopp
restart: unless-stopped
environment:
POSTGRES_USER: dopp_dev
POSTGRES_PASSWORD: dopp_dev_pass
PGDATA: /data/postgres
ports:
- "5432:5432"
volumes:
- dbdata-dopp:/data/postgres
networks:
- network-dopp
pgadmin:
image: dpage/pgadmin4
environment:
PGADMIN_DEFAULT_EMAIL: pgadmin4#pgadmin.org
PGADMIN_DEFAULT_PASSWORD: admin
PGADMIN_CONFIG_SERVER_MODE: 'False'
depends_on:
- db
volumes:
- dbdata-dopp:/data/pgadmin
ports:
- "5050:80"
networks:
- network-dopp
networks:
network-dopp:
driver: bridge
volumes:
dbdata-dopp:
name: dopp-db-data
driver: local
This works fine, insofar as I can navigate to PgAdmin in my host machine's browser and through that I can connect to the database using the credentials I've defined in the environment variables. However, when attempting to make a direct connection to the postgres database from my host machine (by connecting to localhost:5432, since I have configured to expose that port), I then get the following error response:
[28P01] FATAL: password authentication failed for user "dopp_dev"
I'm fairly new to the peculiarities of Postgres and docker configuration, so I'm not sure what is causing Postgres to say that password authentication fails when connecting from my host machine, while it works perfectly fine if I do it through PgAdmin, which is on the same internal docker network.
Actually, I discovered that the docker postgres service's port 5432 was being shadowed by a local postgres instance running my host machine.
I have a samle app I'm using docker-compose to run locally on my machine. The web app is in one container and the db (postgres) in another.
I am having an connection issue that I can't work through.
docker-compose
version: '3.8'
services:
db:
image: postgres
environment:
POSTGRES_PASSWORD: 'password'
POSTGRES_DB: 'postgres'
POSTGRES_USER: 'postgres'
volumes:
- ./postgres-db:/var/lib/postgresql/data
ports:
- '5432:5432'
app:
build:
context: .
dockerfile: app/Dockerfile
restart: always
environment:
APP_FRONTEND_PORT: '8080'
DB_PORT: '5433'
DB_HOST: 'db'
ports:
- '8080:8080'
depends_on:
- 'db'
volumes:
postgres-db:
Dockerfile
FROM golang:latest
WORKDIR /scratch
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /bin/frontend ./...
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /go/bin/
COPY --from=build /bin/frontend /go/bin/frontend
ENTRYPOINT ["/go/bin/frontend"]
Both containers are running and I'm able to log into the running postgres container and postgres us running.
When I try to run a update from the US I get a 500 error and it does not seem like the app container can communicate with the db container. I'm not sure what I'm missing
client side error when trying to make a call to update date:
encountered err: failed to begin transaction: failed to connect to `host=db user=postgres database=postgres`: dial error (dial tcp 172.29.0.2:5433: connect: connection refused)
docker ps yeilds:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
19eeed869434 sample_app "/go/bin/frontend" 48 minutes ago Up 48 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp sample_app_1
84804f00c751 postgres "docker-entrypoint.s…" 48 minutes ago Up 48 minutes 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp sample_app_db_1
$
As per stated in https://docs.docker.com/network/bridge/, you need to put both services into a user-defined bridge network for them to refer to each other by the container names. Here is how to do it inside docker-compose.yml:
Define a custom bridge network:
networks:
some-name:
driver: bridge
Put both services into that network:
services:
db:
image: postgres
environment:
POSTGRES_PASSWORD: 'password'
POSTGRES_DB: 'postgres'
POSTGRES_USER: 'postgres'
volumes:
- ./postgres-db:/var/lib/postgresql/data
ports:
- '5432:5432'
networks:
- some-name
app:
build:
context: .
dockerfile: app/Dockerfile
restart: always
environment:
APP_FRONTEND_PORT: '8080'
DB_PORT: '5433'
DB_HOST: 'db'
ports:
- '8080:8080'
depends_on:
- 'db'
networks:
- some-name
Force specific container names especially the one being referred to by the other, otherwise docker-compose will add prefix and suffix to the service name as the container name like sample_app_db_1:
services:
db:
container_name: db
image: postgres
environment:
POSTGRES_PASSWORD: 'password'
POSTGRES_DB: 'postgres'
POSTGRES_USER: 'postgres'
volumes:
- ./postgres-db:/var/lib/postgresql/data
ports:
- '5432:5432'
networks:
- some-name
I am trying to use my docker-compose file to run 2 instances of both my database, and my rest api, so that I can run tests on a test instance of the database.
version: "3.8"
services:
db:
image: postgres:13.2-alpine
container_name: "db-prod"
ports:
- "5432:5432"
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
networks:
- fullstack
volumes:
- database_postgres:/var/lib/postgresql/data
db_test:
image: postgres:13.2-alpine
container_name: "db-test"
ports:
- "5433:5432"
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
networks:
- fullstack-test
volumes:
- database_postgres_test:/var/lib/postgresql/data
api:
build: .
container_name: "rest-api"
environment:
DB_USERNAME: "postgres"
DB_PASSWORD: "password"
DB_HOST: "db-prod"
DB_TABLE: "postgres"
DB_DB: "postgres"
DB_PORT: "5432"
ports:
- "8080:8080"
depends_on:
- db
networks:
- fullstack
api_test:
build: .
container_name: "rest-api-test"
environment:
DB_USERNAME: "postgres"
DB_PASSWORD: "password"
DB_HOST: "db-test"
DB_TABLE: "postgres"
DB_DB: "postgres"
DB_PORT: "5433"
ports:
- "8081:8080"
depends_on:
- db_test
networks:
- fullstack-test
volumes:
database_postgres:
database_postgres_test:
networks:
fullstack:
driver: bridge
fullstack-test:
driver: bridge
When i run this, my prod database starts, and my regular API connects to it fine.
My test DB also starts, and I can connect to it using
psql -U postgres -h localhost -p 5433
however my test rest API wi
dial tcp 192.168.112.2:5433: connect: connection refused
The goal is to set up my go tests to run on the test DB and just clear after each test as needed, and not affect the prod db.
I am not sure if I am going about this the right way - perhaps there is a better construct for this - and if so please correct me. But regardless, I do not understand why im getting this error?
I dont get why one connection works well and the other fails?
Edit: Also interesting, i just noticed if i change the api_test container to use:
DB_HOST: "host.docker.internal"
it works. But i still dont understand why one can use a container name and the other cannot? And i cant leave it this way as it needs to work on a mac as well, and host.docker.internal doesnt work on my mac (hence why the first one was changed to the container name)
Using docker to connect springboot to postgres via docker-compose. Using port 5432 on postgres works fine, if i try an port other than that it fails
working code
spring
spring.datasource.url=jdbc:postgresql://db:5432/wwc
spring.datasource.username=wwc
spring.datasource.password=test
spring.datasource.driver-class-name=org.postgresql.Driver
docker-compose
version: '2.1'
services:
db:
container_name: db
image: postgres:9.4
ports:
- 5432:5432
volumes:
- /tmp:/var/lib/postgresql
environment:
- POSTGRES_USER=wwc
- POSTGRES_DB=wwc
- POSTGRES_PASSWORD=test
server:
container_name: spring-boot-rest-server
build:
context: .
dockerfile: Dockerfile.server
ports:
- 8080:8080
logging:
driver: json-file
depends_on:
- db
web:
container_name: nginx-web
links:
- "server:springboot"
build:
context: .
dockerfile: Dockerfile.web
ports:
- 80:80
- 8088:8088
logging:
driver: json-file
depends_on:
- server
**connection refused code **
spring
spring.datasource.url=jdbc:postgresql://db:6000/wwc
spring.datasource.username=wwc
spring.datasource.password=test
spring.datasource.driver-class-name=org.postgresql.Driver
docker-compose
version: '2.1'
services:
db:
container_name: db
image: postgres:9.4
ports:
- 6000:5432
volumes:
- /tmp:/var/lib/postgresql
environment:
- POSTGRES_USER=wwc
- POSTGRES_DB=wwc
- POSTGRES_PASSWORD=test
server:
container_name: spring-boot-rest-server
build:
context: .
dockerfile: Dockerfile.server
ports:
- 8080:8080
logging:
driver: json-file
depends_on:
- db
web:
container_name: nginx-web
links:
- "server:springboot"
build:
context: .
dockerfile: Dockerfile.web
ports:
- 80:80
- 8088:8088
logging:
driver: json-file
depends_on:
- server
error:
spring-boot-rest-server | org.postgresql.util.PSQLException: Connection to db:6000 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
What am i doing wrong?
You are confusing a bit the ports: your "db" container only exports 1 port: 5432. The 6000 that you put in your docker-compose is the port on localhost that you map to that container (db) on that port (5432).
You shouldn't even use the port mappings for the postgres container unless you want to connect from localhost which I guess you don't.
If you want to use another port than 5432 you need to extend the postgres Dockerfile and change the configuration so that postgres starts listening on a different port.
Hope this helps.
In other words: The port mapping configured in docker-compose has no relevancy to how the containers connect to each other. The mapping is only relevant when something/someone attempts to connect to your containers within the docker-compose from the outside. (Like from the localhost, as #Mihai remarked.)
I have a docker-compose file with services for python, nginx, postgres and pgadmin:
services:
postgres:
image: postgres:9.6
env_file: .env
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5431:5431"
pgadmin:
image: dpage/pgadmin4
links:
- postgres
depends_on:
- postgres
environment:
PGADMIN_DEFAULT_EMAIL: admin#admin.com
PGADMIN_DEFAULT_PASSWORD: pwdpwd
volumes:
- pgadmin:/root/.pgadmin
ports:
- "5050:80"
backend:
build:
context: ./foobar # This refs a Dockerfile with Python and Django requirements
command: ["/wait-for-it.sh", "postgres:5431", "--", "/gunicorn.sh"]
volumes:
- staticfiles_root:/foobar/static
depends_on:
- postgres
nginx:
build:
context: ./foobar/docker/nginx
volumes:
- staticfiles_root:/foobar/static
depends_on:
- backend
ports:
- "0.0.0.0:80:80"
volumes:
postgres_data:
staticfiles_root:
pgadmin:
When I run docker-compose up and visit localhost:5050, I see the pgadmin interface. When I try to create a new server there, with localhost or 0.0.0.0 as host name and 5431 as port, I get an error "Could not connect to server". If I remove these and instead enter postgres in the "Service" field, I get the error "definition of service "postgres" not found". How can I connect to the database with pgadmin?
the docker container name changes when you run docker-compose to prefix the folder name (to keep container names unique). You could force the name of the container with container_name property
version: "3"
services:
# postgres database
postgres:
image: postgres:12.3
container_name: postgres
environment:
- POSTGRES_DB=admin
- POSTGRES_USER=admin
- POSTGRES_PASSWORD=admin
- POSTGRES_HOST_AUTH_METHOD=trust # allow all connections without a password. This is *not* recommended for prod
volumes:
- database-data:/var/lib/postgresql/data/ # persist data even if container shuts down
ports:
- "5432:5432"
# pgadmin for managing postgis db (runs at localhost:5050)
# To add the above postgres server to pgadmin, use hostname as defined by docker: 'postgres'
pgadmin:
image: dpage/pgadmin4
container_name: pgadmin
environment:
- PGADMIN_DEFAULT_EMAIL=admin
- PGADMIN_DEFAULT_PASSWORD=admin
- PGADMIN_LISTEN_PORT=5050
ports:
- "5050:5050"
volumes:
database-data:
Another option is to connect the postgres container to localhost with
network_mode: host
But you lose the nice network isolation from docker that way
Be careful that the default postgres port is 5432 not 5431. You should update the port mapping for the postgres service in your compose file. The wrong port might be the reason for the issues you reported. Change the port mapping and then try to connect to postgres:5432. localhost:5432 will not work.