skip to Main Content

I really need some help. I am new to Ruby on Rails. I am building a rails 7.1.0 app using postresql with docker. I am working on a Pop!_OS 22.04 LTS computer with
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux] and psql (PostgreSQL) 16.0 (Ubuntu 16.0-1.pgdg22.04+1) installed.
After I run command "docker-compose build", everything went well with the compiling process.

But when I try to run docker-compose up it keeps saying bin/rails aborted!
YAML syntax error occurred while parsing /rails/config/database.yml. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Error: (): found character that cannot start any token while scanning for the next token at line 14 column 13

There is what I tried.

After I build he app with "docker-compose build". I ran the command "docker-compose up" in the terminal. I was expecting to launch server with docker so that I could launch the app at the "localhost:3000" address in my browser. But I got the opposite.

My terminal displayed the following:

sharkphonesuniverse-demo-web-1  | YAML syntax error occurred while parsing
/rails/config/database.yml. Please note that YAML must be consistently
indented using spaces. Tabs are not allowed. Error: (<unknown>): found
character that cannot start any token while scanning for the next token at
line 14 column 13

Here is the content of my database.yml:

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 } %>
  host: <%= ENV['POSTGRES_HOST'] %>
  port: 5432

development:
  <<: *default
  database: sharkphonessale_development
  username: <%= ENV['POSTGRES_USER'] %>
  password: <%= ENV['POSTGRES_PASSWORD'] %>

test:
  <<: *default
  database: sharkphonessale_test
  username: <%= ENV['POSTGRES_USER'] %>
  password: <%= ENV['POSTGRES_PASSWORD'] %>

production:
  <<: *default
  database: <%= ENV['POSTGRES_DB'] %>
  username: <%= ENV['POSTGRES_USER'] %>
  password: <%= ENV['POSTGRES_PASSWORD'] %>

The contents of my .env file

RAILS_ENV=production
POSTGRES_HOST=db
POSTGRES_DB=demodb_production
POSTGRES_USER=my db username goes here
POSTGRES_PASSWORD=my db password goes here
RAILS_MASTER_KEY=I paste the content of my config > master.key file here

N.B. I already made sure that the database.yml contents are consistently indented, and I also checked my database.yml content here at https://www.yamllint.com/, and it shows its content is valid. But I still get the same error message.

2

Answers


  1. The error message tells that the issue in line 14 column 13. It is not always clear if those tools start counting lines and columns with 0 or 1, but I guess the error message refers to this line in the development section:

      password: <%= ENV['POSTGRES_PASSWORD'] %>
                ^
    

    Now it makes sense to take a look at how Ruby on Rails handles that file. First it reads the file, then it processes the ERB statement in that file and replaces the statements with their return values, and then the last step Rails parses the YAML.

    That means, when the YAML parse raises an error, then we do not need to look at the raw YAML file. But instead, we need to understand how the document will look like after the ERB statements were processed.

    And because the error message refers to exact that position at which the return value of the <%= ENV['POSTGRES_PASSWORD'] %> in the document starts, it is pretty clear that the problem is actually the value of ENV['POSTGRES_PASSWORD'].

    I can only guess. ENV['POSTGRES_PASSWORD'] might be blank and that line might look like this after processing:

      password: 
    

    Or it might be present, but the password starts with a character that leads the YAML to become invalid. Imagine the password was {foo, then that line would look like this:

      password: {foo
    

    And as a result, the YAML would be invalid because the { is an indicator character that is not allowed at that place.

    To fix this issue:

    • Double-check that the POSTGRES_PASSWORD environment variable is actually set in your development environment.

    • Review if the password includes characters that require special handling in YAML. Or wrap the output of the ERB statement with quotes, like this:

        password: "<%= ENV['POSTGRES_PASSWORD'] %>"
      
    Login or Signup to reply.
  2. You ain’t gonna need it.

    In Rails you can set any of the database settings through ENV["DATABASE_URL"] which is automatically merged with the settings from database.yml.

    For example to connect to the my_hostname as bob with the password p4ssword you would set ENV["DATABASE_URL"] to:

    postgresql://my_hostname/my_database_name?password=p4ssword&user=bob
    

    There is no need to create a bunch of additional configuration vars.

    In fact you really just need the bare minimum in your database.yml file:

    default: &default
      adapter: postgresql
      encoding: unicode
      pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
    
    development:
      <<: *default
      database: sharkphonessale_development
    
    # Warning: The database defined as "test" will be erased and
    # re-generated from your development database when you run "rake".
    # Do not set this db to the same as development or production.
    test:
      <<: *default
      database: sharkphonessale_test
      
    # This entire configuration is provided via ENV["DATABASE_URL"]
    production:
      <<: *default
    

    This "just works" out of the box with Postgres in test and development in most cases as the defaults don’t require any config. All you then have to do is set a single ENV var in production.

    Don’t make things more complicated then they need to be.

    You also don’t need DotEnv if your project uses Docker. If any additional config is needed provide it via the Docker config or through Rails encrypted credentials.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search