How to create database in TestContainers? - testcontainers

I'm using this dependency:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<version>1.5.1</version>
<scope>test</scope>
</dependency>
this is the Container, lauched with my tests:
#ClassRule
public static PostgreSQLContainer postgres = new PostgreSQLContainer()
.withDatabaseName("user")
.withUsername("postgres")
.withPassword("postgres");
but when i'm trying to stablish connection to database user i'm receiving exception:
PSQLException: FATAL: database "user" does not exist
In this container only present default DB "postgres".
How to create database "user"?

The problem was because container return JDBC_URL with random port, and by the default port is accessible default Postgres DB, but thee neede one is on random port
this is the workaround:
#ClassRule
public static DockerComposeContainer environment =
new DockerComposeContainer(new File("src/test/resources/docker-compose-postgres.yml"))
.withExposedService("postgres-it", 5432);
this is the docker-compose yml:
version: "2"
services:
postgres-it:
image: postgres
ports:
- 5432:5432
hostname: postgres-it
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: user

I tried this test from TestContainers project with DB_NAME set to "user" and USER/PWD set to "postgres", the result was successful.
Make sure you configure your connection correctly, or consider JDBC-style containers.

Related

How dockerize Spring Boot app if Postgres db is going to be AWS RDS?

version: "3.7"
services:
api_service:
build: .
restart: always
ports:
- 8080:8080
depends_on:
- postgres_db
links:
- postgres_db:database
postgres_db:
image: "postgres:11.4"
restart: always
ports:
- 5435:5432
environment:
POSTGRES_DB: testDb
POSTGRES_PASSWORD: admin
this is my YAML file.
and I got properties
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://database:5432/testDb
spring.datasource.username=postgres
spring.datasource.password=admin
if my Postgres is rds then do I need to compose them or I just can go with Dockerfile for jar only and not YAML file?
You can create environment variables for the RDS address, RDS username, RDS password and RDS port. Pass it to the Dockerfile to the api_service. Your api_service should know to assemble Postgres connection string based on the environment variables. Please check - Spring Profiles in connection String
Those Spring properties values are probably incorrect in most of the environments in which you might run your application. In your unit-test environment the database might be H2 or HDBC instead of PostgreSQL; in a local-developer setup it will be on localhost; in RDS it will be a different name again. These host names and credentials should not be in your src/main/resources tree anywhere.
Spring allows you to set Spring properties using environment variables. So you can set e.g. spring.datasource.url at the point where you deploy your application. In your Compose setup, for example:
version: "3.8"
services:
api_service:
build: .
restart: always
ports:
- 8080:8080
depends_on:
- postgres_db
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://postgres_db:5432/testDb
- SPRING_DATASOURCE_USERNAME=postgres
- SPRING_DATASOURCE_PASSWORD=admin
postgres_db:
image: "postgres:11.4"
restart: always
ports:
- 5435:5432
environment:
POSTGRES_DB: testDb
POSTGRES_PASSWORD: admin
If your production environment uses RDS, then it should be enough to remove the postgres_db container and change the SPRING_DATASOURCE_* environment variables to match the RDS host name and credentials. You don't have to recompile anything or change the contents of your jar file.

How to connect Spring Boot application to a Postgres database that's in a Docker container

I'm working on a Spring Boot application and it has to use a database. I can run the database locally and connect to it without problems but now I'm trying to run just the database in a Docker container and connect to it with my Spring application and I can't get it to work.
This is the docker-compose file that is used to start the docker container with the postgres image
version: '3.8'
services:
db:
container_name: postgres-container
image: postgres:14.1-alpine
restart: always
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
- POSTGRES_DB=shop
ports:
- '5432:5432'
volumes:
- db:/var/lib/postgresql/data
volumes:
db:
driver: local
This is the application.yml file
spring:
datasource:
url: jdbc:postgresql://localhost:5432/shop
username: postgres
password: password
This is the V1.0__init.sql file used to initiate a table in the database
CREATE TABLE IF NOT EXISTS igredient(
id SERIAL PRIMARY KEY NOT NULL,
name VARCHAR(50) NOT NULL,
price INTEGER NOT NULL,
is_healthy BOOL NOT NULL,
type VARCHAR(10)
);
I tried connecting to the database with DBeaver in the following way (can't upload an image):
Host: localhost
Port: 5432
Database: shop
Authentication: Database Native
Username: postgres
Password: password
Advanced:
Local Client: PostgreSQL 14
When I test the connection I get this "FATAL: database "shop" does not exist" and I don't understand what I'm missing. I have been googling for too long and I don't have a clue what else to do.
I tried running the Spring application but I get this error:
org.postgresql.util.PSQLException: FATAL: database "shop" does not exist
and this:
Message : FATAL: database "shop" does not exist
Also DB Browser in Intellij is giving me this error in the V1.0__init.sql file (I guess because I'm not connected to a database):
Invalid or incomplete statement
expected one of the following:
BITMAP CONTEXT DIRECTORY EDITIONABLE EDITIONING FORCE FUNCTION INDEX MATERIALIZED MULTIVALUE NO NONEDITIONABLE OR PACKAGE PROCEDURE PUBLIC ROLE SEQUENCE SYNONYM TRIGGER TYPE UNIQUE USER VIEW

spring jpa authentication fail

I'm running postgres as docker container and using spring jpa trying to connect with the DB. simple operation. Even though, I gave right username and password, still JPA throws following exception
org.postgresql.util.PSQLException: FATAL: password authentication failed for user "admin"
docker-compose.yaml
version: '3.9'
services:
postgres:
image: postgres:14-alpine
ports:
- 5432:5432
environment:
- POSTGRES_PASSWORD=admin
- POSTGRES_USER=admin
- POSTGRES_DB=mydb
Application.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=admin
spring.datasource.password=admin
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.format_sql=true

Connection refused to localhost:5432 through Docker Compose after already specifying the name of the service instead of localhost

I have a few microservices running under Docker. They are Zuul, Eureka, and a configuration server. These are working but when I start my authorization-service, it says I cannot connect to PostgreSQL.
version: '3'
services:
eureka-discovery:
...
zuul-gateway:
...
config:
...
postgres:
image: postgres
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: root
POSTGRES_DB: spring_microservices
ports:
- 5432:5432
authorization-service:
image: authorization-service:0.0.1
environment:
- eureka.client.serviceUrl.defaultZone=http://eureka-discovery:8761/eureka
- spring.cloud.config.uri=http://zuul-gateway:8765/config-service
- spring.datasource.url=jdbc:postgresql://postgres:5432/spring_microservices
depends_on:
- eureka-discovery
- zuul-gateway
- config
- postgres
ports:
- 1001:1001
What's confusing is that I am specifying postgres instead of localhost to make the connection, but the error continues to say "localhost". You see I override other properties the same way I do with spring.datasource.url and they work but this one.
org.postgresql.util.PSQLException: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
I attempted a few variations I could find around, such as using a different service name, using SPRING_DATASOURCE_URL, using the connection string as postgresql://[user]:[pass]#[service]/[database], I tried moving this line to the config-service instead since the database connection is indeed in the Spring Cloud Config Server microservice, but all to no avail. What's missing? It seems to be correct comparing to all the solutions I found.
I made Spring Config Server see my repository for the configurations. Thinking better, if it's reading from the repository it's evident that changing it on the fly locally won't work, so I updated the connection string of the configuration file for authorization-service then pushed, and it worked. I wonder if this is a good practice or better to make Config Server see local files and change it on the fly?
Hi i hope you are okay !
above your authorization-service add a link like this:
links:
- "postgres"
Greetings

Problems deploying a project with docker

I recently started trying to use the docker in a more advanced way. I had already used it to create mysql server and postgres server containers. At the moment I have a Spring test project, which runs normally when starting up. But I tried to instantiate the same with docker, it successfully creates a mysql server, and instantiates a tomcat, but it does not go up the project itself.
Dockerfile content:
FROM tomcat:9-jre11
ENV CATALINA_OPTS="$CATALINA_OPTS -Duser.timezone=America/Sao_Paulo -Xms1024m -Xmx2560m -XX:+UseParallelGC -XX:-OmitStackTraceInFastThrow"
ADD ./smartCircuit/target/*.war $CATALINA_HOME/webapps/
EXPOSE 8080
CMD catalina.sh run;
docker-compose.yaml content:
version: '3.5'
services:
db:
image: mysql:5.7
restart: always
container_name: mysql-container
environment:
MYSQL_DATABASE: 'smart_circuit'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
ports:
# <Port exposed> : < MySQL Port running inside container>
- '3307:3306'
expose:
# Opens port 3306 on the container
- '3306'
# Where our data will be persisted
volumes:
- my-db:/var/lib/mysql
web:
build: .
container_name: tomcat
ports:
- 8080:8080
environment:
DB_URL: jdbc:mysql://mysql-container:3306/smart_circuit?useSSL=false
DB_USER: user
DB_PASSWORD: password
links:
- db:mysql-container
# Names our volume
volumes:
my-db:
I'm expecting my application to start and be accessible when I use the command "sudo docker-compose up --build". For example I have one RestController mapped "project" with a method mapped "find" which receives an id and either retrieves it when found or throws a NotFoundException.
When I run it through InteliJ without docker it works, but when I start it through docker I get a Tomcat 404 Not Found return.
Basically I can access the mysql instance with no problem and the tomcat is kind of working, but the project itself is not being deployed.

Resources