Docker:服务器是不是在主机“localhost”(::1) 上运行并接受端口 5432 上的 TCP/IP 连接?

Posted

技术标签:

【中文标题】Docker:服务器是不是在主机“localhost”(::1) 上运行并接受端口 5432 上的 TCP/IP 连接?【英文标题】:Docker: Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432?Docker:服务器是否在主机“localhost”(::1) 上运行并接受端口 5432 上的 TCP/IP 连接? 【发布时间】:2018-01-20 02:09:18 【问题描述】:

我在使用 Ruby on Rail 在本地系统上设置和运行 docker 实例时遇到问题。请查看我的 docker 配置文件:-

Dockerfile

FROM ruby:2.3.1

RUN useradd -ms /bin/bash web
RUN apt-get update -qq && apt-get install -y build-essential
RUN apt-get -y install nginx
RUN apt-get -y install sudo
# for postgres
RUN apt-get install -y libpq-dev

# for nokogiri
RUN apt-get install -y libxml2-dev libxslt1-dev

# for a JS runtime
RUN apt-get install -y nodejs
RUN apt-get update

# For docker cache
WORKDIR /tmp 
ADD ./Gemfile Gemfile
ADD ./Gemfile.lock Gemfile.lock
ENV BUNDLE_PATH /bundle
RUN gem install bundler --no-rdoc --no-ri
RUN bundle install
# END
ENV APP_HOME /home/web/cluetap_app
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME
ADD . $APP_HOME
RUN chown -R web:web $APP_HOME
ADD ./nginx/nginx.conf /etc/nginx/
RUN unlink /etc/nginx/sites-enabled/default
ADD ./nginx/cluetap_nginx.conf /etc/nginx/sites-available/
RUN ln -s /etc/nginx/sites-available/cluetap_nginx.conf /etc/nginx/sites-enabled/cluetap_nginx.conf
RUN usermod -a -G sudo web

docker-compose.yml

version: '2'
services:
  postgres:
    image: 'postgres:9.6'
    environment:
      - PGDATA=/var/lib/postgresql/data/pgdata
      - POSTGRES_PASSWORD=
      - POSTGRES_USER=postgres
      - POSTGRES_HOST=cluetapapi_postgres_1
    networks:
      - default
      - service-proxy
    ports:
      - '5432:5432'
    volumes:
      - 'postgres:/var/lib/postgresql/data'
    labels:
      description: "Postgresql Database"
      service: "postgresql"
  web:
    container_name: cluetap_api
    build: .
    command: bash -c "thin start -C config/thin/development.yml && nginx -g 'daemon off;'"
    volumes:
      - .:/home/web/cluetap_app
    ports:
      - "80:80"
    depends_on:
      - 'postgres'
networks:
  service-proxy:
volumes:
  postgres:

当我运行 docker-compose builddocker-compose up -d 这两个命令时,它运行成功,但是当我从 url 中点击它时 docker-compose up -d strong>内部服务器错误,错误是

Unexpected error while processing request: could not connect to server: Connection refused
    Is the server running on host "localhost" (127.0.0.1) and accepting
    TCP/IP connections on port 5432?
could not connect to server: Cannot assign requested address
    Is the server running on host "localhost" (::1) and accepting
    TCP/IP connections on port 5432?

我已经应用了一些解决方案,但它对我不起作用,请指导我,我是 docker 和 AWS 的新手。

【问题讨论】:

docker logs 线索tap_api 的输出是什么?我建议给你的 postgres 一个容器名称,例如:my-postgres。您可以使用 my-postgres:5432 从您的 api-container 内部连接到您的 postgres,因为它们部署在同一个网络中。您甚至不需要映射端口。 如果你想映射你的端口,你可以使用 server-ip:5432 从你的 api-container 连接。比你的容器不需要在同一个网络中。 【参考方案1】:

问题是您正在尝试连接到 DB 容器内的 localhost。您为 postgres 执行的端口映射 5432:5432 将 5432 映射到主机的 localhost。

现在您的web 容器代码正在容器内运行。而且它的 localhost:5432 上什么也没有。

因此,您需要在配置中更改连接详细信息以连接到 postgres:5432,这是因为您将 postgres DB 服务命名为 postgres

改变它,它应该可以工作。

【讨论】:

我已经成功连接到数据库,但是我不知道为什么我运行docker-compose build时没有创建数据库而不是它给出错误Unexpected error while processing request: FATAL: database "cluetap_development" does not exist Postgres 图像将根据您在环境变量中指定的名称初始化一个新数据库。 POSTGRES_DB。在你的 docker-compose 中将此环境变量设置为线索tap_development,它应该有数据库 嗨,朋友,我已经将数据库名称添加到 yml 文件 db: image: postgres environment: POSTGRES_PASSWORD: POSTGRES_USER: postgres POSTGRES_DATABASE: cluetap_development @RavindraYadav,使用您正在使用的最新 docker-compose.yml 更新您的问题。因为我在那里看不到变量。还将日志粘贴到您的问题中,显示错误详细信息 我已经解决了这个问题。谢谢你的帮助。现在只有一个问题是当我将应用程序的端口从“80:80”更改为“3000:3000”时,它没有运行并且没有抛出任何错误【参考方案2】:

默认情况下,postgres 图像已经暴露给 5432,因此您可以在 yml 中删除该部分。

如果你想检查 web 服务是否可以连接到你的 postgres 服务,你可以运行这个docker-compose exec web curl postgres:5432 然后它应该返回:

curl: (52) 来自服务器的空回复

如果无法连接会返回:

curl: (6) 无法解析主机:postgrescurl: (7) 无法连接到 postgres 端口 5432:连接被拒绝

更新:

我现在知道问题所在了。这是因为您尝试在 localhost 上连接,您应该连接到 postgres 服务。

【讨论】:

我已经从 yml 文件中删除了端口部分,然后运行 ​​docker 命令,但它仍然有同样的问题,运行此docker-compose exec web curl postgres:5432 后它返回 curl: (52) Empty reply from server 那么我应该怎么做才能解决这个问题。 我已经成功连接到数据库但是我不知道为什么我运行docker-compose build时没有创建数据库而不是它给出错误Unexpected error while processing request: FATAL: database "cluetap_development" does not exist POSTGRES_DB=cluetap_development 在你的 postgres 服务环境中添加这个 嗨,朋友,我已经将数据库名称添加到 yml 文件 db: image: postgres environment: POSTGRES_PASSWORD: POSTGRES_USER: postgres POSTGRES_DATABASE: cluetap_development 我正在使用 Figaro gem 获取特定于环境的数据。【参考方案3】:

我刚才也有这个问题。我的解决方案是

    在 Postgres 服务中删除端口 port: '5432:5432'POSTGRES_HOST=cluetapapi_postgres_1 更改为POSTGRES_HOST=localhost

当您需要访问您的数据库时,只需使用示例 sqlalchemy.url = postgresql+psycopg2://postgres:password@postgres/dbname

【讨论】:

【参考方案4】:

我在 Ubuntu 20.04 中使用 DockerTraefik 处理 Rails 6 应用程序时遇到了同样的问题.

在我的例子中,我试图将在 docker 容器中运行的 Ruby on Rails 应用程序连接到在主机上运行的 PostgreSQL 数据库。

所以每次我尝试连接到数据库时都会收到错误:

Unexpected error while processing request: could not connect to server: Connection refused
    Is the server running on host "localhost" (127.0.0.1) and accepting
    TCP/IP connections on port 5432?
could not connect to server: Cannot assign requested address
    Is the server running on host "localhost" (::1) and accepting
    TCP/IP connections on port 5432?

这是我修复它的方法

首先,容器中运行的应用程序通过 Traefik 暴露给主机,Traefik 映射到端口 80 上的主机。

首先,我必须修改我的 PostgreSQL 数据库配置文件以接受来自其他 IP 地址的远程连接。这个 *** 答案可以帮助解决这个问题 - PostgreSQL: FATAL - Peer authentication failed for user (PG::ConnectionBad)

其次,我必须创建一个 docker 网络,Traefik 和其他将通过它代理的应用程序将使用该网络:

docker network create traefik_default

第三,我在docker-compose.yml 文件中设置应用程序以使用我刚刚创建的同一网络:

version: "3"

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    env_file:
      - .env
    environment:
      RAILS_ENV: $RAILS_ENV
      RACK_ENV: $RACK_ENV
      POSTGRES_USER: $DATABASE_USER
      POSTGRES_PASSWORD: $DATABASE_PASSWORD
      POSTGRES_DB: $DATABASE_NAME
      POSTGRES_HOST_AUTH_METHOD: $DATABASE_HOST
      POSTGRES_PORT: $DATABASE_PORT
    expose:
      - $RAILS_PORT
    networks:
      - traefik_default
    labels:
      - traefik.enable=true
      - traefik.http.routers.my_app.rule=Host(`$RAILS_HOST`)
      - traefik.http.services.my_app.loadbalancer.server.port=$NGINX_PORT
      - traefik.docker.network=traefik_default
    restart: always
    volumes:
      - .:/app
      - gem-cache:/usr/local/bundle/gems
      - node-modules:/app/node_modules
  web-server:
    build:
      context: .
      dockerfile: ./nginx/Dockerfile
    depends_on:
    - app
    expose:
      - $NGINX_PORT
    restart: always
    volumes:
      - .:/app
networks:
  traefik_default:
    external: true
volumes:
  gem-cache:
  node-modules:

最后,在我的.env 文件中,我将主机的私有IP 地址 指定为DATABASE_HOST 作为环境变量:

DATABASE_NAME=my_app_development
DATABASE_USER=my-username
DATABASE_PASSWORD=passsword1
DATABASE_HOST=192.168.0.156
DATABASE_PORT=5432

RAILS_HOST=my_app.localhost
NGINX_PORT=80

RAILS_ENV=development
RACK_ENV=development
RAILS_MASTER_KEY=e879cbg21ff58a9c50933fe775a74d00
RAILS_PORT=3000

就是这样。

我希望这会有所帮助

【讨论】:

以上是关于Docker:服务器是不是在主机“localhost”(::1) 上运行并接受端口 5432 上的 TCP/IP 连接?的主要内容,如果未能解决你的问题,请参考以下文章

无法连接到 Docker 守护程序。 docker 守护进程是不是在此主机上运行?

Mac OS X sudo docker 无法连接到 Docker 守护程序。 docker 守护进程是不是在此主机上运行?

本地主机不记录更改?

Docker 构建失败 - 带有 GKE 的 Gitlab CI。无法通过 tcp://localhost:2375 连接到 Docker 守护程序。 docker 守护进程是不是正在运行?

【swarm】Docker跨主机网络:overlay

Consul+Registrator+Docker实现服务发现(nginx反向代理)