Populating a Dockerized PostgreSQL Database through a Dockerized Spring Boot Application - postgresql

I have a Postgres server running inside Docker. Inside this Postgres server, I have a database named 'aa'.
I also have a Docker image of a Spring Boot Application. When this image is executed in Docker, database tables should be created inside database 'aa'.
In order to achieve this, I executed the following steps:
Run the Postgres Server inside Docker
docker run --name PostgresServer --e POSTGRES_PASSWORD=*** -d Postgres
Enter PostgresServer then Create database 'aa'
sudo docker exec -it PostgresServer psql -U postgres
CREATE DATABASE AA;
3. Run the Sprint Boot Docker Image (this is where the problem happens)
docker run -v /Users/juancesard.pineda/Desktop/brapi:/home/brapi/properties -d brapicoordinatorselby/brapi-java-server:v2
I checked the logs: It says database 'aa' does not exist wherein clearly it exists in the Postgres Server
org.postgresql.util.PSQLException: FATAL: database "aa" does not exist
Some additional info:
Docker listens at port 8080
Postgres server listens at port 5432
My application.properties file looks like this:
server.port = 8080
server.servlet.context-path=/Users/juancesard.pineda/Desktop/brapi/application.properties/germplasm
spring.datasource.url=jdbc:postgresql://host.docker.internal:5432/aa
spring.datasource.username=****
spring.datasource.password=****
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.hbm2ddl.import_files=sql/crops.sql, sql/lists.sql, sql/locations.sql, sql/people.sql, sql/programs.sql, sql/trials.sql, sql/seasons.sql, sql/studies.sql, sql/breeding_methods.sql, sql/germplasm.sql, sql/attribute_defs.sql, sql/attribute_values.sql, sql/seed_lots.sql, sql/observation_units.sql, sql/crosses.sql, sql/pedigree.sql, sql/events.sql, sql/images.sql, sql/observation_variables.sql, sql/observations.sql, sql/samples.sql, sql/allele_calls.sql, sql/genome_maps.sql, sql/references.sql, sql/vendor.sql
spring.mvc.dispatch-options-request=true
Am I missing some config in my application.properties file?
Thank you in advance

The problem is in your application.properties file. The datasource url is pointing to host.docker.internal. This should only be used when connecting something from inside a docker container to something running outside docker on the host machine (documentation). You need a different solution because your Spring server and Postgres server are both running inside docker containers.
You need a Docker Network, specifically a bridge network, to connect your different containers. Docker Bridge Networks
Try something like this
Run this command to create a network in docker called “brapi_net”
$> docker network create --driver bridge network_name
Run the postgres container and link it to the network. Create your database schema as normal.
$> docker run --name PostgresServer --network=network_name --e POSTGRES_PASSWORD=*** -d Postgres
$> sudo docker exec -it PostgresServer psql -U postgres
$> CREATE DATABASE aa;
With a Docker network, container names act as server names. Modify your application.properties to reflect this
spring.datasource.url=jdbc:postgresql://PostgresServer:5432/aa
Run the server container and link it to the network.
$> docker run -v /Users/juancesard.pineda/Desktop/brapi:/home/brapi/properties --network=network_name -d brapicoordinatorselby/brapi-java-server:v2

Related

No access to docker container's exposed port from host

when I start docker container like this:
sudo docker run -p5432:5432 -d -e POSTGRES_PASSWORD=test_pass -e POSTGRES_USER=test_user -e POSTGRES_DB=test_db --name postgres postgres:12
I can see it's started by command sudo docker ps. But when I try to connect to the container from host using
psql -Utest_user -p5432 -h localhost -d test_db
it just hangs for several minutes and then reports that wasn't able to connect.
But when I add --net host option like this:
sudo docker run --net host -p5432:5432 -d -e POSTGRES_PASSWORD=test_pass -e POSTGRES_USER=test_user -e POSTGRES_DB=test_db --name postgres postgres:12
everything starts working as expected, I can connect to the postgresql the same psql command.
The same happens to other containers which I run, not only created from postgres:12 image.
I can only make requests to them when I set --net host option.
But I need to expose different ports like for example 2000:5432 to run, for example, several postgres containers simultaneously.
What should I do to make it work? My machine is Ubuntu:20, in case if it matters, and docker is fresh new one installed by instruction from the official site yesterday.
You can't connect to database container because by default it only allows connections from the localhost ( local machines in the same network ).
When you start docker container it makes it's own network ( usually in 172.0.0.0/something ip range).
When you set the flag -net host, docker takes your host's ip address for it's own, and that's why you are able to connect to the database ( because then you are both on the same network ).
The solution is either use the -net host flag, or to edit the config file for the database container to allow external connections which is not recommended.

How to fix: 'Psql: could not connect to server: Connection refused' when using Postgres in a docker container in gitlab-ci

I’m currently trying to run fossology in Gitlab CI. Fossology requires an external database that can be set up from a schema created using pg_dump. When I'm trying to use psql I get the title error.
At the moment, I have a script that sets up a container that runs the required version of postgres (9.6). It then tries to run an .sql script via psql in the postgres container via docker exec. Upon doing so it gets the title error.
I have tried specifying both a port and a host when issuing the psql statement, neither of which worked. I have tried using localhost, 127.0.0.1, the IP address of the postgres container and the name of the container as a host. I have tried rewriting things in different scripts, but nothing seems to work.
After extensive google searching, many people seem to have the same error message but not for the same reasons and not usually when using a docker container to host the database.
When I have run the contents of my script in the command line, i do not get this error, the script works fine and I can connect to Fossology. The issue only arises when trying to do the same in Gitlab CI.
The sequence of steps (i.e. pasted line by line) that works when using the command line on Mac:
# creates blank database and hosts it in a docker container
docker run -d --name fossdb -p 5432:5432 postgres:9.6
docker cp /fossology_db_schema.sql fossdb:/fossy.sql
docker exec -it fossdb bash
psql postgres -U postgres
# creates user needed for database to work with fossology
create user fossy with password 'fossy';
create database fossology;
grant all privileges on database fossology to fossy;
\q
# builds the fossology database in the hosted blank database
psql fossology < fossy.sql
psql postgres -U postgres
\connect fossology
exit
What I am attempting in GitLab CI:
# creates container with postgres image
docker run -d --name fossdb -p 5432:5432 --network foss-net postgres:9.6
# creates blank database (error occurs here)
docker exec fossdb psql -h $(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' fossdb) -f ./createBlank.sql -U postgres
# builds fossology database from schema
docker exec fossdb psql -h $(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' fossdb) fossology < ./schema.sql -U postgres
createBlank.sql:
create user fossy with password 'fossy';
create database fossology;
grant all privileges on database fossology to fossy;
Expected results: runs createBlank.sql to create a blank database called fossology, then builds fossology database from schema
Actual results: psql: could not connect to server: Connection refused
Is the server running on host "172.19.0.2" and accepting
TCP/IP connections on port 5432?
Are you sure you set up postgres completely?
A few quick checks you can perform:
(Excuse me, you DID do that. goto suggestion 2)
suggestion 1: Did you tell postgres there is a user with a password? (createuser command)
https://www.postgresql.org/docs/9.2/app-createuser.html
suggestion 2: Did you tell postgres that user can connect, and how? (tcp or local sockets)
https://www.postgresql.org/docs/9.2/auth-pg-hba-conf.html

connection refused postgres docker

I made a small application with spring-boot, spring jpa data, that connects to a dockerized postgres instace and it works pretty fine, even if I try to connect via
'psql' to the dockerized postgres instace it works well. The porblem is when I try to dockerize an image's instance of my spring-boot application and I try to link it with the dockerized postegres instance.
The docker command I use is this
docker run -it --link mypgcontainerwithpwd:postgres --name postgresclient1 sprinbootjpa
As a I already mentioned the container mypgcontainerwithpwd is running and reachable either with a local application either via psql
psql -p 5555 postgres postgres
in the jar I'm going to execute the application.properties file looks like this
spring.datasource.url=jdbc:postgresql://localhost:5555/postgres
spring.datasource.username=postgres
spring.datasource.password=password
spring.jpa.generate-ddl=true
During the starting phase an exception is raised up that prints: connection refused localhost-> 5555
The dockerfile that builds the instace looks like this
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD ./SpringJPA-PostgreSQ-0.0.1.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
I'm new to docker and I didn't find anything to fix the issue, I'm running docker on windows 10 with unix containers.
Thanks to all.
In your property file you are stating that postgres is running in the same container as your Spring Boot application (localhost) which is not true as it is running in a different container.
Replace you property by this:
spring.datasource.url=jdbc:postgresql://postgres:5555/postgres
You could also point to the docker bridge ip which usually is 172.17.0.1.
Change -
spring.datasource.url=jdbc:postgresql://localhost:5555/postgres
TO
spring.datasource.url=jdbc:postgresql://postgres:5555/postgres
Since you started the client container with link --link mypgcontainerwithpwd:postgres which means your client will be able to reach your mypgcontainerwithpwd container using alias postgres. localhost means your client container itself & not mypgcontainerwithpwd.
This works, but I just want to emphasize Vivek's point that "postgres" comes from the container name and not the userID or the database type. I am using Docker Compose, so this name comes from my docker-compose.yml file.

Docker Postgres data volume on the host

I've a simple tiny issue. I have an app (ASPNET Core) and db (Postgres). I run the container of the db first and then run the app container so that the app can discover the db at runtime. Now I can connect the Postgres database using pgAdmin tool (On Windows) and everything works fine.
Now if I run the Postgres container with a data volume command like:
docker run -p 5432:5432 -d -v pg-data:/var/lib/postgresql/data --network=isolated_network --name postgres -e POSTGRES_PASSWORD=5432 postgres
Here, I can connect to Postgres instance running in the container and I get my data there. Here I have the question that where the data volume pg-data is available on the host?
Moreover, if I mount my Windows directories to the Docker Engine and run the command:
docker run -p 5432:5432 -d -v d:/data:/var/lib/postgresql/data --network=isolated_network --name postgres -e POSTGRES_PASSWORD=5432 postgres
I do see the data folder on in the D:\ drive but I can't connect to this instance of the Postgres container with pgAdmin tool and my app stops working.
In linux default location of volume is:
/var/lib/docker/volumes
For windows i am not sure. but you can inspect container that will give you path and all details that you want.
docker inspect containername

Docker Tomcat container unable to access Postgres container

I have a alpine docker with postgres, with listen address '*' and listening to 5432, which I'm deploying using
docker run -d --name postgres me/postgres:v1
and my tomcat container with oracle jre8, on which I'm deploying my rest web service using:
# Set environment
ENV CATALINA_HOME /opt/tomcat
EXPOSE 8080
# Launch Tomcat on startup
CMD ${CATALINA_HOME}/bin/catalina.sh run
RUN rm -rf ${CATALINA_HOME}/webapps/docs \
${CATALINA_HOME}/webapps/examples \
${CATALINA_HOME}/webapps/ROOT
# Deploying war file
ADD myapp.war ${CATALINA_HOME}/webapps/ROOT.war
# Restarting server after deploying
CMD ${CATALINA_HOME}/bin/catalina.sh run
And deploying it with
docker run -d -p 8080:8080 --name tomcat --link postgres:postgres me/tomcat:v1
Both are being executed on my laptop, with IP address 192.168.x.x, and I checked the port is listening.
Unfortunately my web service on tomcat cannot connect to the postgres service using
jdbc:postgresql://192.168.x.x:5432/dBName
Alternate I already tried: I launched postgres on it's own port using,
docker run -d -p 5432:5432 --name postgres me/postgres:v1
docker run -d -p 8080:8080 --name tomcat me/tomcat:v1
Then used
jdbc:postgresql://192.168.x.x:5432/dBName
and
jdbc:postgresql://localhost:5432/dBName
but neither seems to work.
In both cases I can see my web server running in tomcat manager, and I am able to access my dB using
psql -h localhost -p 5432 -d dBName -U myUser
as well as pgAdmin.
Any help in resolving this is appreciated.
Solution Update: While using --link, point to postgres (i.e., your postgresql container name) instead of IP
jdbc:postgresql://postgres:5432/dBName
Many thanks to #larsks for pointing it out.
While using --link, point to postgres (i.e., your postgresql container name) instead of IP
jdbc:postgresql://postgres:5432/dBName
So for a full solution, run your postgresql and tomcat container
docker run -d --name postgres me/postgresql:v1
docker run -d -p 8080:8080 --name tomcat --link postgres:postgres me/tomcat:v1
(Notice here I didn't put port for postgres container since it will already have 5432 exposed internally, unless you want to hit it from outside your host, you don't need to specify a port here)
And your server war file will the jdbc address above, postgres will automatically resolve to the container's IP address when they are linked.
Many thanks to #larsks for pointing it out.