Skip to content

Commit

Permalink
Merge pull request #114 from fly-apps/single-database-url-secret
Browse files Browse the repository at this point in the history
Enable DATABASE_URL to control the placement of all of the databases
  • Loading branch information
rubys authored Sep 24, 2024
2 parents 8599053 + 02de62d commit a84f7f3
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 3 deletions.
29 changes: 29 additions & 0 deletions lib/generators/dockerfile_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,8 @@ def generate_app

template "docker-compose.yml.erb", "docker-compose.yml" if options.compose

template "database.yml.erb", "config/database.yml" if fix_database_config

if using_litefs?
template "litefs.yml.erb", "config/litefs.yml"

Expand Down Expand Up @@ -1450,4 +1452,31 @@ def fly_make_toml

toml
end

# if there are multiple production databases defined, allow them all to be
# configured via DATABASE_URL.
def fix_database_config
yaml = IO.read("config/database.yml")

production = YAML.load(yaml, aliases: true)["production"]
return unless production.is_a?(Hash) && production.values.all?(Hash)
return if production.keys == [ "primary" ]

section = yaml[/^(production:.*?)(^\S|\z)/m, 1]

replacement = section.gsub(/( ).*?\n((\1\s+).*?\n)*/) do |subsection|
spaces = $3
name = subsection[/\w+/]

if /^ +url:/.match?(subsection)
subsection
elsif name == "primary"
subsection + spaces + %(url: <%= ENV["DATABASE_URL"] %>\n)
else
subsection + spaces + %(url: <%= URI.parse(ENV["DATABASE_URL"]).tap { |url| url.path += "_#{name}" } if ENV["DATABASE_URL"] %>\n)
end
end

yaml.sub(section, replacement)
end
end
1 change: 1 addition & 0 deletions lib/generators/templates/database.yml.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= fix_database_config %>
10 changes: 10 additions & 0 deletions test/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,16 @@ def check_entrypoint
assert_equal expected, results
end

def check_database_config
results = IO.read("config/database.yml")

IO.write("#{@results}/database.yml", results) if @capture

expected = IO.read("#{@results}/database.yml")

assert_equal expected, results
end

def teardown
return if ENV["TEST_KEEP"]
Dir.chdir ".."
Expand Down
4 changes: 2 additions & 2 deletions test/results/postgresql/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,5 @@ USER rails:rails
ENTRYPOINT ["/rails/bin/docker-entrypoint"]

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD ["./bin/rails", "server"]
EXPOSE 80
CMD ["bundle", "exec", "thrust", "./bin/rails", "server"]
102 changes: 102 additions & 0 deletions test/results/postgresql/database.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# PostgreSQL. Versions 9.3 and up are supported.
#
# Install the pg driver:
# gem install pg
# On macOS with Homebrew:
# gem install pg -- --with-pg-config=/usr/local/bin/pg_config
# On Windows:
# gem install pg
# Choose the win32 build.
# Install PostgreSQL and put its /bin directory on your path.
#
# Configure Using Gemfile
# gem "pg"
#
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: test_postgresql_development

# The specified database role being used to connect to PostgreSQL.
# To create additional roles in PostgreSQL see `$ createuser --help`.
# When left blank, PostgreSQL will use the default role. This is
# the same name as the operating system user running Rails.
#username: test_postgresql

# The password associated with the PostgreSQL role (username).
#password:

# Connect on a TCP socket. Omitted by default since the client uses a
# domain socket that doesn't need configuration. Windows does not have
# domain sockets, so uncomment these lines.
#host: localhost

# The TCP port the server listens on. Defaults to 5432.
# If your server runs on a different port number, change accordingly.
#port: 5432

# Schema search path. The server defaults to $user,public
#schema_search_path: myapp,sharedapp,public

# Minimum log levels, in increasing order:
# debug5, debug4, debug3, debug2, debug1,
# log, notice, warning, error, fatal, and panic
# Defaults to warning.
#min_messages: notice

# 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: