Skip to content

Commit

Permalink
Merge pull request #14286 from opf/feature/production-database-yml
Browse files Browse the repository at this point in the history
Allow customization of the production database.yml
  • Loading branch information
machisuji committed Nov 30, 2023
2 parents 385e46f + 69747f2 commit b7e402b
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 24 deletions.
77 changes: 77 additions & 0 deletions config/database.production.yml
@@ -0,0 +1,77 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2023 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++

<%
DATABASE_OPTIONS = %w[
url
database
encoding
pool
username
password
sslmode
sslcompression
sslcert
sslkey
sslpassword
sslrootcert
sslcrl
application_name
statement_timeout
].freeze
DATABASE_VARIABLES = %w[
statement_timeout
]
DATABASE_DEFAULTS = {
# Fallback to unprefixed DATABASE_URL if present
'url' => ENV['DATABASE_URL'],
'statement_timeout' => ENV.fetch("POSTGRES_STATEMENT_TIMEOUT", "90s"),
'encoding' => 'unicode',
'application_name' => 'openproject',
}.freeze
%>

production:
adapter: postgresql
<% DATABASE_OPTIONS.each do |option| %>
<% env_name = "OPENPROJECT_DB_#{option.upcase}" %>
<% value = ENV.fetch(env_name, DATABASE_DEFAULTS[option]) %>
<% unless value.nil? %>
<%= option %>: <%= value %>
<% end %>
<% end %>
variables:
<% DATABASE_VARIABLES.each do |option| %>
<% env_name = "OPENPROJECT_DB_#{option.upcase}" %>
<% value = ENV.fetch(env_name, DATABASE_DEFAULTS[option]) %>
<% unless value.nil? %>
<%= option %>: <%= value %>
<% end %>
<% end %>
1 change: 1 addition & 0 deletions docker/prod/Dockerfile
Expand Up @@ -49,6 +49,7 @@ COPY Rakefile .
COPY bin ./bin
COPY app ./app
COPY config ./config
COPY config/database.production.yml ./config/database.yml
COPY lib ./lib
COPY lib_static ./lib_static
COPY frontend ./frontend
Expand Down
8 changes: 0 additions & 8 deletions docker/prod/setup/postinstall-common.sh
Expand Up @@ -48,11 +48,3 @@ rm -rf "$APP_PATH/frontend/.angular"
rm -rf /root/.npm

rm -f "$APP_PATH/log/production.log"

cat > "$APP_PATH/config/database.yml" <<CONF
production:
url: <%= ENV.fetch("DATABASE_URL") %>
variables:
# https://github.com/ankane/the-ultimate-guide-to-ruby-timeouts#postgresql
statement_timeout: <%= ENV.fetch("POSTGRES_STATEMENT_TIMEOUT", "90s") %>
CONF
Expand Up @@ -48,16 +48,58 @@ In both cases the seeder will be run when you (re)launch OpenProject to make sur



## Setting DATABASE_URL and options separately

OpenProject will merge the settings from `DATABASE_URL` with manually specified environment options. Here are the supported options:

| Environment variable | Default | Description | Documentation |
| ------------------------------------ | ----------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| DATABASE_URL<br />OPENPROJECT_DB_URL | *none* | URL style passing of database options | https://guides.rubyonrails.org/configuring.html#configuring-a-database |
| OPENPROJECT_DB_ENCODING | unicode | Encoding of the database | Should be left at unicode unless you really know what you're doing. |
| OPENPROJECT_DB_POOL | *none* | Connection pool count | https://guides.rubyonrails.org/configuring.html#database-pooling |
| OPENPROJECT_DB_USERNAME | *none* | Database username, if not presented in URL above | https://guides.rubyonrails.org/configuring.html#configuring-a-database |
| OPENPROJECT_DB_PASSWORD | *none* | Database password, if not presented in URL above | https://guides.rubyonrails.org/configuring.html#configuring-a-database |
| OPENPROJECT_DB_APPLICATION_NAME | openproject | PostgreSQL application name option | https://www.postgresql.org/docs/13/libpq-connect.html#LIBPQ-CONNECT-APPLICATION-NAME |
| OPENPROJECT_DB_STATEMENT_TIMEOUT | 90s | Default statement timeout before connection statements are terminted | https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-STATEMENT-TIMEOUT |



## Using SSL/TLS with a PostgreSQL database

By default, the packaged installation installs a local database and does not use SSL encryption. If you provide a custom PostgreSQL database that supports SSL/TLS connections for servers and/or clients, you can pass the options as part of the DATABASE_URL. See the above guides on how to set this environment variable for Docker or packaged installations.

The most import option is the `sslmode` parameter. Set this to the appropriate mode as defined in the [PostgreSQL documentation](https://www.postgresql.org/docs/13/libpq-connect.html#LIBPQ-PARAMKEYWORDS). For example, to require a SSL connection with full verification of the server certificate, use these parameters:
The most import option is the `sslmode` parameter. Set this to the appropriate mode as defined in the [PostgreSQL documentation](https://www.postgresql.org/docs/13/libpq-connect.html#LIBPQ-PARAMKEYWORDS). For example, to require a SSL connection with full verification of the server certificate, you can add it to the database URL:

```bash
DATABASE_URL=postgres://user:pass@host:port/dbname?sslmode=require-full&sslcert=/path/to/postgresql.cert
```

Alternatively, for better readibility, you can set these parameters with separate environment variables:

| Environment variable | Default | Description | PostgreSQL documentation |
| ----------------------------- | ---------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| OPENPROJECT_DB_SSLMODE | prefer | connection mode for SSL. See | [sslmode](https://www.postgresql.org/docs/13/libpq-connect.html#LIBPQ-CONNECT-SSLMODE) |
| OPENPROJECT_DB_SSLCOMPRESSION | 0 | If set to 1, data sent over SSL connections will be compressed | [sslcompression](https://www.postgresql.org/docs/13/libpq-connect.html#LIBPQ-CONNECT-SSLCOMPRESSION) |
| OPENPROJECT_DB_SSLCERT | ~/.postgresql/postgresql.crt | Path to certificate | [sslcert](https://www.postgresql.org/docs/13/libpq-connect.html#LIBPQ-CONNECT-SSLCERT) |
| OPENPROJECT_DB_SSLKEY | ~/.postgresql/postgresql.key | Path to certificate key | [sslkey](https://www.postgresql.org/docs/13/libpq-connect.html#LIBPQ-CONNECT-SSLKEY) |
| OPENPROJECT_DB_SSLPASSWORD | | Password to certificate key | [sslpassword](https://www.postgresql.org/docs/13/libpq-connect.html#LIBPQ-CONNECT-SSLPASSWORD) |
| OPENPROJECT_DB_SSLROOTCERT | ~/.postgresql/root.crt | Path to CA | [sslrootcert](https://www.postgresql.org/docs/13/libpq-connect.html#LIBPQ-CONNECT-SSLROOTCERT) |
| OPENPROJECT_DB_SSLCRL | ~/.postgresql/root.crl | Path to revocation list | [sslcrl](https://www.postgresql.org/docs/13/libpq-connect.html#LIBPQ-CONNECT-SSLCRL) |



```
="prefer" # disable, allow, prefer, require, verify-ca, verify-full
="0" # 0 or 1
="~/.postgresql/postgresql.crt" # Path to the certificate
="~/.postgresql/postgresql.key" # Path to the certificate private key
="" # Password for the certificate key, if any
="~/.postgresql/root.crt" # Path to CA
="~/.postgresql/root.crl" # Path to revocation list
```





PostgreSQL supports a wide variety of options in its connection string. This is not specific to OpenProject or Rails. See the following guide for more information: https://www.postgresql.org/docs/13/libpq-connect.html#LIBPQ-PARAMKEYWORDS
14 changes: 0 additions & 14 deletions packaging/conf/database.yml

This file was deleted.

2 changes: 1 addition & 1 deletion packaging/setup
Expand Up @@ -4,7 +4,7 @@
date -u +"%Y-%m-%dT%H:%M:%SZ" > RELEASE_DATE

# Copy default database.yml
cp -f packaging/conf/database.yml config/database.yml
cp -f config/database.production.yml config/database.yml

cp -f packaging/conf/configuration.yml config/configuration.yml
sed -i "s|config.public_file_server.enabled = false|config.public_file_server.enabled = true|" config/environments/production.rb
Expand Down

0 comments on commit b7e402b

Please sign in to comment.