API cannot connect to postgres database using docker compose - docker

I'm trying to use docker compose to connect my ASP.Net Core web api to my postgres database.
Here is my docker-compose file
version: "3.9"
services:
db:
image: postgres:15.1-alpine
container_name: db
restart: always
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: "MyPassword123"
ports:
- "5432:5432"
volumes:
- db_data:/var/lib/postgresql/data
api:
image: ${DOCKER_REGISTRY-}api
container_name: api
environment:
ASPNETCORE_ENVIRONMENT: Development
ConnectionStrings_Default: Server=db;Port=5432;Database=DB;User Id=postgres;Password=MyPassword123;
ports:
- "7001:80"
depends_on:
- db
build:
context: .
dockerfile: src/Services/Api/Dockerfile
volumes:
db_data:
Here are the logs of my postgres DB
db | 2023-01-19 09:46:17.887 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
db | 2023-01-19 09:46:17.887 UTC [1] LOG: listening on IPv6 address "::", port 5432
db | 2023-01-19 09:46:17.906 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db | 2023-01-19 09:46:17.921 UTC [50] LOG: database system was shut down at 2023-01-19 09:46:17 UTC
db | 2023-01-19 09:46:17.929 UTC [1] LOG: database system is ready to accept connections
But on the API side I get the messsage:
Unhandled exception. Npgsql.NpgsqlException (0x80004005): Failed to connect to [::1]:5432
The db is correctly created and I can access it from my machine using PGAdmin using localhost and port 5432.
Should I create a user defined bridge network? I'm pretty sure everything should work like this.
Any help would be greatly appreciated.

The [::1] in the error message from the API is the IPv6 address for localhost. So it looks like it's not picking up the server name correctly from your connection string.
Looking at the docs, it seems like the keyword for the server is 'Host' and not 'Server', so try
ConnectionStrings_Default: Host=db;Port=5432;Database=DB;User Id=postgres;Password=MyPassword123;
If that doesn't help, then please provide more information on how you take the connection string and establish the connection to the database in C#.

Related

Program in docker can't connect to PostgreSQL in docker

I run my Golang API and PostgreSQL with docker-compose.
My log with error connection refused:
db_1 |
db_1 | PostgreSQL Database directory appears to contain a database; Skipping initialization
db_1 |
api_1 | Unable to connect to database: dial tcp 0.0.0.0:5432: connect: connection refusedartpaper_api_1 exited with code 1
db_1 | 2021-12-26 15:18:35.152 UTC [1] LOG: starting PostgreSQL 14.1 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.3.1_git20211027) 10.3.1 20211027, 64-bit
db_1 | 2021-12-26 15:18:35.152 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
db_1 | 2021-12-26 15:18:35.152 UTC [1] LOG: listening on IPv6 address "::", port 5432
db_1 | 2021-12-26 15:18:35.216 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1 | 2021-12-26 15:18:35.329 UTC [22] LOG: database system was shut down at 2021-12-26 15:05:11 UTC
db_1 | 2021-12-26 15:18:35.515 UTC [1] LOG: database system is ready to accept connections
My config:
config := pgx.ConnConfig{
Host: "0.0.0.0",
Port: 5432,
Database: "artpaper",
User: "admin",
Password: "admin1",
}
I think mistake in docker-compose.yml or Dockerfile for API, because on correct ports docker ps:
0.0.0.0:5432->5432/tcp artpaper_db_1
Dockerfile for API:
FROM golang:1.17.5-alpine3.15
WORKDIR /artpaper
COPY ./ ./
RUN go mod download // download dependencies
RUN go build ./cmd/main/main.go // compile code to one binary file
EXPOSE 8080
CMD [ "./main" ] // run binary file
docker-compose.yml:
version: "3.3"
services:
db:
image: postgres:14.1-alpine3.15
volumes:
- ./data/db:/var/lib/postgresql/data
environment:
- POSTGRES_DB=artpaper
- POSTGRES_USER=admin
- POSTGRES_PASSWORD=admin1
ports:
- 5432:5432
api:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
depends_on:
- db
Password and user in API config like in docker-compose.yml
Hostname from container with api is 0.0.0.0:5432
In your Golang application try using: db:5432, not 0.0.0.0:5432.
version: '3.8'
services:
db:
image: postgres:14.1-alpine3.15
volumes:
- ./data/db:/var/lib/postgresql/data
environment:
- POSTGRES_DB=artpaper
- POSTGRES_USER=admin
- POSTGRES_PASSWORD=admin1
ports:
- 5432:5432
api:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
depends_on:
- db
debug:
image: postgres:14.1-alpine3.15
command: sleep 1d
Try connect to the database within:
docker-compose up -d
docker-compose exec debug ash -c 'psql -h db -U admin --dbname artpaper'
First: In config database host should be a db like in docker-compose.yml
Second: Postgres as a program does not have time to turn on inside the container. I added in api code delay before connection to database.

Docker containers in the same network cannot communicate with container names (M1 Mac)

I am trying to run express, Prisma ORM, and postgre applications in Docker.
I have two containers in the same network, but they cannot communicate with each other unless they use the actual IP address instead of the container name. Here is my docker-compose.yml file:
version: '3.8'
services:
web:
container_name: urefer-backend
networks:
- backend
build: .
volumes:
- .:/usr/app/
- /usr/app/node_modules
ports:
- "5000:5000"
depends_on:
- db
environment:
DATABASE_URL: postgresql://postgres:docker#urefer-db:5432/urefer?schema=public
stdin_open: true # docker run -i
tty: true # docker run -t
db:
networks:
- backend
image: postgres:latest
environment:
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-docker}
POSTGRES_DB: "urefer"
container_name: urefer-db
restart: always
ports:
- 5432:5432
volumes:
- database-data:/var/lib/postgresql/data/
volumes:
database-data:
networks:
backend:
The urefer-backend container and the urefer-db container are in the same "backend" network. However, when I run docker-compose up --build, I always have a connection issue:
urefer-backend | Error: Error in migration engine: Can't reach database server at `urefer-db`:`5432`
urefer-backend |
urefer-backend | Please make sure your database server is running at `urefer-db`:`5432`.
When I replace "urefer-db" with the actual IP address of the db server, then it connects successfully. This I think means that there is something wrong with the DNS setup.
Could anyone please help me connect the two containers without using the actual IP address? the IP address for DB is always changing whenever I stop and restart the container, so it is really bothering to use.
#edit:
I got a suggestion from a comment to put all log and errors I got on the console.
urefer-db |
urefer-db | PostgreSQL Database directory appears to contain a database; Skipping initialization
urefer-db |
urefer-db | 2021-10-01 14:44:57.165 UTC [1] LOG: starting PostgreSQL 14.0 (Debian 14.0-1.pgdg110+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
urefer-db | 2021-10-01 14:44:57.165 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
urefer-db | 2021-10-01 14:44:57.165 UTC [1] LOG: listening on IPv6 address "::", port 5432
urefer-db | 2021-10-01 14:44:57.168 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
urefer-db | 2021-10-01 14:44:57.171 UTC [28] LOG: database system was shut down at 2021-10-01 14:44:49 UTC
urefer-db | 2021-10-01 14:44:57.177 UTC [1] LOG: database system is ready to accept connections
urefer-backend | Prisma schema loaded from prisma/schema.prisma
urefer-backend | Datasource "db": PostgreSQL database "urefer", schema "public" at "urefer-db:5432"
urefer-backend |
urefer-backend | Error: P1001: Can't reach database server at `urefer-db`:`5432`
urefer-backend |
urefer-backend | Please make sure your database server is running at `urefer-db`:`5432`.
urefer-backend | Prisma schema loaded from prisma/schema.prisma
urefer-backend |
When the backend service is up, it runs the command npx prisma migrate dev --name init, and this command creates this connection error.
You should use host name instead of container name. Containers uses hostname when communicate each other. So if you add hostname docker-compose for container it will work
version: '3.8'
services:
web:
container_name: urefer-backend
networks:
- backend
build: .
volumes:
- .:/usr/app/
- /usr/app/node_modules
ports:
- "5000:5000"
depends_on:
- db
environment:
DATABASE_URL: postgresql://postgres:docker#urefer-db:5432/urefer?schema=public
stdin_open: true # docker run -i
tty: true # docker run -t
db:
networks:
- backend
image: postgres:latest
environment:
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-docker}
POSTGRES_DB: "urefer"
container_name: urefer-db
hostname: urefer-db
restart: always
ports:
- 5432:5432
volumes:
- database-data:/var/lib/postgresql/data/
volumes:
database-data:
networks:
backend:

Docker compose container is not visible inside pgAdmin4

I created a docker file to create a pgAdmin4 container and a postgres container.
version: '3.8'
services:
postgres:
container_name: pg_container
image: postgres
restart: always
environment:
POSTGRES_USER: webquiver
POSTGRES_PASSWORD: webquiver
POSTGRES_DB: quiver_db
ports:
- "5432:5432"
pgadmin:
container_name: pgadmin4_container
image: dpage/pgadmin4
restart: always
environment:
PGADMIN_DEFAULT_EMAIL: admin#admin.com
PGADMIN_DEFAULT_PASSWORD: admin
ports:
- "5050:80"
When running docker compose up I can go to the localhost:5050 to reach pgAdmin4 and login in with my credentials you can see in the code.
But when I use the dropdown menu for servers, it is empty. nothing is created. And I can not create any server there. It does not allow me to. I get the Error:
Unable to connect to server:
could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and
accepting
TCP/IP connections on port 5432?
could not connect to server: Address not available
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 5432?
please help. THX ^^
greetings
I've reproduced your docker-compose file and everything is fine with it.
I'm guessing there is a misunderstanding how postgres and pgadmin are interacting with each other from scratch.
pgadmin is only the frontend that you can connect to a postgres database, it's not automatically searching for any existing postgres server.
I'm able to add the server inside the pgadmin with this host and port: postgres:5432 As inside the docker will resolve the service name as hostname postgres to the other service pgadmin.
This configuration will be lost, when the composition is restartet, as no volumes to persist the configuration are specified. Therefore, you have to follow steps from Importing-servers and repeat them every time you start the composition.
eg: build you own pgadmin image that specifies the json to import at startup
Use the docker compose build: property to specify a source
Ok after a night of sleep I found the issue. For the server Host I wrote the db name and not the real container name. So pgAdmin could not find the container.
Have a nice day. : )

Cannot connect to container within compose but host connectivity works

Using the docker compose file
version: '3'
services:
sqlserver:
image: microsoft/mssql-server-linux:2017-latest
ports:
- 1401:1433
volumes:
- ./db:/tmp/data
environment:
- ACCEPT_EULA=Y
- "MSSQL_SA_PASSWORD='Password99'"
command:
- /tmp/data/run.sh
api:
build:
context: .
dockerfile: dockerfile
depends_on:
- sqlserver
links:
- sqlserver
ports:
- 5000:80
With appsettings.json connection string:
"ConnectionStrings": {
"Entities": "data source=(local),1401;initial catalog=DB_Test;user id=sa;password=Password99;enlist=False;multipleactiveresultsets=True;connect timeout=30;App=EntityFramework"
},
I get the error
api_1 | System.Data.SqlClient.SqlException (0x80131904):
A network-related or instance-specific error occurred while
establishing a connection to SQL Server. The server was not found or
was not accessible. Verify that the instance name is correct and that
SQL Server is configured to allow remote connections. (provider: TCP
Provider, error: 40 - Could not open a connection to SQL Server)
A connection from a host running api instance to the sql server instance running in docker-compose works fine, so the SQL instance running in the container is fine.
Can anyone help with connectivity between api & sql inside docker?
Thanks!
Inside docker the hostname for the database will be "sqlserver" not localhost or 127.0.0.1

install influxdb in a docker with non standard port

I am new in dockers and I need some help please.
I am trying to install TICK in docker. Influxdb, Kapacitor and Chronograf will be installed in dockers but telegraf will be installed in each machine that will be necessary.
Port 8086 in my host is in use, so I will use 8087 for influxdb. Is it posible to configure influxdb dokcer with -p 8087:8086? If so, which port should I configure in conf files?
Docker compose file will be:
version: '3'
networks:
TICK_network:
services:
influxdb:
image: influxdb
container_name: influxdb
networks:
TICK_network:
ports:
- "8087:8086"
- "8083:8083"
expose:
- "8087"
- "8083"
hostname: influxdb
volumes:
- /var/lib/influxdb:/var/lib/influxdb
- /etc/influxdb/influxdb.conf:/etc/influxdb/influxdb.conf:ro
restart: unless-stopped
kapacitor:
image: kapacitor
container_name: kapacitor
networks:
TICK_network:
links:
- influxdb
ports:
- "9092:9092"
expose:
- "9092"
hostname: kapacitor
volumes:
- /var/lib/kapacitor:/var/lib/kapacitor
- /etc/kapacitor/kapacitor.conf:/etc/kapacitor/kapacitor.conf:ro
restart: unless-stopped
chronograf:
image: chronograf
container_name: chronograf
networks:
TICK_network:
links:
- influxdb
- kapacitor
ports:
- "8888:8888"
expose:
- "8888"
hostname: chronograf
volumes:
- /var/lib/chronograf:/var/lib/chronograf
restart: unless-stopped
influxdb.conf is edited to point to port 8087
[http]
enabled = true
bind-address = ":8087"
auth-enabled = true
Kapacitor.conf and telegraf.conf are also pointing to port 8087.
But I am receiving following errors:
Telegraf log:
W! [outputs.influxdb] when writing to [http://localhost:8087]: database "telegraf" creation failed: Post http://localhost:8087/query: EOF
E! [outputs.influxdb] when writing to [http://localhost:8087]: Post http://localhost:8087/write?db=tick: EOF
E! [agent] Error writing to outputs.influxdb: could not write any address
kapacitor log:
vl=error msg="encountered error" service=run err="open server: open service *influxdb.Service: failed to link subscription on startup: authorization failed"
run: open server: open service *influxdb.Service: failed to link subscription on startup: authorization failed
What you did is correct if you want to access those services from outside the Docker network, that is from the host access to localhost:8087 for example.
However, this is not correct in your case. As you are using docker-compose, all the services are in the same network, and therefore, you need to attack the port in which the influx is listening in the Docker network (the right-side port), that is, 8086.
But, even if you do so, it will still not work. Why? Because you are trying to access localhost from the Telegraf container. You need to configure the access to influx as influxdb:8086, not as localhost:8087. influxdb here is the name of the container, if for example you name it ailb90, then it would be ailb90:8086
thanks for your answer. But telegraf is not installed in a container. This is why I access to database using urls = ["http://localhost:8087"].
In the other hand, kapacitor is installed in a docker container. The conexion to influxdb is made using the string urls=["https://influxdb:8087"]. If I cinfigure kapacitor in port 8086 it gives a connexion error (I think it is because influxdb.conf is pointing to port 8087):
lvl=error msg="failed to connect to InfluxDB, retrying..." service=influxdb cluster=default err="Get http://influxdb:8086/ping: dial tcp 172.0.0.2:8086: connect: connection refused"

Resources