繁体   English   中英

从Docker容器访问主机postgresql(Linux上的Docker)

[英]Accessing host postgresql from docker container (docker on linux)

我的Linux主机上的docker容器中运行着一个spring-boot java应用程序。 我要从正在运行的容器连接到主机上安装了一个postgresql实例。

我尝试了多种不同的方法(--network =“ host”不是我想要的)。

我的Dockerfile看起来像这样:

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

我已经配置了postresql的设置listen_addressess ='*',以下条目位于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

这是构建输出:

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

当我使用指向host.docker.internal的数据源URL来运行它时,尽管/ etc / hosts文件的输出确认它在那里,但我还是遇到了UnknownHostException。 据我了解,alpine下/etc/nsswitch.conf可能存在问题。 我尝试添加文件并从主机粘贴以下行:

hosts:          files mdns4_minimal [NOTFOUND=return] dns myhostname

无济于事。

当我使用指向172.17.0.1:5432的数据源URL运行它时,连接超时。

我通过将pgadmin指向192.168 ip来验证从主机对psql的访问,以验证listen_addresses ='*'是否有效:

host    all     all     192.168.1.0/24      md5

它做的。 这是一个不同的入口。

Docker版本:

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版本:

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

因此,TL; DR:两个问题:1.如何使host.docker.internal在Linux下的docker上工作? 2.如何将容器化的应用程序连接到主机postgresql实例?

我不是以提出问题时的预期方式解决此问题的,但问题已解决。

我最终也创建了一个postgres容器,该容器具有一定的容量以保持持久的数据持久性。

我为postgres创建了一个Dockerfile,如下所示:

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" ]

initdb.sql脚本仅创建与注释的环境变量相同的东西,即用户,密码和数据库。 当数据库启动并准备就绪时,放置在该文件夹中的sql脚本由入口点脚本运行(这是我衍生自的docker映像中的开箱即用功能)。 他们被注释掉的原因是它在docker-compose文件中(请参阅下文)。 postgresql.conf基本上是包含在容器中的模板,但未注释listen_addresses ='*'。

我还制作了一个docker-compose.yml以很好的方式一起运行这两个容器:

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:

我不确定您是否必须先创建卷或是否将其包含在docker-compose中,但如果需要,仅是docker volume create postgres-volume

有关如何使用映像和/或从映像派生的Postgres文档: docker hub上的Postgres 注意:当您使用指定的卷启动容器时,犯一些错误并关闭它,当再次启动它时,它不会弄乱卷上的现有数据库。 您可能会陷入一个“悬而未决的卷”的位置,这些卷是您已杀死并删除的旧运行时容器的陈旧版本,但它们可能产生意外行为(对我而言,由于以下原因未创建用户和数据库)这个)。 您可以使用以下命令清除它们: docker volume rm $(docker volume ls -qf dangling=true) (或在$()中运行命令以列出最终的悬挂卷。

由于我在docker-compose文件中创建了专用的docker网络,因此容器可以按名称(请注意container_name)找到彼此。 这使得我的java的application.yml中的连接URL如下所示: url: jdbc:postgresql://postgres:5432/StatisticalRestService

我希望有人对此有所帮助:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM