1

I have a spring-boot java application running in a docker container on my linux host machine. I have a postgresql instance installed on the host that I want to connect to from the running container.

I've tried multiple different approaches (--network="host" is not what I want).

My Dockerfile looks like this:

FROM openjdk:13-ea-9-jdk-alpine3.9
EXPOSE 8080
CMD mkdir /opt/StatisticalRestService
COPY target/StatisticalRestService-0.0.1-SNAPSHOT.jar         
/opt/StatisticalRestService/
COPY DockerConfig/application.yml /opt/StatisticalRestService/
RUN chmod 777 /opt/StatisticalRestService/StatisticalRestService-0.0.1-SNAPSHOT.jar \
&& ls -l /opt/StatisticalRestService/StatisticalRestService-0.0.1-SNAPSHOT.jar \
&& INTERNAL_HOST_IP=$(ip route show default | awk '/default/ {print $3}') \
&& echo "$INTERNAL_HOST_IP  host.docker.internal" >> /etc/hosts \
&& chmod +r /etc/hosts \
&& cat /etc/hosts 
ENTRYPOINT [ "java", "-jar", "-Dspring.config.location=/opt/StatisticalRestService/application.yml", "/opt/StatisticalRestService/StatisticalRestService-0.0.1-SNAPSHOT.jar" ] 

application.yml:

spring:
    application:
        name: StatisticalRestService
    jpa:
        database: POSTGRESQL
        show-sql: true
        hibernate:
            ddl-auto: create-drop
    datasource:
        platform: postgres
        #url: jdbc:postgresql://host.docker.internal:5432/StatisticalRestService
        url: jdbc:postgresql://172.17.0.1:5432/StatisticalRestService
        username: statEntityUser
        password: test123
        driverClassName: org.postgresql.Driver

I have configured postresql's setting listen_addressess = '*' and the following entry is in the pg_hba.conf:

host    all     all     172.17.0.0/16       md5
host    all     all     192.168.1.0/24      md5

ifconfig docker0:

arizon@tuxpad:~/Utveckling/StatisticalRestService$ ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
    inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
    inet6 fe80::42:3bff:fe4f:ed34  prefixlen 64  scopeid 0x20<link>
    ether 02:42:3b:4f:ed:34  txqueuelen 0  (Ethernet)
    RX packets 28  bytes 1506 (1.5 KB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 198  bytes 25515 (25.5 KB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

This is the build output:

arizon@tuxpad:~/Utveckling/StatisticalRestService$ sudo docker build . -t arizon/statisticalrestservice:1.0.0-SNAPSHOT
Sending build context to Docker daemon  223.7MB
Step 1/7 : FROM openjdk:13-ea-9-jdk-alpine3.9
---> 6a6c49978498
Step 2/7 : EXPOSE 8080
---> Running in df7ebc70e950
Removing intermediate container df7ebc70e950
---> 417e50a9f5fd
Step 3/7 : CMD mkdir /opt/StatisticalRestService
---> Running in f33ca0acddf7
Removing intermediate container f33ca0acddf7
---> 59ae394176f3
Step 4/7 : COPY target/StatisticalRestService-0.0.1-SNAPSHOT.jar /opt/StatisticalRestService/
---> 4fbcfeb039f8
Step 5/7 : COPY DockerConfig/application.yml /opt/StatisticalRestService/
---> 244d31fc4755
Step 6/7 : RUN chmod 777 /opt/StatisticalRestService/StatisticalRestService-0.0.1-SNAPSHOT.jar && ls -l /opt/StatisticalRestService/StatisticalRestService-0.0.1-SNAPSHOT.jar && INTERNAL_HOST_IP=$(ip route show default | awk '/default/ {print $3}') && echo "$INTERNAL_HOST_IP  host.docker.internal" >> /etc/hosts && chmod +r /etc/hosts && cat /etc/hosts
---> Running in 241f43aebbdc
-rwxrwxrwx    1 root     root      35266534 Mar 16 19:52 /opt/StatisticalRestService/StatisticalRestService-0.0.1-SNAPSHOT.jar
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2  241f43aebbdc
172.17.0.1  host.docker.internal
Removing intermediate container 241f43aebbdc
---> 5c6c53d8011d
Step 7/7 : ENTRYPOINT [ "java", "-jar", "-Dspring.config.location=/opt/StatisticalRestService/application.yml", "/opt/StatisticalRestService/StatisticalRestService-0.0.1-SNAPSHOT.jar" ]
---> Running in 213a87164e8f
Removing intermediate container 213a87164e8f
---> 802cd987771f
Successfully built 802cd987771f
Successfully tagged arizon/statisticalrestservice:1.0.0-SNAPSHOT

When I run this with the datasource url pointed to host.docker.internal, i get unknownHostException, despite the output from the /etc/hosts file confirming it's there. From what I understand, there might be an issue with /etc/nsswitch.conf under alpine. I've tried adding the file and pasting this line from my host:

hosts:          files mdns4_minimal [NOTFOUND=return] dns myhostname

to no avail.

When I run it with the datasource url pointed to 172.17.0.1:5432, I get connection timed out.

I verified access to psql from my host by pointing pgadmin to the 192.168 ip to verify that listen_addresses = '*' works:

host    all     all     192.168.1.0/24      md5

which it does. It's a different entry tho.

Docker version:

Client:
 Version:           18.09.2
 API version:       1.39
 Go version:        go1.10.4
 Git commit:        6247962
 Built:             Tue Feb 26 23:52:23 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.09.2
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.4
  Git commit:       6247962
  Built:            Wed Feb 13 00:24:14 2019
  OS/Arch:          linux/amd64
  Experimental:     false

Postgresql version:

arizon@tuxpad:~/Utveckling/StatisticalRestService$ dpkg --list | grep postgresql
ii  postgresql-10                                               10.6-0ubuntu0.18.04.1               amd64        object-relational SQL database, version 10 server

So, TL;DR: Two questions: 1. How do I get host.docker.internal to work on docker under linux? 2. How do I connect my containerized application to my host postgresql instance?

2
  • Sounds fact but have you tried EXPOSE 5432 in your docker file? Commented Mar 18, 2019 at 14:02
  • @daark yes, but it seems that EXPOSE is more of a documentary setting. the -p flag when running the container is what matters. I tried doing both -p 8081:8080 and -p 5432:5432, no difference. Commented Mar 18, 2019 at 14:47

1 Answer 1

1

I solved this not in the way I intended when I asked the question but It's solved.

I ended up creating a postgres container too with a volume to keep the persisted data persitent.

I made a Dockerfile for postgres that looks like this:

FROM postgres:10-alpine
RUN mkdir /docker-entrypoint-initdb.d/
#COPY initdb.sql /docker-entrypoint-initdb.d/
COPY my-postgres.conf /usr/local/share/postgresql/postgresql.conf
#ENV POSTGRES_USER statEntityUser
#ENV POSTGRES_PASSWORD test123
#ENV POSTGRES_DB StatisticalRestService
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 5432
CMD [ "postgres" ]

The initdb.sql script is just creating the same thing that the commented environment variables are, the user, password and database. Sql-scripts placed in that folder is run by the entry point script when the database is started and ready (it's an out-of-the-box feature in the docker image I derive from). The reason they are commented out is that it's in the docker-compose file (see below). The postgresql.conf is basically the template that is included in the container but with listen_addresses = '*' uncommented.

I also made a docker-compose.yml to run both of these containers in a good way together:

version: "3"
services:
  statistical-rest-service:
    build: ./StatisticalRestService
    ports: 
      - 8081:8080
    depends_on:
      - postgres
    networks:
      - statisticsNet
  postgres:
    container_name: postgres
    build: ./Postgres
    ports:
      - 5433:5432
    volumes:
      -  postgres-volume:/var/lib/postgresql/data
    command: postgres -c 'config_file=/usr/local/share/postgresql/postgresql.conf'
    networks:
      - statisticsNet
    environment:
      POSTGRES_USER: statEntityUser
      POSTGRES_PASSWORD: test123
      POSTGRES_DB: StatisticalRestService
networks:
  statisticsNet:
volumes:
  postgres-volume:

I'm not sure if you have to create the volume before hand or if it's included in docker-compose but if you need to, it's just docker volume create postgres-volume.

Postgres documentation on how to use the image and/or derive from it: Postgres on docker hub NOTE: When you start the container with an appointed volume, make some mistake and shut it down, when you start it again, it will not mess with the existing database on the volume. You might get into a position where you have "dangling volumes" that are stale versions of old run-time containers that you've killed and removed but they can produce unexpected behavior (for me, the user and database wasn't created because of this). You can clear them with this command: docker volume rm $(docker volume ls -qf dangling=true) (or run the command inside $() to list eventual dangling volumes.

Since I am creating a dedicated docker network in the docker-compose file, the containers can find each other by name (note container_name). That makes the connection url in the application.yml for my java like this: url: jdbc:postgresql://postgres:5432/StatisticalRestService

I hope someone is helped by this :)

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.