User:Matthewtrescott/OpenProject

Jump to: navigation, search
OpenProject is an open-source web-based project management system written in Ruby (with a front-end in Angular). It is a fork of ChiliProject, which was a fork of Redmine.
OpenProject Work Packages.png
  • OpenProject Icon.png OpenProject
    openproject
  • Modern, web-based, open-source project management system
  • Developer:
    OpenProject GmbH
  • License:
    GPL-3.0

Installation

Icon-info.png
The packages described here have a few differences compared to the packages provided upstream. See the Limitations section below for more details.


These packages are not (yet) part of the main openSUSE distribution, so you will need to add a few extra repositories. On openSUSE Tumbleweed:

# zypper addrepo https://download.opensuse.org/repositories/devel:/languages:/ruby:/extensions/openSUSE_Tumbleweed/devel:languages:ruby:extensions.repo
# zypper addrepo https://download.opensuse.org/repositories/home:/matthewtrescott:/openproject/openSUSE_Tumbleweed/home:matthewtrescott:openproject.repo

On openSUSE Leap 15.2:

# zypper addrepo https://download.opensuse.org/repositories/devel:/languages:/ruby/openSUSE_Leap_15.2/devel:languages:ruby.repo
# zypper addrepo https://download.opensuse.org/repositories/devel:/languages:/ruby:/extensions/openSUSE_Leap_15.2/devel:languages:ruby:extensions.repo
# zypper addrepo https://download.opensuse.org/repositories/home:/matthewtrescott:/openproject/openSUSE_Leap_15.2/home:matthewtrescott:openproject.repo

Then, install the openproject package. You may wish to use YaST to de-select some of the automatically-recommended packages that you don't need (for example, all the Ruby 2.5 and Ruby 2.7 packages that get pulled in). Installing the package from the command line with Zypper will not cause any problems, but will take up slightly more disk space with packages you don't need.

Since OpenProject is a Ruby on Rails app, it uses a Ruby-specific web server called Puma to handle requests. (Puma implements the Rack API, a standard for Ruby web programs.) Puma is not as well-suited for serving static assets like images and CSS stylesheets, and is not as flexible for configuration by a system administrator. It is strongly recommended to use a reverse proxy, and by default, when you install the openproject package, Apache will automatically be installed to fill this role. If you do not wish to use Apache as your reverse proxy, you may de-select the “recommended” packages apache2 and openproject-apache2 at installation.

The openproject-apache2 package only includes a configuration file for Apache, and you are not required to use it. You are free to configure Apache yourself, or choose another reverse proxy like Nginx or Lighttpd, which can be somewhat faster than Apache but are less flexible. However, when configuring the reverse proxy yourself,

  • You will need to find the correct settings for your chosen web server and write your own configuration file. (The openproject-apache2 package provides a configuration file for Apache, which is highly recommended.)
  • You will need to install the PostgreSQL database server manually (via the postgresql-server package), or point OpenProject to a PostgreSQL server on a different machine.
  • Git and Subversion repository support will require extra work to set up, since OpenProject's repository management and authentication mechanism relies on mod_perl, which is a module specifically for Apache. You can install the openproject-scm-perl-scripts package on another machine if you would like to host repositories separately—but this will still require hosting them with Apache.

Configuring OpenProject

Low-level configuration (e.g. for the Puma application server and Git/SVN repositories) is handled via environment variables, which are stored in /etc/sysconfig/openproject-application and loaded by systemd when the OpenProject service starts up. If you use the YaST Sysconfig editor (shipped by default with openSUSE and highly recommended), you will find the settings in the Network/OpenProject group. All other configuration is handled via the OpenProject web app, and the settings are stored in the OpenProject database.

Sysconfig Settings

The default settings provided with the package should be suitable, although you may wish to tune certain settings for performance. Secret keys are set to “abc123” on installation, but will be generated the first time OpenProject is started. This guide will tell you which settings to change where needed.

Web App Settings

The official OpenProject documentation will guide you through configuring the application. Please note that the version of OpenProject provided in this package has been patched so that the Sys API is configured via environment variables instead of the web app frontend.


Configuring Apache

The openproject-apache2 package (installed by default when installing OpenProject, unless specifically de-selected) provides a sample configuration for Apache and installs it to /etc/apache2/vhosts.d/openproject.conf. This configuration file is written to automatically detect repository hosting features when they are available and will work almost out-of-the-box. You may safely edit this configuration file without worrying about it being overwritten on updates—any changes to the file in the package will go to a new file called /etc/apache2/vhosts.d/openproject.conf.rpmnew.

Enabling Apache modules

The sample Apache configuration file provided with the OpenProject package uses configuration directives provided by these modules, so Apache won't start unless you enable them. The authz_host module is used to protect the Sys API (which performs user authentication for repositories) from outside requests. The filter and deflate modules help speed up your website by compressing the HTML, CSS, and JavaScript sent to users' web browsers. The proxy and proxy_http modules are used to forward requests to Puma.

# a2enmod authz_host
# a2enmod filter
# a2enmod deflate
# a2enmod proxy
# a2enmod proxy_http

Now that you've enabled the necessary modules, set the ServerName directive at the top of /etc/apache2/vhosts.d/openproject.conf to your real domain name.

Configuring loopback HTTP connections

When Subversion or Git repositories are hosted on the same machine as the web app, different parts of OpenProject need to be able to make HTTP requests to each other. For more details on why this is required, see the section of this article called Repository Configuration. The web app that you interact with makes requests to the repository management Perl script, and the repository authentication Perl script makes requests to the web app's Sys API to validate user accounts.

The default Apache configuration provided with these packages includes the following line for convenience:

ServerAlias localhost

This allows access to your OpenProject instance via the built-in localhost domain name. If OpenProject is the only website you will be serving on your server, then it is OK to leave this line in your file for convenience. However, if you are serving multiple virtual hosts, you will probably want to delete this line from your configuration. If you are hosting Git and/or Subversion repositories on the same machine as the OpenProject web app, follow the steps below for a better method that avoids conflicts.

Using an entry in /etc/hosts

Make sure the fully-qualified public domain name for your OpenProject instance is included in your /etc/hosts file. This allows OpenProject to make loopback HTTP requests with the HTTP “Host” header set correctly, which in turn allows Apache to correctly determine which virtual host configuration to use. Add the following lines to your /etc/hosts file:

127.0.0.1       openproject.example.com
::1             openproject.example.com

(Of course, replace your openproject.example.com with your real domain name.) Then, launch the YaST Sysconfig editor. Replace “localhost” with your public domain name in the following variables as needed:

  • OPENPROJECT_REPOAUTH_APP_URL (for all setups where repositories are located on the same machine as the web app)
  • OPENPROJECT_SUBVERSION_MGMT_URL (only if using Subversion and using the “repoman” Perl script)
  • OPENPROJECT_GIT_MGMT_URL (only if using Git and using the “repoman” Perl script)

Additional precaution for a public website

If you are hosting a public website on a VPS service, you'll want to restrict website access to your personal IP address until you've changed the default password. Add this line to /etc/apache2/openproject.conf, just below the opening <VirtualHost> tag, but replace the example IPv4 and IPv6 addresses below with your own:

<Location '/'>
    Require ip 12.34.56.78 f05e:2a00:1712:a50:8260:69a4:8106:c337
</Location>

Starting and Stopping OpenProject

OpenProject startup uses systemd. Enable the service for start-up on boot, and then start it now:

# systemctl enable openproject.service
# systemctl start openproject.service

If everything was successful, your OpenProject instance should be accessible from a web browser. Depending on your Apache configuration, however, and whether or not you removed the ServerAlias directive in the Configuring loopback HTTP connections section, you may have to enter your fully-qualified domain name in your web browser instead of just “localhost.” Try it and see! The default username and password are both “admin.”

At this point, you will have a basic installation of OpenProject. For additional features and alternative installation options, please see the sections below. If you need to stop OpenProject for any reason, you will probably want to stop all its dependencies too:

# systemctl stop openproject.socket
# systemctl stop openproject.service
# systemctl stop openproject-background-jobs.service
# systemctl stop apache2

SSL/TLS with OpenProject

Transport Layer Security ensures that confidential information such as passwords does not get leaked as it travels from a user's web browser to your server. Typically, TLS is terminated externally from OpenProject with Apache or another reverse proxy.

There are many ways to set up TLS encryption with Apache and you are encouraged to consult reputable tutorials and the official documentation for details. Whichever method you choose, there are two extra steps specific to OpenProject:

  1. Enable mod_headers: # a2enmod headers
  2. In your Apache virtual host configuration file that responds to HTTP requests over TLS (a.k.a. HTTPS), uncomment the line that reads RequestHeader set X-Forwarded-Proto https. Since Apache typically forwards requests to OpenProject over a local, unencrypted HTTP connection, this header is needed to inform OpenProject that the user is accessing the website over HTTPS. In turn, OpenProject will set HSTS (HTTP Strict Transport Security) headers to ensure that the user's web browser always accesses the website over HTTPS.

Let's Encrypt/ACME Auto-configuration with Certbot and Apache

Let's Encrypt provides free domain-validation certificates automatically via the ACME protocol and makes it easy to set up TLS on your website. The Certbot program is an ACME client that can automate provisioning and renewing your TLS certificates. To use it with OpenProject, install the python3-certbot and python3-certbot-apache packages, then enter a superuser shell:

# sudo su

Certbot works with your Apache configuration files, so if you are using the configuration file provided with the openproject-apache2 package, you will need to load the environment variables first:

# set -o allexport
# source /etc/sysconfig/openproject-sys-api-protection

Additionally, if you are serving repositories:

# source /etc/sysconfig/openproject-repoauth
# source /etc/sysconfig/openproject-repoman

Now, you can request a certificate and have it automatically set up.

# certbot --apache

Lastly, you will likely want to automate the renewal of your certificate. To do this, install the certbot-systemd-timer. As before, you will need to make sure the necessary environment variables are loaded prior to running Certbot. Create a systemd drop-in override to load the environment variables:

# systemctl edit certbot-renew.service

Add the following lines:

[Service]
EnvironmentFile=/etc/sysconfig/openproject-sys-api-protection

# Only include these lines if you have installed
# the openproject-scm-perl-scripts package.
EnvironmentFile=/etc/sysconfig/openproject-repoauth
EnvironmentFile=/etc/sysconfig/openproject-repoman

Reload the systemd units so that your changes take effect:

# systemctl daemon-reload

Enable automatic renewal:

# systemctl enable --now certbot-renew.timer

For more advanced topics, such as OCSP stapling, refer to the official documentation for Apache's mod_ssl.

HTTPS Between Puma and the Reverse Proxy

Puma also supports TLS. The main use case for this would be in a datacenter with many (virtual) servers running OpenProject and just one or two central reverse proxies (and for some reason an untrustworthy network connection between them). The path to the TLS secret key is passed as part of the OPENPROJECT_PUMA_BIND_URL environment variable. Read the documentation for that option in the YaST Sysconfig editor for more details.


Remote database server (PostgreSQL)

Sometimes, it is useful to host the OpenProject's database on a separate server from the web app. This could be the case if your datacenter or hosting provider offers a dedicated database server that will relieve the extra load from your web server. By default, OpenProject expects a local installation of PostgreSQL accessible via a Unix domain socket. (This is why postgresql-server is a “recommended” package.) Securing a database for non-local access is out of the scope of this article, but using such a database from the perspective of OpenProject is quite easy:

  1. Create a database user account on the remote PostgreSQL server. Generate a long, random password for this account. (For these instructions, we'll assume the username is “db_user” and the password is “db_pass.”
  2. Create a database on the remote PostgreSQL server and grant the user account you just created full permissions on that database. (For these instructions, we'll assume the database is called “openproject_db.”
  3. Open the YaST Sysconfig Editor on the machine hosting the web app. Under the Network/OpenProject/Database section, set the following variables:
    • OPENPROJECT_DATABASE_URL. This should contain the hostname and port number of your remote database server. For example, if your database was hosted at db.example.com, port 5433, you would set this variable to postgresql://db.example.com:5433. You can find more documentation on this format here in the section called “Connection URIs.” However, do not include database credentials or the database name in this variable—those options are configured separately. Since this URL is passed on the command line during OpenProject start-up, putting credentials in this variable would make them visible to other users on the system.
    • OPENPROJECT_DATABASE_NAME. This should be the name that was picked when creating the user and database in step 2 (e.g. “openproject_db”).
    • OPENPROJECT_DATABASE_USERNAME. This should be set to the username of the account that was created on the remote database server in step 1 (e.g. “db_user”).
    • OPENPROJECT_DATABASE_PASSWORD. This should be set to the password of the account that was created on the remote database server in step 1 (e.g. “db_pass”).

Repository Configuration

OpenProject includes built-in support for working with Subversion and Git version control system repositories. Specifically, it performs:

  • Management: creation and deletion of repositories from the web interface.
  • Authentication and Authorization: ensuring only the correct users can read and write to repositories.

Management can be performed either:

  1. Directly by the OpenProject web app via a background job; or
  2. In a separate Perl script embedded in Apache via mod_perl

Managing repositories directly (option 1) works well when you are hosting repositories on the same machine as the OpenProject web app, but using the Perl script (option 2) is required if you would like to host repositories on a separate machine from the web app. The Perl script will work in either situation (provided that loopback HTTP connections are set up properly) but managing repositories directly allows OpenProject to provide extra information about disk usage.

In either case, repositories must be served over HTTP/HTTPS with Apache, using a mod_perl script. The benefit of this is that repository authentication is implement in a generic way—the Perl script simply hooks into Apache's HTTP Basic Authentication requests and authorizes or denies the request. Both Subversion and Git client programs work the same way in this respect, which makes the entire process much easier.

Follow the steps below to set up repositories for your OpenProject installation.

Icon-warning.png
Warning: These instructions assume you are using the Apache virtual host configuration files provided with the OpenProject packages. If you choose to write you own Apache configuration file, please use /etc/apache2/vhosts.d/openproject-repositories-standalone.template and /etc/apache2/conf.d/openproject-repositories.snippet as examples. The files are well-commented and should be fairly easy to understand, although certain parts (such as the IfDefine directives) would not be necessary in a custom configuration file.

Setting up the machine that will host repositories

First, install the openproject-scm-perl-scripts package if it is not already installed. If you are hosting repositories and the web app on the same server, you will likely already have it installed since it is listed as a recommended package by the openproject package.

If you installed the package with the --no-recommends flag to zypper, or deselected optional packages when installing it in YaST, double check that you have the necessary packages installed:
  • If you plan to host Subversion repositories, make sure the subversion-server package is installed.
  • If you plan to host Git repositories, make sure the git-core package is installed.

Enable Apache Modules

As explained above, mod_perl is required for all repository hosting configurations with OpenProject because it is used by the repository authentication script. Enable it now on the server that is hosting repositories (which may be the same server that is hosting the web app):

# a2enmod perl

If you are hosting Subversion repositories with OpenProject, enable the dav and dav_svn modules. Together, these two modules provide access for Subversion client programs directly within Apache:

# a2enmod dav
# a2enmod dav_svn

If you are hosting Git repositories with OpenProject, you will need to choose from two different modules based on your Apache configuration. This is because unlike Subversion, Git repositories require an external CGI program to be executed by Apache. Apache provides two different modules to provide CGI support, so you will need to select the correct module to use based on the MPM (multi-processing module) that Apache is configured to use.

The three commonly-used Apache MPMs are Prefork, Worker, and Event. The Prefork MPM is typically installed by default, but the Event and Worker MPMs can be easily installed in separate packages. When the Apache server is started, the openSUSE startup script will try to use the Event, Worker, and Prefork MPMs in that order. The first available MPM will be used. However, this behavior can be overridden by the setting APACHE_MPM in the YaST Sysconfig Editor. Check that setting and your installed packages to determine which MPM your copy of Apache is using.

If you are using the traditional Prefork MPM, use mod_cgi, which executes CGI programs directly from the main server process:

# a2enmod cgi

If you are using a higher-performance, threaded MPM such as Worker or Event, use mod_cgid, which executes CGI programs from a separate daemon process:

# a2enmod cgid

Enable repository access in your Apache configuration

If you are hosting repositories and the OpenProject web app on the same machine and using Apache (the default setup), no extra work is required. The Apache virtual host configuration file for the web app that you edited earlier will automatically enable repository access when it is available through an IncludeOptional directive.

If you are hosting repositories and the web app on separate machines, an Apache virtual host template is provided for this purpose. Copy it over and modify it as needed (in particular, make sure that the ServerName directive is set correctly):

# cp /etc/apache2/vhosts.d/openproject-repositories-standalone.template /etc/apache2/vhosts.d/openproject-repositories.conf

Configuring communication between repositories and the web app

The repository management Perl script provides a web API to the OpenProject web app; and the OpenProject web app provides a web API (the “Sys API”) to the repository authentication Perl script. You will need to make sure that both components know how to communicate.

First, point the repository authentication Perl script to your OpenProject web app so that it can verify user credentials. Open the YaST Sysconfig Editor on the machine that is hosting your repositories. Find the option OPENPROJECT_REPOAUTH_APP_URL and set it to the URL of your OpenProject web app; e.g. https://openproject.example.com.

Next, point the the web app to the repository management Perl script. Since it is possible to host Git and Subversion repositories on separate servers, you will need to set this option in two places if you are providing both types of repositories. On the machine that is hosting the web app, open the YaST Sysconfig Editor. Find the option OPENPROJECT_SUBVERSION_MGMT_URL and set it to the URL of your repository server; e.g. https://scm.example.com/repoman-subversion. Find the option OPENPROJECT_GIT_MGMT_URL and set it to e.g. https://scm.example.com/repoman-git.

The locations /repoman-subversion and /repoman-git are hardcoded in /etc/apache2/conf.d/openproject-repositories.snippet. This file is included by the virtual host templates discussed in this article and provides some convenient features, but you are not required to use it. If your repositories are hosted on the same machine as the web app, you can also have OpenProject manage them directly by setting the *_MGMT_URL options to file paths. The recommended default path is provided in the drop-down menu in the Sysconfig Editor.

Generating and setting API tokens

If you are hosting the web app on the same machine as your repositories, you can skip this step. API tokens are automatically generated and set the first time you start up OpenProject.

In order to ensure that all repository creation and deletion commands are issued by the OpenProject web app and not by an attacker, the repository management Perl script requires an API token (essentially just a long, random password). Generate a secure, random password and copy it to the OPENPROJECT_REPOMAN_TOKEN setting in the YaST Sysconfig Editor on the machine that is hosting the repositories. Then, on the machine that is hosting the web app, open the YaST Sysconfig Editor and set OPENPROJECT_SUBVERSION_REPOMAN_TOKEN and/or OPENPROJECT_GIT_REPOMAN_TOKEN to the same password (depending on which type of repository, or both, the repository server will be hosting).

Likewise, the OpenProject web app requires an API token to ensure that requests to the OpenProject Sys API are legitimate. The OpenProject Sys API is used by the repository authentication Perl script to verify user credentials and control access to repositories based on user account roles in the web app. This token will be generated the first time you start the OpenProject web app. On the machine that is hosting the web app, open the YaST Sysconfig Editor, find the setting called OPENPROJECT_SYS_API_KEY, and make a note of the value. Then, on the machine that is hosting the repositories, open the YaST Sysconfig Editor, find the OPENPROJECT_REPOAUTH_SYS_API_KEY setting, and fill in the value that you wrote down.

Configuring mod_authz_host for repositories

If you are hosting the web app on the same machine as your repositories, you can skip this step. By default, only local (loopback) connections to the Sys API and repository management script are allowed, which is secure and works well as long as you have your /etc/hosts file set up correctly.

The Apache configuration files provided with OpenProject use mod_authz_host to provide an extra layer of security on top of the API tokens configured above. By default, Apache will only allow connections from the loopback IP addresses 127.0.0.1 (IPv4) and ::1 (IPv6) to access the OpenProject Sys API or the repository management script. This works well if you are hosting the repositories on the same machine as the web app, but if you are hosting them separately you will need to change this in the YaST Sysconfig Editor:

  • Set both OPENPROJECT_REPOMAN_HOST_AUTHZ_TYPE and OPENPROJECT_SYS_API_HOST_AUTHZ_TYPE to “forward-dns” on the repository-hosting machine and the web app-hosting machine, respectively.
  • On the repository-hosting machine, set OPENPROJECT_REPOMAN_HOST_AUTHZ_LIST to the host name of your OpenProject web app server (e.g. openproject.example.com)
  • On the web app-hosting machine, set OPENPROJECT_SYS_API_HOST_AUTHZ_LIST to the host name of your OpenProject repository server (e.g. scm.example.com)

These options are passed directly to Apache's Require directive. See the documentation for mod_authz_host for more information and alternative configurations (such as IP-based allowlisting and reverse-DNS lookups).

Setting the URL for checkout instructions in the web app

Now, log into the OpenProject web app as the admin user, and in the system settings, enable checkout instructions. Refer to the table below for the base URL to use. This table assumes that the URL paths are the ones used in the repository configuration snippet shipped with the openproject-scm-perl-scripts package. Change both the domain name and protocol (HTTP/HTTPS) to match your configuration.

Version Control System
Subversion Git
Repository hosting Shared with web app https://openproject.example.com/svn/ https://openproject.example.com/git/
Separate https://scm.example.com/svn/ https://scm.example.com/git/

Trying out repositories

Now, restart both Apache (on the machine hosting repositories) and OpenProject (on the machine hosting the web app) if you have not already done so:

# systemctl restart openproject.service
# systemctl restart openproject-background-jobs.service
# systemctl restart apache2.service

In the web app, add a managed repository to a project and attempt to check it out with a Subversion or Git client using the checkout URL shown at the top of the repository page. Make sure you use an account with read-write privileges to the repository. Then, make a new commit in the revision control system (and push the commit, if using Git). If everything worked, you have just successfully set up repositories with OpenProject!

Troubleshooting

Although repositories involve a number of different pieces of software, you will most likely find Apache the most useful piece for debugging. First, make sure you can access the repository management script at the locations you set. For example, visit http://scm.example.com/repoman-git with your web browser. If you get some JSON code saying “Request invalid” everything is working. If you get a 403 Forbidden error, you most likely need to adjust your configuration for mod_authz_host. If you get a 500 error, it may include a useful message from the Apache configuration file for repositories that is shipped with the package.

If you are still running into issues, the Apache error log will be the most useful option. Set the Apache log level to “debug” and see if you can find anything helpful in the error log.

Memcached

TODO


Alternative reverse proxies

TODO. Should not be very difficult to do.


Limitations

This section discusses some of the technical details of how these packages are built and possible concerns for a administrator who wants to install OpenProject.

  • These packages require OpenProject to be located at the web server root—i.e. at openproject.example.com, not example.com/openproject. This is because certain static assets (JavaScript and CSS files) shipped with OpenProject include absolute paths that are set when they are compiled and compressed when the packages are built. Theoretically, the assets could be compiled with RAILS_RELATIVE_URL_ROOT=___URL_ROOT___ and then replaced with Apache's mod_substitute.
  • Only the plugins bundled with OpenProject (in the modules folder) are packaged at this time.
  • The OpenProject configuration files provided with this package (configuration.yml, database.yml, and secrets.yml, located in /usr/lib/openproject/config) are not intended for direct editing. Instead, they serve as as shims for loading options via environment variables. All low-level configuration should be done by editing the files in /etc/sysconfig or by using the YaST Sysconfig Editor.
  • Certain secrets are also stored in the Sysconfig files for more convenient configuration. The files are read-protected by default, but the environment variables could leak into external programs if those programs were somehow executed by OpenProject very early in the startup process (before the YAML configuration file is loaded). The YAML/ERB configuration file shipped in this package retrieves these secrets through Ruby's ENV.delete function which helps prevent them from leaking into the environment of external programs that OpenProject uses, such as catdoc, xls2csv, or tesseract for document conversion. The secrets are:
    • The database password (if the database server is not on the same machine as OpenProject)
    • The secret key base (used for generating secure session tokens)
    • The Sys API key (used to check credentials for the repositories)
    • The repository manager token(s).
  • Additionally, copies of the Sys API key and the repository manager token are stored in separate Sysconfig files for use by the Perl scripts that manage the repositories and handle user authentication (since these scripts can be installed separately from the OpenProject web app). These environment variables are passed to Apache via a systemd “drop-in” configuration file in /usr/lib/systemd/system/apache2.service.d. They are then substituted in /etc/apache2/conf.d/openproject-repositories.snippet. Apache will not pass these secrets to CGI scripts unless a PassEnv directive is used, so this is expected to be safe. Furthermore, in the default configuration provided with this package, Apache will only allow local requests to the repository manager and the Sys API.