Jason Swett
Jason Swett

Reputation: 45094

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"

Upvotes: 14

Views: 32620

Answers (4)

Aref Aslani
Aref Aslani

Reputation: 1636

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

Upvotes: 4

LeoT
LeoT

Reputation: 21

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

Upvotes: 2

Samuel
Samuel

Reputation: 2442

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.

Upvotes: 2

Olalekan Sogunle
Olalekan Sogunle

Reputation: 2357

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.

Upvotes: 4

Related Questions