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
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: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 ofENV['POSTGRES_PASSWORD']
.I can only guess.
ENV['POSTGRES_PASSWORD']
might be blank and that line might look like this after processing: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: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:
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 fromdatabase.yml
.For example to connect to the
my_hostname
asbob
with the passwordp4ssword
you would setENV["DATABASE_URL"]
to: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: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.