在Docker容器中将Superset连接到PostgreSQL - 端口已关闭。

5
我的操作系统是Linux。 我打算将Superset连接到PostgreSQL。 PostgreSQL端口是开放的,其值为5432。 PostgreSQL也在运行且未关闭。 不幸的是,在经过一天的互联网研究后,我无法解决这个问题,它给出了以下错误:
The port is closed.

enter image description here

数据库端口:
在此输入图像描述


命令:lsof -i TCP:5432
python3 13127 user   13u  IPv4 279806      0t0  TCP localhost:40166->localhost:postgresql (ESTABLISHED)
python3 13127 user   14u  IPv4 274261      0t0  TCP localhost:38814->localhost:postgresql (ESTABLISHED)

请帮帮我,我是个初学者,但是我搜索了很多次也没有找到任何结果。
解决方案
使用host.docker.internal代替127.0.0.1localhost。(感谢pdxrlk)

要让Docker容器访问主机,你可以使用hostname host.docker.internal。 - pdxrlk
@Sardar,我按照你的建议操作了,但仍然显示“端口关闭”。还有其他方法可以进行故障排除吗? - undefined
@ff8mania 检查操作系统防火墙 - undefined
我是一个Linux的新手。我使用的是Ubuntu 22.04。我应该如何检查防火墙是否是问题所在? - undefined
@Sardar,执行ufw status命令后,我发现它是未激活状态。 - undefined
显示剩余5条评论
7个回答

18

由于您正在docker容器中运行Superset,因此无法使用127.0.0.1或localhost,因为它们解析为容器而不是主机。对于主机,请使用host.docker.internal。


host.docker.internal在Ubuntu 22上无法使用。 - dbaltor
@dbaltor 我正在使用Ubuntu 22,它运行正常。 - Sardar
谢谢,@Sardar。很抱歉,在我的笔记本上情况并非如此。我正在使用Ubuntu Budgie 22.04。可能是由于我使用的Docker版本不同。我是通过snap进行安装的:sudo snap install docker - dbaltor

2

我曾经在使用docker compose时遇到过类似的问题。端口关闭可能是由于网络问题引起的。在Ubuntu 22上,Host.docker.internal对我不起作用。我建议不要按照官方文档的方式操作,而是使用单个docker镜像来启动。不要通过compose运行5个容器,而是将所有内容都运行在一个容器中。使用官方docker镜像,在这里image。然后按照以下方式修改docker文件以安装自定义数据库驱动程序:

FROM apache/superset
USER root
RUN pip install mysqlclient
RUN pip install sqlalchemy-redshift
USER superset 

第二步是根据Docker文件描述构建新的镜像。为了避免网络问题,请将两个容器都放在同一个网络上(superset,您的数据库),更容易使用主机网络。我在Google云示例中使用了以下方法:

第二步是基于Docker文件描述构建新的镜像。为避免网络问题,请将两个容器放在同一网络中(即superset和您的数据库),最简单的方法是使用主机网络。我在Google Cloud的示例中采用了以下方法:

docker run -d --network host --name superset supers

使用相同的命令启动带有数据库的容器。 —network host。这解决了我的问题。更多详细步骤教程请参考: medium 或者 blog


1
我在使用Docker来运行Superset和MySQL,所以host.docker.internal对我来说比127.0.0.1或localhost更有效。

0
从配置文件中,您设置了端口5432,但这并不意味着您的pg服务可用。

什么是解决方案? - Sardar
首先,您可以使用 lsof -i:8848 命令来检查 pg 端口占用情况,然后判断服务是否可用。如果不可用,请在启动 pg 服务时粘贴下面的启动日志。 - black white
感谢 @black white。为什么使用8848端口?我输入了这个命令(lsof -i TCP:5432),输出是 -> localhost:40166->localhost:postgresql (已建立连接)。 - Sardar
它在8848端口上没有显示任何内容,但我不知道这个端口是用来做什么的。 - Sardar
抱歉,这是我的情况,您只需要使用5432替换8848即可。 - black white
显示剩余2条评论

0
在Ubuntu 22.04上,您可以使用ifconfig来获取主机的IP地址-例如172.18.0.1,并使用该地址。然而,请务必关闭ufw并查看是否解决了问题。我最近启用了它,并没有注意到这一点,直到我想起来。

0
我可能会迟到,但还是回答这个问题。当我连接我的本地运行的Postgres到在docker上运行的superset时,我也遇到了同样的问题。然后我在本地系统上启动了一个运行在5000端口的Postgres容器,然后在superset中使用了该端口和主机名hub.docker.internal,然后它完美地工作了,我可以从superset容器中访问在我的本地系统上运行的Postgres容器,但仍然无法弄清楚为什么无法访问5432端口。

0
答案接受(host.docker.internal)在我使用Ubuntu 22.04和通过sudo snap install docker安装的docker中没有起作用。我通过将我的数据库容器映像(在我的情况下是MySQL)添加到Superset的docker-compose-non-dev.yml文件中解决了这个问题。这样,Superset就可以连接到我的数据库容器。
以下是整个组合文件。我添加的片段位于#=======之间。
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
x-superset-image: &superset-image apachesuperset.docker.scarf.sh/apache/superset:${TAG:-latest-dev}
x-superset-depends-on: &superset-depends-on
  - db
  - redis
#=======
  - billing_db  
#=======
x-superset-volumes: &superset-volumes
  # /app/pythonpath_docker will be appended to the PYTHONPATH in the final container
  - ./docker:/app/docker
  - superset_home:/app/superset_home

version: "3.7"
services:
  redis:
    image: redis:7
    container_name: superset_cache
    restart: unless-stopped
    volumes:
      - redis:/data

#=======  
  billing_db:
    image: billing_dbap:latest
    container_name: billing_dbap
    restart: unless-stopped
    volumes:
      - billing_db_home:/var/lib/mysql
#=======

  db:
    env_file: docker/.env-non-dev
    image: postgres:14
    container_name: superset_db
    restart: unless-stopped
    volumes:
      - db_home:/var/lib/postgresql/data

  superset:
    env_file: docker/.env-non-dev
    image: *superset-image
    container_name: superset_app
    command: ["/app/docker/docker-bootstrap.sh", "app-gunicorn"]
    user: "root"
    restart: unless-stopped
    ports:
      - 8088:8088
    depends_on: *superset-depends-on
    volumes: *superset-volumes

  superset-init:
    image: *superset-image
    container_name: superset_init
    command: ["/app/docker/docker-init.sh"]
    env_file: docker/.env-non-dev
    depends_on: *superset-depends-on
    user: "root"
    volumes: *superset-volumes
    healthcheck:
      disable: true

  superset-worker:
    image: *superset-image
    container_name: superset_worker
    command: ["/app/docker/docker-bootstrap.sh", "worker"]
    env_file: docker/.env-non-dev
    restart: unless-stopped
    depends_on: *superset-depends-on
    user: "root"
    volumes: *superset-volumes
    healthcheck:
      test: ["CMD-SHELL", "celery -A superset.tasks.celery_app:app inspect ping -d celery@$$HOSTNAME"]

  superset-worker-beat:
    image: *superset-image
    container_name: superset_worker_beat
    command: ["/app/docker/docker-bootstrap.sh", "beat"]
    env_file: docker/.env-non-dev
    restart: unless-stopped
    depends_on: *superset-depends-on
    user: "root"
    volumes: *superset-volumes
    healthcheck:
      disable: true

volumes:
  superset_home:
    external: false
  db_home:
    external: false
  redis:
    external: false
#=======
  billing_db_home:
    external: false
#=======

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接