Scala JDBC project won't run outside of Docker Container? - scala

com.zaxxer.hikari.pool.HikariPool$PoolInitializationException: Failed to initialize pool: The connection attempt failed.
I get the above error when entering sbt run However, inside my docker containers everything works fine.
Inside the first container I have a postgres database. The second container I have an image built from my project folders. When I run docker-compose up --build everything works fine.
I suspect the project (actual codebase) can't see the postgres database in docker-compose container.
Do I need another postgres database outside the docker-compose containers to go with my project code outside the containers?
docker-compose.yml file.
version: '3.6'
services:
# App Backend PostgreSQL
postgres:
container_name: sportsAppApiDb
image: postgres:11.7-alpine
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: password
POSTGRES_URL: postgres://admin:password#localhost:5432/sportsappapi
POSTGRES_DB: sportsappapi
POSTGRES_HOST: postgres
ports:
- "5432:5432"
# App Backend
sports-app-api:
container_name: sportsAppApi
build: ./
volumes:
- ./:/usr/src/sports-app-api
command: sbt run
working_dir: /usr/src/sports-app-api
ports:
- "8000:8000"
environment:
POSTGRES_URI: postgres://admin:password#postgres:5432/sportsappapi
Entrypoint for scala project
object SportsAppApiStartup extends App {
SportsAppApiDb(SportsAppApiConfig.appDb).init
WebServer(Endpoints.handler, 8000).start()
println(s"Running sports-app-api on port: 8000")
}

Your database is not accessible outside of docker-compose under postgres:5432. Try to connect to it through psql or pgcli or other client and you'll see.
When you'll call docker-compose ps or docker ps you'll be able to see how to connect to Postgres docker image (under ports) - most likely it will be something like 0.0.0.0:5432.
E.g. if I have:
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d90871418bcb postgres "docker-entrypoint.s…" 2 weeks ago Up 4 days 0.0.0.0:7766->5432/tcp postgres_container
it means that Postgres was available under 0.0.0.0:7766 from outside Docker.
This has nothing to do with Scala, sbt and slick as far as I can tell.

Related

Docker with postgresql in flask web application (part 2)

I am building a Flask application in Python. I'm using SQLAlchemy to connect to PostgreSQL.
In the flask application, I'm using this to connect SQLAlchemy to PostgreSQL
engine = create_engine('postgresql://postgres:[mypassword]#db:5432/employee-manager-db')
And this is my docker-compose.yml
version: '3.8'
services:
backend:
build:
context: .
dockerfile: Dockerfile
ports:
- 8000:8000
volumes:
- .:/app
links:
- db:db
depends_on:
- pgadmin
db:
image: postgres:14.5
restart: always
volumes:
- .dbdata:/var/lib/postgresql
hostname: postgres
environment:
POSTGRES_PASSWORD: [mypassword]
POSTGRES_DB: employee-manager-db
pgadmin:
image: 'dpage/pgadmin4'
restart: always
environment:
PGADMIN_DEFAULT_EMAIL: [myemail]
PGADMIN_DEFAULT_PASSWORD: [mypassword]
ports:
- "5050:80"
depends_on:
- db
I can do "docker build -t employee-manager ." to build the image. However, when I do "docker run -p 5000:5000 employee-manager" to run the image, I get an error saying
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not translate host name "db" to address: Try again
Does anybody know how to fix this? Thank you so much for your help
Your containers are on different networks and that is why they don't see each other.
When you run docker-compose up, docker-compose creates a separate network and puts all the services defined inside docker-compose.yml on that network. You can see that with docker network ls.
When you run a container with docker run, it is attached to the default bridge network, which is isolated from other networks.
There are several ways to fix this, but this one will serve you in many other scenarios:
Run docker container ls and identify the name or ID of the db container that was started with docker-compose
Then run your container with:
# ID_or_name from the previous point
docker run -p 5000:5000 --network container:<ID_or_name> employee-manager
This attached the new container to the same network as your database container.
Other ways include creating a network manually and defining that network as default in the docker-compose.yml. Then you can use docker run --network <network_name> ... to attach other containers to that network.
docker run doesn't read any of the information in the docker-compose.yml file, and it doesn't see things like the Docker network that Compose automatically creates.
In your case you already have the service fully-defined in the docker-compose.yml file, so you can use Compose commands to build and restart it
docker-compose build
docker-compose up -d # will delete and recreate changed containers
(If the name of the image is important to you – maybe you're pushing to a registry – you can specify image: alongside build:. links: are obsolete and you should remove them. I'd also avoid replacing the image's content with volumes:, since this misses any setup or modification that's done in the Dockerfile and it means you're running untested code if you ever deploy the image without the mount.)

Postgres, Local installed instance interfered with Docker instance

Windows 10-Pro. Have a local Postgres installed and working fine.
With it running, VSC terminal, docker-compose up the following ok:
version: '3.8'
services:
postgres:
image: postgres:10.4.2
ports:
- '5432:5432'
volumes:
- ./sql:/docker-entrypoint-initdb.d
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass1
POSTGRES_DB: db
But PSQL shell always complain password authentication failed for user.
Stopping postgres service from Windows Services and docker-compose up, PSQL shell authentication and query ok. But VSC terminal keep complaining another thing:
FATAL: password authentication failed for user "postgres"
DETAIL: User "postgres" has no password assigned.
Connection matched pg_hba.conf line 95: "host all all all md5"
How to stop the above error when docker container's instance is running? Also, possible to co-run both local and docker?
Hope you are enjoying you containers journey !
I tried to execute your docker-compose as it was but cannot fetch the postgres:10.4.2 image:
❯ docker-compose up
[+] Running 0/1
⠿ postgres Error 2.1s
Error response from daemon: manifest for postgres:10.4.2 not found: manifest unknown: manifest unknown
so i decided to use postgres:14.2 instead. Since I dont have your sql script i'll comment out the volume section.
Here is how my docker-compose looks like:
version: '3.8'
services:
postgres:
image: postgres:14.2
ports:
- '5432:5432'
# volumes:
# - ./sql:/docker-entrypoint-initdb.d
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass1
POSTGRES_DB: db
So, when a execute the compose I got this:
❯ docker-compose up -d
[+] Running 1/1
⠿ Container postgre-local-and-dockercompose-71984505-postgres-1 Started
❯ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
4b90573f6108 postgres:14.2 "docker-entrypoint.s…" 18 seconds ago Up 15 seconds 0.0.0.0:5432->5432/tcp postgre-local-and-dockercompose-71984505-postgres-1
When i connect to the container with:
❯ docker exec -it postgre-local-and-dockercompose-71984505-postgres-1 bash
root#4b90573f6108:/#
and execute this command to connect to your created DB and connect with the "pass1" password:
root#4b90573f6108:/# psql --username=$POSTGRES_USER -W --host=localhost --port=5432 --dbname=$POSTGRES_DB
Password:
psql (14.2 (Debian 14.2-1.pgdg110+1))
Type "help" for help.
db=#
everything is fine.
So I advise you to use the same postgres:14.2 image i tried with (patched with the last security issues) and do the same test.
If you want me to test exactly what you are doing just send your sql scripts.
To answer your second question, yes it is possible to co-run both local and docker postgres instances
you just have to port-forward the postgresql port of your container to another port like this:
version: '3.8'
services:
postgres:
image: postgres:14.2
ports:
- '5433:5432'
# volumes:
# - ./sql:/docker-entrypoint-initdb.d
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass1
POSTGRES_DB: db
since there is no port conflict (your local db is running on 5432 and your docker db on 5433), everything will work fine (I will use dbeaver to try to connect ):
PERFECT !
Hope I answered your questions.
bguess.

Connect to Postgres container with PhpStorm

I would like to access my Postgres database (docker container) from PhpStorm.
docker-compose.yml
# Run docker-compose build
# Run docker-compose up
# Live long and prosper
version: '3.1'
services:
apache:
build: .docker/apache
container_name: sf-apache
ports:
- 82:80
volumes:
- .docker/config/vhosts:/etc/apache2/sites-enabled
- ${SYMFONY_APP}:/home/wwwroot/sf3
depends_on:
- php
postgres:
container_name: postgres
restart: always
image: 'postgres:12.6'
ports:
- "5432:5432"
environment:
- "POSTGRES_USER=${PGSQL_ADMIN_USER}"
- "POSTGRES_PASSWORD=${PGSQL_ADMIN_PASSWORD}"
volumes:
- ./API/var/postgres:/var/lib/postgresql/data
- .docker/postgresql/init-database.sh:/docker-entrypoint-initdb.d/init-database.sh
My PhpStorm config :
I can access to my database via docker exec -it postgres bash
If php storm is on the same host then you need to use localhost. If both phpstorm and pg is part of the same compose file , then you would use the service name since both would be in the same virtual network
I found the solution.
I have a Postgres local and a Postgres with docker. My Postgres local get the upper hand on my docker Postgres. I have killed the service and put the container service name on it.
Works perfectly.
Thanks for you help,

How to connect to a postgres database when having two docker-compose files?

First I have built an image using Dockerfile:
FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/*-SNAPSHOT.jar
ADD ${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
as I have two docker-compose files one for production:
version: "3"
services:
app:
image: "demo:latest"
container_name: demo-production-api
restart: always
depends_on:
- "productiondb"
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://productiondb:5432/testdb
- SPRING_DATASOURCE_HIKARI_JDBC_URL=jdbc:postgresql://productiondb:5432/testdb
- SPRING_DATASOURCE_USER=tester
- SPRING_DATASOURCE_PASSWORD=test
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
ports:
- "8440:8443"
productiondb:
image: "postgres:latest"
container_name: productiondb
ports:
- "5430:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
volumes:
- postgres-db-production:/usr/local/var/postgres
volumes:
postgres-db-production:
and one for develop:
version: "3"
services:
app:
image: "demo:latest"
container_name: demo-develop-api
restart: always
depends_on:
- "developdb"
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://developdb:5432/testdb
- SPRING_DATASOURCE_HIKARI_JDBC_URL=jdbc:postgresql://developdb:5432/testdb
- SPRING_DATASOURCE_USER=tester
- SPRING_DATASOURCE_PASSWORD=test
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
ports:
- "8441:8443"
developdb:
image: "postgres:latest"
container_name: developdb
ports:
- "5431:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
volumes:
- postgres-db-develop:/usr/local/var/postgres
volumes:
postgres-db-develop:
I build both images using:
docker-compose -p demo-production-api -f docker-compose.yml up -d && docker-compose -p demo-develop-api -f docker-compose-develop.yml up -d
Now I was able to build both environments demo-develop-api and demo-production-api as well, the Spring Boot application from demo-develop-api docker image runs using the command:
docker run -it demo-develop-api
The application runs but I keep getting this error:
Caused by: java.net.UnknownHostException: productiondb
The above error happened after changing the database host in the application.properties file from localhost to productiondb first I was getting the following:
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.
Why this issue occurring or what is the cause?
How to solve this kind of issue?
As far as I see it, the issue might be that you have binded port 5430 and 5431 to 5432 and you might be having the port set to 5432 in your application.resources file. Your application should be trying to connect to the database by using either port 5430 or 5431 for production and development respectively. Please check and try this. So, make a port change in the application.resources file.
So after a long time of debugging and trials, hopefully, this is is going to save people hours, it turned out that actually, the Spring Boot application inside the container was restarting runs and crashes without any errors, which made me more confused why it is not listening or opening a port. I even doubt it that it could be a firewall or something. So basically I just tried to get a shell from the container by doing:
docker exec -it <container id or image> sh
Note: Since I am using the image openjdk:8-jdk-alpine don't do below you will not get a shell:
docker exec -it <container id or image> bash
Then I tried to get a list of open ports by doing:
netstat -tulpn | grep ":8443"
The port 8443 was not listed, I thought it could be a problem with the java program not being running, tried to execute the spring boot which executed but without any errors and the shell itself was exiting which made me more confused.
Until I have found out that container was restartig because of Spring Boot was crashing. So I enabled verbose mode by adding the below properties to application.properties then rebuild the image again:
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=DEBUG
So I retried the last above steps where I get a shell and execute the app.jar and it turned out that the database testdb did not exist.
UPDATE: So to sum up here how I modifed my project, I created two Spring Boot Profiles for my case one for develop application-develop.properties and one for production application-production.properties:
So inside the application-develop.properties I have it mapped to a develop postgres container host and port:
spring.datasource.url=jdbc:postgresql://developdb:5432/testdb
spring.datasource.hikari.jdbc-url=jdbc:postgresql://developdb:5432/testdb
spring.datasource.username=tester
spring.jpa.generate-ddl=true
spring.datasource.password=test
spring.jpa.database-platform=postgres
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
server.port=8443
And for application-production.properties:
spring.datasource.url=jdbc:postgresql://productiondb:5432/testdb
spring.datasource.hikari.jdbc-url=jdbc:postgresql://productiondb:5432/testdb
spring.datasource.username=tester
spring.jpa.generate-ddl=true
spring.datasource.password=test
spring.jpa.database-platform=postgres
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
server.port=8443
And in the docker-compose file for develop I just define the Spring Boot profile environment variable to:
environment:
- SPRING_PROFILES_ACTIVE=develop
And for production docker-compose file I define it as below:
environment:
- SPRING_PROFILES_ACTIVE=production

Docker compose doesn't connect two containers

I have two containers that don't connect to each other:
1. I made an image postgres that get data from dump.sql
here is Dockerfile:
FROM postgres:11.1-alpine
COPY restore_db.sh /docker-entrypoint-initdb.d/
COPY db.sql /backup/
ENV PGDATA=/data
Then I created container with docker run --name db -p 5432:5432 db
4.I made a image with app. Dockerfile for app look like:
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY build/libs/ /app/
# Make port 80 available to the world outside this container
EXPOSE 8085
# Define environment variable
ENV NAME app
# Run app when the container launches
CMD java -jar /app/olympic-0.0.1-SNAPSHOT.jar
I made a container with run.
then i use docker-compose up with file that looks like:
version: '3'
services:
db:
image: db-data
container_name: postgres
ports:
- 5432:5432
volumes:
- ./pg_data:/data
environment:
POSTGRES_DB: innovation
POSTGRES_USER: postgres
PGDATA: /data
restart: always
web:
image: app
container_name: roc
environment:
POSTGRES_HOST: db
ports:
- 8085:8085
restart: always
links:
- db
```
here is property file:
```
spring.datasource.url=jdbc:postgresql://db:5432/innovation
spring.datasource.username=postgres
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.root=INFO
spring.output.ansi.enabled=ALWAYS
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
spring.liquibase.change-log=classpath:liqubase/db.changelog-master.xml
spring.liquibase.url=jdbc:postgresql://db:5432/innovation
spring.liquibase.user=postgres
```
Thet are not able to be connected.
I always got an error:
org.postgresql.util.PSQLException: Connection to db:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
First of all I dont see any network defined in your Docker files for both containers
So I assume ther are on $project-default network.
docker network inspect $project-default
will give you list of all containers using default network.
Now coming to the containers, Let's assume DB is Container 1 (10.1.1.2) and Spring App is Container 2 (10.1.1.3).
You can get running containers IP by running
docker inspect containerName
You are exposing 5432 and 8085 port for db and Spring respectively
Inside Spring app container property file spring.datasource.url
localhost:5432 or db:5432 (not sure what is db hostname mapped to) is not accessable as DB is in different container.
You can try 10.1.1.2:5432
When you are exposing 5432 and 8085 port from Host machine you can access these port.
eg in Docker for Windows it would be 192.168.99.100:5432
but same cant be access from inside container.
spring.datasource.url=jdbc:postgresql://10.1.1.2:5432/innov should work assuming DB is up and running