当前位置: 首页 > 知识库问答 >
问题:

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

桑宇
2023-03-14

在使用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 build和docker compose up-d这两个命令时,它会成功运行,但当我从url中点击时,它会出现内部服务器错误,错误是

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的新手。

共有3个答案

鱼征
2023-03-14

在Ubuntu20.04中使用Docker和Traefik开发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地址的远程连接。此StackOverflow答案有助于-PostgreSQL:FATAL-用户的对等身份验证失败(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地址指定为数据库\u主机作为环境变量,如下所示:

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

仅此而已。

我希望这有帮助。

叶冥夜
2023-03-14

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

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

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

如果无法连接,它将返回:

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

更新:

我现在知道问题了。这是因为您试图在本地主机上连接,所以您应该连接到postgres服务。

陈誉
2023-03-14

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

现在,您的web容器代码正在容器内运行。而且它的本地主机5432上没有任何内容。

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

改变这一点,它应该会起作用。

 类似资料: