Docker: Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432?
Asked Answered
M

4

42

I am getting issues while setup and run the docker instance on my local system with Ruby on Rail. Please see my docker configuration files:-

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:

When I have run docker-compose build and docker-compose up -d these two commands it run succesfully but when I have hit from the url the it thorught internal server error and the error is

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?

I have applied some solution but it did not work for me, please guide me I am new to docker and AWS.

Magnify answered 11/8, 2017 at 14:6 Comment(2)
what is the output of docker logs cluetap_api ? I would recommend to give your postgres a containername like: my-postgres. You can connect from inside your api-container to your postgres by using my-postgres:5432 because they are deployed in the same network. You don't even need to map the port.Fraya
If you want to map your port than you can connect from your api-container by using server-ip:5432. Than your containers don't need to be inside the same network.Fraya
E
65

The issue is that you are trying to connect to localhost inside the container for DB. The port mapping that you do 5432:5432 for postgres map 5432 to localhost of your host machine.

Now your web container code is running inside the container. And there is nothing on its localhost:5432.

So you need to change your connection details in the config to connect to postgres:5432 and this is because you named the postgres DB service as postgres

Change that and it should work.

Eunaeunice answered 11/8, 2017 at 15:8 Comment(9)
I have connected to database successfully but I don't know why the database not created when I have run docker-compose build not its giving error Unexpected error while processing request: FATAL: database "cluetap_development" does not existMagnify
Postgres image will initialize a new DB based on the name you specify in environment variable. POSTGRES_DB. Set this environment variable as cluetap_development in your docker-compose and it should have the DBEunaeunice
Hi amigo I have already added database name into yml file db: image: postgres environment: POSTGRES_PASSWORD: POSTGRES_USER: postgres POSTGRES_DATABASE: cluetap_developmentMagnify
@RavindraYadav, update your question with the latest docker-compose.yml you are using. Because I don't see the variable there. Also paste the logs in your question which shows the error detailsEunaeunice
I have resolved the issue. Thanks for your help. Now only one issue coming is when I have changed the port for app from "80:80" to "3000:3000" its not running and its not throwing any errorMagnify
below is my docker-compose.yml file version: '2' services: db: image: postgres environment: POSTGRES_PASSWORD: POSTGRES_USER: postgres POSTGRES_DB: cluetap_development 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" links: - db depends_on: - dbMagnify
@RavindraYadav, that is because nginx is listening on 80 and not 3000. You shoudl change it as "3000:80"Eunaeunice
@Tarun Lalwanih when you say "change your connection details in the config" could you say what detail you are referring to ? should the port look like this? ports: - 'postgres:5432'Elconin
@user3738936, The nginx config needs to use the port of the container and not the the one that is mapped outside to the host. So whether your use the port mapping 3000:80 or 5000:80 the nginx will always use port 80 as it is concerned about the container portEunaeunice
P
6

By default the postgres image is already exposing to 5432 so you can just remove that part in your yml.

Then if you would like to check if web service can connect to your postgres service you can run this docker-compose exec web curl postgres:5432 then it should return:

curl: (52) Empty reply from server

If it cannot connect it will return:

curl: (6) Could not resolve host: postgres or curl: (7) Failed to connect to postgres port 5432: Connection refused

UPDATE:

I know the problem now. It's because you are trying to connect on the localhost you should connect to the postgres service.

Phototype answered 12/8, 2017 at 3:58 Comment(6)
I have removed the port section from yml file and then run the docker command but it still have same issue and after run this docker-compose exec web curl postgres:5432 it returns curl: (52) Empty reply from server so what should I do to resolve the issue.Magnify
I have connected to database successfully but I don't know why the database not created when I have run docker-compose build not its giving error Unexpected error while processing request: FATAL: database "cluetap_development" does not existMagnify
POSTGRES_DB=cluetap_development add this in your postgres service environmentPhototype
Hi amigo I have already added database name into yml file db: image: postgres environment: POSTGRES_PASSWORD: POSTGRES_USER: postgres POSTGRES_DATABASE: cluetap_developmentMagnify
I am using Figaro gem for the environment specific data.Magnify
I'm not really sure what you meant but putting POSTGRES_DATABASE: cluetap_development on the environments will create a database on the postgres containerPhototype
E
2

I had this same issue when working on a Rails 6 application in Ubuntu 20.04 using Docker and Traefik.

In my case I was trying to connect the Ruby on Rails application running in a docker container to the PostgreSQL database running on the host.

So each time I try to connect to the database I get the error:

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?

Here's how I fixed it:

So first the applications running in the container are exposed to the host via Traefik which maps to the host on port 80.

Firstly, I had to modify my PostgreSQL database configuration file to accept remote connections from other IP addresses. This Stack Overflow answer can help with that - PostgreSQL: FATAL - Peer authentication failed for user (PG::ConnectionBad)

Secondly, I had to create a docker network that Traefik and other applications that will proxy through it will use:

docker network create traefik_default

Thirdly, I setup the applications in the docker-compose.yml file to use the same network that I just created:

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:

Finally, in my .env file, I specified the private IP address of my host machine as the DATABASE_HOST as an environment variable this way:

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
Emphatic answered 14/10, 2020 at 10:19 Comment(0)
L
-1

I also had this problem just now. My solution is

  1. Remove port port: '5432:5432' in Postgres service
  2. Change POSTGRES_HOST=cluetapapi_postgres_1 to POSTGRES_HOST=localhost

When you need to access your db, just use like example sqlalchemy.url = postgresql+psycopg2://postgres:password@postgres/dbname

Laborsaving answered 9/2, 2020 at 11:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.