如何从外部/应用访问容器化的Postgresql数据库

时间:2020-10-11 12:44:31

标签: postgresql docker docker-compose

我一直在努力从本地主机和外部连接到Postgresql容器。

这是一个非常不错的演示,效果很好,如https://linuxhint.com/postgresql_docker/所示。下面是docker-compose.yml,通过它可以将postgres:12.2和pgadmin容器化并运行。而且确实在运行docker-compose.yml文件(通过docker-compose up -d)后,它们可以工作。

然后,您可以在浏览器中进入http:// localhost:8080 /,并可以直接访问pgadmin(具有给定的凭据,即admin@linuxhint.com,机密),然后开始在postgres:12.2安装上进行操作在docker上。

但是,当我尝试直接从本地主机或外部/某些应用程序/ ip(例如Java Spring Boot)找到与该postgres:12.2 -database的连接时,我的困难就开始了。

诚然,我不是docker方面的专家,而只是一名学生-因此,我寻求帮助。希望有人可以告诉我应该怎么做才能使来自外部/应用程序的(此)容器化postgres数据库成为可能。我正在使用Win 10。

更新:

  • 任何人都可以说为什么一个Web应用程序(在docker.compose.yml中添加到下面,请参见下文)在启动后会持续关闭吗?

  • docker日志给出以下错误:

    由以下原因引起:org.springframework.beans.factory.BeanCreationException:在类路径资源[org / springframework / boot / autoconfigure / jdbc / DataSourceConfiguration $ Hikari.class]中创建名称为“ dataSource”的bean时出错。失败嵌套的异常是org.springframework.beans.factory.BeanCreationException:创建名称为org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker的bean时出错:调用init方法失败;嵌套的异常是org.springframework.jdbc.datasource.init.UncategorizedScriptException:无法执行数据库脚本;嵌套的异常是org.springframework.jdbc.CannotGetJdbcConnectionException:无法获取JDBC连接。嵌套的异常是org.postgresql.util.PSQLException:到本地主机的连接:5433被拒绝。检查主机名和端口是否正确以及邮局主管正在接受TCP / IP连接。

  • 这是该应用程序的 Dockerfile

    FROM maven:3-jdk-11

    VOLUME / tmp

    博览会8095

    ADD /target/spring-boot-demo-0.0.1-SNAPSHOT.jar app.jar

    运行ls -ls

    ENTRYPOINT [“ java”,“-Djava.security.egd = file:/ dev /./ urandom”,“-jar”,“ / app.jar”]

  • ,这是 application.properties 文件中的连接详细信息:

    spring.datasource.url = jdbc:postgresql:// db:5432 / postgres

    spring.datasource.username = admin

    spring.datasource.password =秘密

  • 另外两个服务(db和pgadmin正常启动)

docker-compose.yml

version: "3.7"

services:

# ========== ADDED APP ===============
 web:
   #restart: on-failure
   image: app-springboot-postgresql
   build: ./
   ports:
     - "8095:8095"
   environment:
     WAIT_HOSTS: postgres:5432
   depends_on:
    - db  
# ========== ADDED APP ===============

  db:
    image: postgres:12.2
    restart: always
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: secret
      PGDATA: /var/lib/postgresql/data
    volumes:
      - db-data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
 
  pgadmin:
    image: dpage/pgadmin4:4.18
    restart: always
    environment:
      PGADMIN_DEFAULT_EMAIL: admin@linuxhint.com
      PGADMIN_DEFAULT_PASSWORD: secret
      PGADMIN_LISTEN_PORT: 80
    ports:
      - "8080:80"
    volumes:
      - pgadmin-data:/var/lib/pgadmin
    links:
      - "db:pgsql-server"

volumes:
  db-data:
  pgadmin-data:

2 个答案:

答案 0 :(得分:1)

docker-compose.yml将Postgres的端口5432发布到运行docker daemon的计算机上。

因此,假设应用程序在计算机上运行,​​则它们应作为Postgres主机连接到127.0.0.1,并作为Postgres端口连接到5432

答案 1 :(得分:0)

检查它们是否在同一网络中

docker network ls

# Output

NETWORK ID          NAME                DRIVER              SCOPE
e094bb99be32        bridge              bridge              local
cde9fb0d3fef        django              bridge              local
1aeb83753889        host                host                local
f152a346ca96        none                null                local
348c59c37462        web                 bridge              local

然后检查网络:

docker network inspect django

# Output

[
    {
        "Name": "django",
        "Id": "6f5fd395946d1bff8583a4ddbe4fb8ea1204875124679f878d24a57f3601b0e6",
        "Created": "2020-10-11T13:16:42.750571609+02:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.20.0.0/16",
                    "Gateway": "172.20.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "079d303b3c2d17196e7cb49056ec7cfc7385c480c3cbf225dc51e53ebeb43f10": {
                "Name": "pgadmin",
                "EndpointID": "10e1f181f18e751ce0b3521f537e30948433e62b454fb9707b96333395f5ba36",
                "MacAddress": "02:42:ac:14:00:04",
                "IPv4Address": "172.20.0.4/16",
                "IPv6Address": ""
            },
            "bff75ff8e23ab998cfc99bc87bec05ea9fb55adbcae1993da1cbc719eea90fd3": {
                "Name": "postgres",
                "EndpointID": "edd547148b50c6c3319f2b65ec151816e14f9ea9e7dd9acb9b5895d44fcd6cda",
                "MacAddress": "02:42:ac:14:00:02",
                "IPv4Address": "172.20.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

在上面的示例中,postgres和pgadmin位于同一网络中,因此他们可以互相看到。

如果在这种情况下,它们不在同一网络中,则应进行明确定义。

# docker-compose.yml

services:
  django:
    container_name: dj
    build:
      context: ./server
    restart: unless-stopped
    volumes:
      - staticfiles:/app/staticfiles
      - mediafiles:/app/media
    command: gunicorn nohchi_mott.wsgi:application --bind 0.0.0.0:8000
    env_file: ./server/.env
    expose:
      - 8000
    networks:
      - web
      - django
    depends_on:
      - db
  db:
    container_name: postgres
    image: postgres:12.0-alpine
    restart: unless-stopped
    labels:
      - "traefik.enable=false"
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    expose:
      - 5432
    networks:
      - django
    env_file: ./db/.env
  pgadmin:
    container_name: pgadmin
    image: dpage/pgadmin4:latest
    restart: unless-stopped
    volumes:
      - pgadmin_data:/var/lib/pgadmin
    env_file: ./db/pgadmin/.env
    links:
      - db:pgsql-server
    networks:
      - web
      - django
    depends_on:
      - db

volumes:
  staticfiles:
  mediafiles:
  postgres_data:
  pgadmin_data:

networks:
  web:
    external: true
  django:
    external: false