Cannot establish connection between Rails and Postgres Docker containers - ruby-on-rails

I am new to Docker and try to dockerize a Rails container and a Postgres container with docker-compose and both build and start but when I try to go to localhost:3009 to see the "Yay, you're on Rails" page, I get this error in the Rails logs:
Started GET "/" for 172.27.0.1 at 2020-10-05 12:40:18 +0000
backend_1 | Cannot render console from 172.27.0.1! Allowed networks: 127.0.0.0/127.255.255.255, ::1
backend_1 |
backend_1 | PG::ConnectionBad (could not connect to server: Connection refused
backend_1 | Is the server running on host "postgres" (172.27.0.2) and accepting
backend_1 | TCP/IP connections on port 5439?
backend_1 | ):
This is my docker-compose.yml:
version: '3'
volumes:
db_data:
driver: local
app_data:
driver: local
services:
# database container
postgres:
image: postgres
volumes:
- app_data:/var/lib/postgresql/data
ports:
- 5439:5432
environment:
POSTGRES_DB: db_name
POSTGRES_USER: user
POSTGRES_PASSWORD: xxxxxx
command: ["postgres", "-c", "log_statement=all"]
restart: always
app:
build: ./server
volumes:
- ./server:/code
ports:
- "3009:3000"
depends_on:
- postgres
environment:
RAILS_ENV: development
DATABASE_HOST: postgres
DATABASE_PORT: 5439
DATABASE_NAME: db_name
DATABASE_USERNAME: user
DATABASE_PASSWORD: xxxxxx
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
And this is the Dockerfile:
FROM ruby:2.7.1
WORKDIR /app
COPY . /app
# Install NodeJS and Yarn.
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update && apt-get install -y yarn
RUN yarn install --check-files
RUN bundle install
CMD ["rails", "server", "-b", "0.0.0.0"]
This is my database.yml
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
host: <%= ENV['DATABASE_HOST'] %>
port: <%= ENV['DATABASE_PORT'] %>
database: <%= ENV['DATABASE_NAME'] %>
username: <%= ENV['DATABASE_USERNAME'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
development:
<<: *default
test:
<<: *default
I can access the pg database in DBeaver with 172.27.0.1:5439, but not with 172.27.0.2:5439 and I have no clue why the Rails container tries to connect on that address.

As David Maze pointed out:
You need to set DATABASE_PORT to the ordinary PostgreSQL port 5432; ports: are ignored (and unnecessary) for inter-container communications.

Related

db issues when dockerizing Ruby on Rails application

I'm trying to dockerize an existing rails application. But it's running into an error when trying to invoke rake db:create.
Here is the error:
could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
Couldn't create database for {"adapter"=>"postgresql", "encoding"=>"unicode", "pool"=>5,
"database"=>"app_development", "username"=>"postgres", "password"=>"postgres"}
rake aborted!
PG::ConnectionBad: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
Here is my Dockerfile
FROM ruby:2.7.2
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app
# COPY entrypoint.sh /usr/bin/
# RUN chmod +x /usr/bin/entrypoint.sh
# ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
docker-compose.yml
version: "3.9"
services:
db:
image: postgres
volumes:
- db_data:/var/lib/postgresql/data
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: app_development
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
volumes:
db_data:
database.yml
...
development:
<<: *default
database: app_development
# url: postgres://...
username: postgres
password: postgres
What am I doing wrong? I've tried everything online and still no luck. Any catches? Thanks in advance.
I think you will need to communicate over TCP/IP rather than a socket, so you should be able to sort this using the host setting in your database.yml file
...
development:
<<: *default
username: postgres
database: postgres
host: 127.0.0.1

Docker compose with Rails and Postgres could not connect to server: No route to host Is the server

I'm currently having an issue with my docker-compose that have these services.
Rails app and Postgres. These are my configurations:
docker-compose.yml
version: '3'
services:
db:
image: postgres:alpine
restart: always
volumes:
- ./tmp/db:/var/lib/postgresql/data
ports:
- "5432:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
app:
build: .
restart: always
command: bash -c "rm -f tmp/pids/server.pid && rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp
- bundle_path:/bundle
ports:
- "3000:3000"
depends_on:
- db
volumes:
bundle_path:
Dockerfile
FROM ruby:2.5.3-slim
# install rails dependencies
RUN apt-get update -qq \
&& apt-get install -y \
# Needed for certain gems
build-essential \
# Needed for postgres gem
libpq-dev \
# Others
nodejs \
vim-tiny \
# The following are used to trim down the size of the image by removing unneeded data
&& apt-get clean autoclean \
&& apt-get autoremove -y \
&& rm -rf \
/var/lib/apt \
/var/lib/dpkg \
/var/lib/cache \
/var/lib/log
# Changes localtime to Singapore
RUN cp /usr/share/zoneinfo/Asia/Singapore /etc/localtime
# create a folder /myapp in the docker container and go into that folder
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
# Run bundle install to install gems inside the gemfile
RUN bundle install
ADD . /myapp
CMD bash -c "rm -f tmp/pids/server.pid && rails s -p 3000 -b '0.0.0.0'"
database.yml
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
database: myapp_development
host: db
username: postgres
password: postgres
port: 5432
I can build the app using docker-compose build but whenever I docker-compose up the service db exited but my rails app is running.
This is the logs I'm getting when I run docker-compose up
db_1 | The files belonging to this database system will be owned by user "postgres".
db_1 | This user must also own the server process.
db_1 |
db_1 | The database cluster will be initialized with locale "en_US.utf8".
db_1 | The default database encoding has accordingly been set to "UTF8".
db_1 | The default text search configuration will be set to "english".
db_1 |
db_1 | Data page checksums are disabled.
db_1 |
db_1 | initdb: error: directory "/var/lib/postgresql/data" exists but is not empty
db_1 | If you want to create a new database system, either remove or empty
db_1 | the directory "/var/lib/postgresql/data" or run initdb
db_1 | with an argument other than "/var/lib/postgresql/data".
The error I'm getting when I access http://localhost:3000 is
could not connect to server: No route to host Is the server running on host "db" (172.18.0.2) and accepting TCP/IP connections on port 5432?
I think you should use volume for Postgres too.
services:
db:
image: postgres:alpine
restart: always
volumes:
- postgres_volume:/var/lib/postgresql/data
volumes:
postgres_volume:
I had similar issue and fixed it with that. Try also to restart Docker.

Rails docker postgres Connection refused

I'm trying to dockerize my Rails application, but I have this error when I want to run it with docker-compose:
! Unable to load application: PG::ConnectionBad: could not connect to server: Connection refused
Is the server running on host "postgres" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
my docker-compose file is:
version: '2'
services:
web:
build: .
image: cda_app
container_name: "cda_app_web"
ports:
- '127.0.0.1:${WEB_PORT}:3000'
env_file: .env
volumes:
- gems:/gems
- ./:/var/www/app
logging:
driver: 'json-file'
options:
max-size: '100m'
max-file: '5'
links:
- redis
- postgres
entrypoint: 'bundle exec puma -C config/puma.rb'
redis:
image: 'redis'
volumes:
- redis:/data
- redis_log:/var/log/redis
postgres:
image: 'postgres:12.4'
volumes:
- postgres:/var/lib/postgresql/data
- postgres_log:/var/log/postgresql
volumes:
gems:
redis:
redis_log:
postgres:
postgres_log:
Dockerfile:
ARG BASE_IMAGE=ruby:2.7.1
FROM $BASE_IMAGE
RUN apt-get update && \
apt-get install -y \
apt-utils \
build-essential \
cmake \
curl \
ghostscript \
libmagic-dev \
libpq-dev \
openssh-client \
rename \
&& rm -rf /var/lib/apt/lists/*
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash && apt-get install -y nodejs
RUN npm install -g yarn
WORKDIR /var/www/app
RUN mkdir /gems
ENV BUNDLE_PATH=/gems
RUN gem install bundler
ARG BUNDLE_WITHOUT=development:test
COPY Gemfile Gemfile.lock ./
RUN bundle install --jobs $(nproc) --with BUNDLE_WITHOUT
COPY package.json yarn.lock ./
RUN yarn install --check-files --ignore-optional
COPY . .
RUN rename -f -v 's/\.sample//' config/*sample.yml
EXPOSE 3000
CMD ./bin/puma -b tcp://0.0.0.0:3000
my database.yml:
default: &default
pool: <%= ENV["DB_POOL"] %>
template: 'template0'
adapter: 'postgresql'
database: <%= ENV["DB_NAME"] %>
username: <%= ENV["DB_USER"] %>
host: <%= ENV["DB_HOST"] %>
port: <%= ENV["DB_PORT"] %>
password: <%= ENV["DB_PASSWORD"] %>
timeout: 5000
encoding: 'utf8'
min_messages: WARNING
development:
<<: *default
database: <%= ENV["DB_NAME"] %>_development
test:
<<: *default
database: <%= ENV["DB_NAME"] %>_test<%= ENV['TEST_ENV_NUMBER'] %>
production:
<<: *default
database: <%= ENV["DB_NAME"] %>_production
.env file:
DB_NAME=cda_database
DB_HOST=postgres
DB_USER=postgres
DB_PASSWORD=postgres
DB_PORT=5432
DB_POOL=5
I can't understand what I'm doing wrong?!
It seems I did everything correctly, but I'm getting the error.
I'm using Digitalocean. Also, the database is working outside of docker, but it can't be accessible in docker.
You can try it in docker-compose file. I hope it working
postgres:
image: 'postgres:12.4'
volumes:
- postgres:/var/lib/postgresql/data
- postgres_log:/var/log/postgresql
environment:
- POSTGRES_USER= postgres
- POSTGRES_PASSWORD= postgres
You can write the environment variables each one for postgresql in docker-compose.yml, example:
version: '2'
services:
web:
build: .
image: cda_app
container_name: "cda_app_web"
ports:
- '127.0.0.1:${WEB_PORT}:3000'
env_file: .env
volumes:
- gems:/gems
- ./:/var/www/app
logging:
driver: 'json-file'
options:
max-size: '100m'
max-file: '5'
links:
- redis
- postgres
entrypoint: 'bundle exec puma -C config/puma.rb'
redis:
image: 'redis'
volumes:
- redis:/data
- redis_log:/var/log/redis
postgres:
image: 'postgres:12.4'
volumes:
- postgres:/var/lib/postgresql/data
- postgres_log:/var/log/postgresql
environment:
POSTGRES_PASSWORD: "${DB_PASSWORD}"
POSTGRES_USER: "${DB_USER}"
POSTGRES_DB: "${DB_NAME}"
volumes:
gems:
redis:
redis_log:
postgres:
postgres_log:
Be aware that the file .env must be in the same directory than your docker-compose.yml

fe_sendauth: no password supplied when creating database

I am in the process of dockerizing our Ruby on rails apps. One of them is throwing the following error when I run docker-compose run web bundle exec rake db:create
Starting sapi_db_1 ... done
[WARNING] The git gem requires git 1.6.0.0 or later, but only found
2.1.4. You should probably upgrade.
fe_sendauth: no password supplied
I am confirmed the config files are working as I have used them 3 times previously with oher apps.
Here's my dockerfile
FROM ruby:2.2.3
RUN apt-get update && apt-get -y install build-essential libpq-dev nodejs
RUN gem install bundler
RUN mkdir /app
WORKDIR /app
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle install
ADD . /app
My docker-compose.yml
version: '3'
services:
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/sapi
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://postgres#db
env_file:
- '.env'
depends_on:
- db
db:
image: postgres:latest
ports:
- "5432:5432"
env_file:
- '.env'
My database.yml file
default: &default
adapter: postgresql
pool: 5
timeout: 5000
url: <%= ENV['DATABASE_URL'] %>
username: <%= ENV['POSTGRES_USER'] %>
password: <%= ENV['POSTGRES_PASSWORD'] %>
development:
<<: *default
database: app_development
How can I resolve this? I have already confirmed that the config files work by carrying the process out on other apps.
Resolved by changing the .env file

Docker-compose rails postgres

I've been following this tutorial to 'dockerize' my rails application and have hit a snag with connecting to the db after some searching around, no solutions seem to work. I've also tried the default user 'postgres' and no password, but still no luck. My error indicates that my password is incorrect, but everything I try doesn't change the error:
web_1 | I, [2017-06-02T00:58:29.217947 #7] INFO -- : listening on addr=0.0.0.0:3000 fd=13
postgres_1 | FATAL: password authentication failed for user "web"
postgres_1 | DETAIL: Connection matched pg_hba.conf line 95: "host all all 0.0.0.0/0 md5"
web_1 | E, [2017-06-02T00:58:29.230868 #7] ERROR -- : FATAL: password authentication failed for user "web"
Here's what I have:
.env
LISTEN_ON=0.0.0.0:3000
DATABASE_URL=postgresql://web:mypassword#postgres:5432/web?encoding=utf8&pool=5&timeout=5000
Dockerfile
FROM ruby:2.3.4
RUN apt-get update && apt-get install -qq -y build-essential nodejs libpq-dev postgresql-client-9.4 --fix-missing --no-install-recommends
ENV INSTALL_PATH /web
RUN mkdir -p $INSTALL_PATH
WORKDIR $INSTALL_PATH
COPY Gemfile Gemfile
COPY Gemfile.lock Gemfile.lock
RUN bundle install
COPY . .
# precompile assets using dummy data
RUN bundle exec rake RAILS_ENV=production DATABASE_URL=postgresql://user:pass#127.0.0.1/dbname SECRET_TOKEN=pickasecuretoken assets:precompile
VOLUME ["$INSTALL_PATH/public"]
VOLUME /postgres
CMD RAILS_ENV=development bundle exec unicorn -c config/unicorn.rb
docker-compose.yml
postgres:
image: postgres:9.4.5
environment:
POSTGRES_USER: web
POSTGRES_PASSWORD: mypassword
ports:
- "5432:5432"
volumes:
- postgres:/var/lib/postgresql/data
web:
build: .
links:
- postgres
volumes:
- .:/web
ports:
- "3000:3000"
env_file:
- .env
config/database.yml
default: &default
adapter: postgresql
encoding: unicode
pool: 5
development:
<<: *default
url: <%= ENV['DATABASE_URL'] %>
The line in database.yml grabs the DATABASE_URL environment variable that is stored in the container from the .env file.
I spent the better part of a day fiddling with this. What finally worked for me was to fall back to the Postgres defaults.
docker-compose.yml
postgres:
image: postgres:9.4.5
ports:
- "5432:5432"
volumes:
- postgres:/var/lib/postgresql/data
.env
DATABASE_URL=postgresql://web:#postgres:5432/web?encoding=utf8&pool=5&timeout=5000
In the DATABASE_URL, keeping the password separator in the url but leaving the password blank finally made it work.

Resources