How to configure database.yml and docker-compose.yml files to make them access the same environment database in a ruby on rails application? - ruby-on-rails

I have a ruby on rails application, version 7. I have configured the docker-compose.yml file for different environments (dev, test). But when I run rspec tests, it is not accessing the appropriate database and giving this error in the terminal:
ActiveRecord::EnvironmentMismatchError: You are attempting to modify a database that was last run in 'development' environment.
You are running in 'test' environment. If you are sure you want to continue, first set the environment using:
bin/rails db:environment:set RAILS_ENV=test
This is my docker-compose.yml file:
version: "3.8"
services:
db:
image: postgres:latest
environment:
- POSTGRES_PASSWORD=password
ports:
- "5432:5432"
volumes:
- "dbdata:/var/lib/postgresql/data"
redis:
image: redis:latest
ports:
- "6379:6379"
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
- redis
environment:
- DATABASE_URL=postgres://postgres:password#db:5432/postgres
- REDIS_URL=redis://redis:6379
volumes:
- .:/app
test:
build: .
depends_on:
- db
- redis
environment:
- DATABASE_URL=postgres://postgres:password#db:5432/postgres
- REDIS_URL=redis://redis:6379
- RAILS_ENV=test
entrypoint: ["bundle", "exec", "rspec"]
volumes:
- .:/app
volumes:
dbdata:
And this is my database.yml file
default: &default
adapter: postgresql
encoding: unicode
host: postgres://postgres:password#db:5432/postgres
port: 5432
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
database: my_dev_database
test:
<<: *default
database: my_test_database
production:
<<: *default
database: my_production_database
username: my_username
password: <%= ENV["password"] %>
Can you please, help me how to configure database.yml file to make it access the correct database when I run tests? Thank you!

Related

Confused by docker networking / connections

OK so I am trying to deploy a Rails app to a docker container (host machine is a mac). I was thinking to deploy in development first to check everything is working.
I have setup a phpmyadmin service and I can connect to the server by typing in server name moviedb_mariamovie_1 with user root and corresponding PW.
But whatever I put into my database.yml for Rails doesn't work: I tried localhost, I tried 127.0.0.1, I tried "mariamovie" and I tried "moviedb_mariamovie_1", and it always says "host not found" when I tried rails db:create (or anything actually that involves the DB).
I am totally confused by this. I read the database section of the docker manuals and I seem to be too stupid for that.
(I have other problems with this but one after the other :)
docker-compose.yml:
version: "3.7"
services:
moviedb:
image: tkhobbes/moviedb
restart: unless-stopped
ports:
- 3001:3000
depends_on:
- mariamovie
environment:
MYSQL_ROOT_PASSWORD: redacted
RAILS_ENV: development
volumes:
- /Users/thomas/Documents/Production/moviedb/storage:/opt/activestorage
mariamovie:
image: mariadb
restart: unless-stopped
ports:
- 3333:3306
environment:
MYSQL_ROOT_PASSWORD: redacted
phpmymaria:
image: phpmyadmin
restart: unless-stopped
ports:
- 8021:80
depends_on:
- mariamovie
environment:
PMA_PORT: 3333
PMA_ARBITRARY: 1
image: nginx:1.21-alpine
volumes:
- /Users/thomas/Documents/Production/moviedb/vendor/nginx:/etc/nginx/user.conf.d:ro
ports:
- 8020:8020
depends_on:
- moviedb
restart: unless-stopped
database.yml:
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
host: 127.0.0.1
port: 3333
username: redacted
password: redacted
development:
<<: *default
database: newmovie_development
...
You're inside your docker "network". Your database should be accessible from your Rails app (which is inside too) via mariamovie:3306.

Rails 6 Docker with PostgreSQL Connection Error

I'm currently starting with Docker and trying to adapt my first application with a Docker- and a Docker-compose file.
It seems to work fine, until I reach the point where I want to create my database. I set up the environment variables correctly and reflected them in my database.yml file
Here's my .env:
POSTGRES_USER='deploy'
POSTGRES_PASSWORD='deploy'
POSTGRES_DB='nkbrf_db'
Here's my database.yml:
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= ENV['POSTGRES_USERNAME'] %>
password: <%= ENV['POSTGRES_PASSWORD'] %>
database: <%= ENV['POSTGRES_DB'] %>
host: db
development:
<<: *default
test:
<<: *default
production:
<<: *default
Here's my docker-compose.yml:
version: '3'
services:
db:
image: postgres
volumes:
- 'postgres:/var/lib/postgresql/data'
env_file:
- '.env'
ports:
- "5432"
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/nkbrfqm
- bundler_gems:/bundle
ports:
- "3000:3000"
environment:
RAILS_ENV: development
depends_on:
- db
volumes:
postgres:
bundler_gems:
It sets up everything correctly but if I try to create my database with
docker-compose run web rake db:create
I get the following error:
PG::ConnectionBad: FATAL: password authentication failed for user
"root"
Where does this user "root" come from? Is something wrong with my environment variable settings?
You need to remove single-quote ' in the .env file then you need to remove all containers in the compose file(docker-compose rm). then execute docker-compose up -d
Example
# .env
POSTGRES_USER=deploy
POSTGRES_PASSWORD=deploy
POSTGRES_DB=nkbrf_db
Thanks

Docker-compose giving URI::InvalidURIError: the scheme postgresql does not accept registry part: $DB_USER:$DB_PASSWORD#$DB_HOST:port (orbad hostname?)

I am using multi containers for a ruby app. The containers are working fine but when it comes to creating database using docker-compose run app rails db:create I get the following error.
rails aborted!
URI::InvalidURIError: the scheme postgresql does not accept registry part: $DB_USER:$DB_PASSWORD#$DB_HOST:port (orbad hostname?).
A snippet of the docker-compose file is shown below
db:
image: postgres:9.4
volumes_from:
- data
environment:
POSTGRES_USER: cpostgres
POSTGRES_DB: micro_login_db
ports:
- 5432
app:
build: .
depends_on:
- db
volumes:
- .:/webapp
command: rails server -p 3000 -b 0.0.0.0
ports:
- 3000:3000
environment:
DB_HOST: db
DB_USER: cpostgres
POSTGRES_DB: micro_login_db
POSTGRES_TEST_DB: micro_login_test
Someone else suggested I create a file named application.yml with the following details
DB_USER: 'cpostgres'
DB_PASSWORD: ''
DB_HOST: 'db'
POSTGRES_DB: 'micro_login_db'
port: 5432
And finally the database.yml file
default: &default
adapter: postgresql
template: template0
encoding: unicode
username: <%= ENV['DB_USER'] %>
database: <%= ENV['POSTGRES_DB'] %>
host: <%= ENV['DB_HOST'] %>
pool: 5
timeout: 5000
development:
<<: *default
Question is, why am I getting this error? How can I solve it? Any help would be greatly appreciated.
Your POSTGRES_DB value has underscore. Have you tried removing those?
Hostname with underscores are known to be problematic sometimes.
Reference

Docker: Docker-compose ruby + postgres - PG::ConnectionBadcould not connect to server

I created Dockerfile to ruby from official docker-compose website. I used docker compose to integrate this with Postgres. When docker-compose up, then PostgreSQL starts but I cannot connect to this. The main problem is in ruby database config because I can't change to listen to another host and set the default user. I don't know how to connect these two containers without changing the ruby database config.
Dockerfile
FROM ruby:2.3.4
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
ADD . /myapp
Docker-compose
version: '3'
services:
db:
image: postgres:9.6
ports:
- "5432:5432"
web:
build: .
ports:
- "4000:4000"
depends_on:
- db
Ruby database.yml
default: &default
adapter: postgresql
encoding: unicode
pool: 5
development:
<<: *default
database: project_development
If i run inside web conatiner "bundle exec rake db:create I get error:
psql: 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"?
I don't know what env set that will connect together.
You didn't specify database host in your database.yml. Set it to db or just try this database.yml
development: &default
adapter: postgresql
encoding: unicode
database: project_development
pool: 5
username: postgres
password:
host: db
test:
<<: *default
database: project_test
You should update your database.yml with the following:
database: ENV['DB_NAME']
username: ENV['DB_USERNAME']
password: ENV['DB_PASSWORD']
There's no such thing as "default PG user", so you have to create your own user with a proper permissions.
So, once you have a PG user created inside of container, you can update your docker-compose.yml file with a proper DB settings:
web:
environment:
- DB_NAME=rails_development
- DB_USERNAME=rails_user
- DB_PASSWORD=rails_password
Also, you probably want to mount local storage of postgres in your docker-compose.yml to keep data when container restarts:
volumes:
- /var/lib/postgresql/data
Just to add to Bartosz Bonisławski's answer.
I encountered this issue when building a Rails application on Ubuntu 18.04.
My Dockerfile for my development environment which was located in docker/development/Dockerfile directory of my project was defined like this:
version: '3'
services:
app:
build:
context: .
dockerfile: ./docker/${RAILS_ENV}/Dockerfile
depends_on:
- database
- redis
ports:
- "3000:3000"
restart: always
volumes:
- .:/app
- gem-cache:/usr/local/bundle/gems
- node-modules:/app/node_modules
env_file:
- .env
environment:
RAILS_ENV: ${RAILS_ENV}
RACK_ENV: ${RACK_ENV}
database:
image: postgres:12.1
expose:
- "5432"
restart: always
env_file:
- .env
environment:
POSTGRES_USER: ${DATABASE_USER}
POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
POSTGRES_DB: ${DATABASE_NAME}
POSTGRES_HOST_AUTH_METHOD: ${DATABASE_HOST}
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
gem-cache:
driver: local
node-modules:
driver: local
postgres-data:
driver: local
While my .env file was defined as this:
DATABASE_USER=myapp_user
DATABASE_PASSWORD=myapp_password
DATABASE_NAME=myapp_development
DATABASE_HOST=database
DATABASE_PORT=5432
RAILS_ENV=development
RACK_ENV=development
The issue I had was that I did not add host config to my database.yml file of my project. So I was encountering the error:
psql: 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's how I solved:
I simply added it like this and it worked perfectly fine:
default: &default
adapter: postgresql
encoding: unicode
# For details on connection pooling, see Rails configuration guide
# https://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
database: <%= ENV['DATABASE_NAME'] %>
username: <%= ENV['DATABASE_USER'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
host: <%= ENV['DATABASE_HOST'] %>
port: <%= ENV['DATABASE_PORT'] %>
That's all.
I hope this helps

Getting "FATAL: role "root" does not exist" when trying to do "docker up"

I'm starting to work with an existing Rails project that uses Docker. I've used Rails for a long time but never Docker.
After I do a docker build . I try to do a docker-compose up, but I get:
FATAL: role "root" does not exist
/usr/local/bundle/gems/activerecord-4.2.5.2/lib/active_record/connection_adapters/postgresql_adapter.rb:661:in `rescue in connect': FATAL: role "root" does not exist (ActiveRecord::NoDatabaseError)
It seems to me that the Docker machine is probably trying to connect to the database as the root user, but there's no role called root, so the connection is rightly failing.
The thing I don't know is why Docker is apparently trying to connect to the database as root and how to get it to use the right user.
Here's my database.yml:
development:
database: my_app_development
adapter: postgresql
encoding: unicode
pool: 5
Any help is appreciated.
Edit: here's my docker-compose.yml:
web:
build: .
volumes:
- .:/my_app
ports:
- "3000:3000"
links:
- postgres
- redis
- mailcatcher
env_file:
- 'config/application.yml'
postgres:
image: postgres:9.4
ports:
- "5432"
env_file:
- 'config/database.yml'
redis:
image: redis:3.0.6
mailcatcher:
image: schickling/mailcatcher
ports:
- "1080:1080"
Postgres image expects POSTGRES_USER, POSTGRES_PASSWORD and POSTGRES_DB to be provided. Otherwise it will use default values. Create a .env file in the root directory of your project:
# .env file
POSTGRES_USER=testuser
POSTGRES_PASSWORD=testpass
POSTGRES_DB=db_development
and change you docker-compose file as:
web:
build: .
volumes:
- .:/my_app
ports:
- 3000:3000
depends_on:
- postgres
- redis
- mailcatcher
postgres:
image: postgres:9.4
ports:
- 5432:5432
env_file: .env
redis:
image: redis:3.0.6
mailcatcher:
image: schickling/mailcatcher
ports:
- 1080:1080
You could also provide the environment variables without .env file:
web:
build: .
volumes:
- .:/my_app
ports:
- 3000:3000
depends_on:
- postgres
- redis
- mailcatcher
postgres:
image: postgres:9.4
ports:
- 5432:5432
environment:
- POSTGRES_USER=testuser
- POSTGRES_PASSWORD=testpass
- POSTGRES_DB=db_development
redis:
image: redis:3.0.6
mailcatcher:
image: schickling/mailcatcher
ports:
- 1080:1080
and update your database.yml file:
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= ENV['POSTGRES_USER'] %>
password: <%= ENV['POSTGRES_PASSWORD'] %>
host: postgres
development:
<<: *default
database: db_development
test:
<<: *default
database: db_test
production:
<<: *default
database: db_production
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 25 } %>
WARNING: Don't use links, it'll be removed soon
You might want to update your compose and database yml as follows. With the expected db user and password in the database.yml. Also, you can make this is an environment variable. But try the default for the postgres db docker image first as follows;
database.yml
development:
database: my_app_development
adapter: postgresql
encoding: unicode
pool: 5
username: postgres
password:
host: postgres(db name in docker-compose.yml)
docker-compose.yml
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/my_app
ports:
- "3000:3000"
links:
- postgres
- redis
- mailcatcher
postgres:
image: postgres:9.4
ports:
- "5432"
redis:
image: redis:3.0.6
mailcatcher:
image: schickling/mailcatcher
ports:
- "1080:1080"
I dont think you want to keep
env_file:
- 'config/database.yml'
and
env_file:
- 'config/application.yml'
Then create the databases with docker-compose run web rake db:create
I added the command instruction because I dont know what your Dockerfile looks like. But if you have a successful build of the app image with docker build -t app-name ., you can remove it and just run docker-compose up.
Without an explicit user set in the database.yml it will attempt to use the root user as this is the same user postgres is running under in the container. To fix this, try setting your database.yml as:
development:
database: my_app_development
adapter: postgresql
encoding: unicode
pool: 5
username: postgres
Note the addition of the username field.
With docker-compose, it tries to preserve volumes between runs; since the user is only created on a new database, you probably need to docker-compose rm -v database to delete the container and associated volume.
And try docker-compose up --build again.
Source: https://github.com/docker-library/postgres/issues/41#issuecomment-167603905

Resources