Commit 4663b851 authored by Konrad Mohrfeldt's avatar Konrad Mohrfeldt

restructure and improve documentation

* NGINX config is includable and will be installed to
* The example NGINX config is basically an include to snippets now.
* Remove sparely maintained production setting examples in
  docs/deployment/ and debian/
  and use the one in grouprise/ instead.
* translate all documentation into english and rewrite, complement,
  and extend basically everything
parent 42b502ad
Pipeline #1714 passed with stage
in 2 minutes and 35 seconds
debian/grouprise.uwsgi.ini => /etc/uwsgi/apps-available/grouprise.ini
debian/ => /etc/grouprise/
grouprise/ => /etc/grouprise/
debian/nginx-app-snippet.conf => /etc/nginx/snippets/grouprise.conf
debian/stadtctl => /usr/bin/stadtctl
debian/README.backups => /var/backups/grouprise/README
debian/tmp/usr/share/grouprise/stadt /usr/share/grouprise/grouprise/
# this is the local grouprise configuration
# you may override any options that grouprise provides in its default file.
# this file is imported once the default was loaded
from stadt.settings.default import * # noqa: F401, F403
# ALLOWED_HOSTS = ['', 'localhost']
# ADMINS = [
# ('Admins', ''),
# ]
# set debug mode to false
DEBUG = False
# increase session cookie time to 1 year
SESSION_COOKIE_AGE = 60 * 60 * 24 * 365
error_page 503 = @maintenance;
charset UTF-8;
set $grouprise_expiration_infinite "public, max-age=31536000, immutable";
set $grouprise_expiration_recheck "public, no-cache";
location / {
uwsgi_pass unix:/var/run/uwsgi/app/grouprise/socket;
include uwsgi_params;
uwsgi_intercept_errors on;
location /stadt/media/ {
alias /var/lib/grouprise/media/;
location /stadt/media/CACHE/ {
add_header Cache-Control $grouprise_expiration_infinite;
location /stadt/static/ {
alias /usr/share/grouprise/static/;
add_header Cache-Control $grouprise_expiration_recheck;
location ~* "stadt/.+\.(?:[0-9a-f]{8,32})\.(?:[0-9a-z]+)$" {
# matches files like foo.ab290fe4.js
add_header Cache-Control $grouprise_expiration_infinite;
location ~* "stadt/(?:[0-9a-f]{8,32})\.(?:[0-9a-z]+)$" {
# matches files like ab290fe4.js
add_header Cache-Control $grouprise_expiration_infinite;
location @maintenance {
root /usr/share/grouprise/offline-website;
try_files /index.html =503;
error_page 503 = @maintenance;
charset UTF-8;
server {
server_name YOUR_HOST_NAME;
location / {
uwsgi_pass unix:/var/run/uwsgi/app/grouprise/socket;
include uwsgi_params;
uwsgi_intercept_errors on;
location /stadt/media/ {
alias /var/lib/grouprise/media/;
location /stadt/media/CACHE/ {
add_header Cache-Control "public, max-age=31536000, immutable";
location /stadt/static/ {
alias /usr/share/grouprise/static/;
location ~* stadt/.+\.(woff|woff2|eot|svg|ttf|otf|jpg|jpeg|png|webp|ico|js|css)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
location @maintenance {
root /usr/share/grouprise/offline-website;
try_files /index.html =503;
include 'snippets/grouprise.conf';
# grouprise Deployment (Version 2.X.X)
Idealerweise kannst du grouprise via deb-Paket installieren. Falls das nicht geht, hilft dir die folgende Anleitung.
## Abhängigkeiten installieren
Folgende Software wird benötigt:
* `python3`
* `pip`
* `virtualenv`
* `nodejs`
Ein passendes DBMS, wir empfehlen `postgresql` mit Python-Bindings (`python3-psycopg2`).
Außerdem verwenden wir in dieser Anleitung eine Konfiguration mit uWSGI und NGINX:
* `uwsgi`
* `uwsgi-plugin-python3`
* `nginx`
Für einige Funktionen von grouprise wird weitere Software benötigt:
* `python3-xapian` (für die Suchfunktion)
* `redis-server` (für asynchronen Nachrichtenversand)
## Quelltext installieren
Das aktuelle stabile Release findest du unter [](
Kopiere den Quelltext in ein passendes Verzeichnis deiner Wahl, wir verwenden hier `/usr/local/share/grouprise`.
## Virtualenv und Assets installieren
Die folgenden Zeilen verändern ausschließlich Dateien im grouprise-Verzeichnis.
cd /usr/local/share/grouprise
make virtualenv_create
. build/venv/bin/activate
## Konfigurationsdatei installieren
Kopiere die [Beispieldatei]( nach `/etc/grouprise/`. Passe die Einstellungen an.
Falls du PostgreSQL verwendest, helfen dir die folgenden Zeilen beim Einrichten der Datenbank:
CREATE USER grouprise WITH PASSWORD 'xxxxx';
(Dafür muss das Locale `de_DE.UTF8` für PostgreSQL installiert sein.)
Nun kannst du einen Link setzen, damit grouprise die Konfiguration findet und die Datenbank initialisieren:
cd /usr/local/share/grouprise
ln -s /etc/grouprise/ stadt/settings/
python migrate
Anschließend kannst du grouprise zum ersten Mal ausprobieren (``):
python runserver
(Wenn du in den Einstellungen `DEBUG = True` setzt, sieht die Seite auch hübsch aus. Vergiss nicht, die Einstellung zurückzusetzen!)
## uWSGI und NGINX einrichten
* install NGINX and uWSGI (being recommendations of the grouprise package): `apt install nginx uwsgi uwsgi-plugin-python3`
* enable the uWSGI service: `ln -s ../apps-available/grouprise.ini /etc/uwsgi/apps-enabled/`
* start uWSGI: `service uwsgi start`
* copy the NGINX site example configuration: `cp /usr/share/doc/grouprise/examples/nginx.conf /etc/nginx/sites-available/grouprise`
* set a suitable `server_name`: `edit /etc/nginx/sites-available/grouprise`
* or remove the `default` NGINX site (if it is not in use) in order to let the `grouprise` site be picked irrespective of the requested hostname
* enable the site: `ln -s ../sites-available/grouprise /etc/nginx/sites-enabled/`
* restart NGINX: `service nginx restart`
* visit the fresh grouprise instance: `http://localhost/` (or use a suitable hostname)
## Weitere Dienste einrichten
Für einige Funktionen werden weitere Dienste benötigt. Anleitung folgt.
# grouprise Configuration
This guide describes which parts of *grouprise* are configurable and
how they can be configured. It assumes that you’ve already installed
*grouprise* on the target host either via our
[deb repository](./ or
## Quick Steps
If you just want to get a working setup fast follow these steps:
1. Copy the `/etc/grouprise/` file to `/etc/grouprise/`.
2. Define the variables outlined in the settings file header. At the very least
these are `SECRET_KEY`, `ADMINS`, and `ALLOWED_HOSTS`.
You should also consider to define the `DATABASES` variable as described in the
[Django documentation](
because switching the database at a later point can be a fairly complicated
and error-prone process. See the [section on database configuration](#database-configuration)
for more detailed information.
3. Initialize the database by running `stadtctl migrate`.
4. Symlink the `/etc/uwsgi/apps-available/grouprise.ini` file to
5. Copy the `/usr/share/doc/grouprise/examples/nginx.conf` file to
`/etc/nginx/sites-available/grouprise`, adapt the server name to your liking
and symlink the file to `/etc/nginx/sites-enabled/grouprise`.
6. Restart the uWSGI and NGINX services with `service uwsgi restart` and
`service nginx restart`.
7. Visit the hostname defined in 5.
## Database Configuration
We recommend PostgreSQL as DBMS, but Django – the underlying web-framework of *grouprise* -
supports [many other options](
As migrating data from one DBMS to the other is often difficult and error-prone you
should avoid it whenever possible. Make your decision and stick with it :).
We explicitly **DO NOT** recommend to use SQLite in production.
If you decide on using PostgreSQL you can execute the following lines as
`postgres` user after starting the `psql` SQL shell. If the `postgres` user
is not available on your system you should install the `postgresql` package.
In this example we use the `de_DE` locale which should be activated beforehand
by running `dpkg-reconfigure locales`.
After that you can add the following lines to your `/etc/grouprise/`:
'default': {
'ENGINE': 'django.db.backends.postgresql',
'HOST': 'localhost',
'NAME': 'grouprise',
'USER': 'grouprise',
If this is the first time you’ve configured the database now is the time
to run `stadtctl migrate` to initialize it. This will create the SQL schema
that grouprise needs in order to operate.
## Application Configuration
Application settings are managed in the `/etc/grouprise/` file, which does
not exist by default. Create it by copying the `/etc/grouprise/` file.
TODO: add documentation for the various grouprise settings.
## WSGI-Application and Web-Server Configuration
Even though *grouprise* should run with any WSGI application server
and/or web server, uWSGI and NGINX are the options that we use ourselves
and are familiar with. This is the reason why we ship preconfigured uWSGI
and NGINX configuration files as part of the `grouprise` deb package.
Note: If you have experience with other WSGI application or web servers
and plan on using them with *grouprise* in a production environment,
feel free to submit a pull/merge request for documentation. We’ll gladly
add it and will try to get rid of any stumbling blocks that may interfere
with such a setup.
## uWSGI
uWSGI is an extensible WSGI server. We ship a default config as part of our
deb package and is located in `/etc/uwsgi/apps-available`. You can activate
it by creating a symlink to the `/etc/uwsgi/apps-enabled` directory.
If you want to use your own uWSGI configuration, but want to keep the
integration with the package, make sure the filename of the configuration
in `/etc/uwsgi/apps-enabled` is `grouprise.ini`.
In case you just want to override the number of workers and/or threads you
environment variables in `/etc/default/uwsgi` and set them to any number
that fits your needs.
Once you’ve symlinked the *grouprise* config or created your own, you
can restart uWSGI with `service uwsgi reload`. Note that setting or
changing the aforementioned worker and thread environment variables will
likely require a `restart` instead of a `reload`.
If you plan on using NGINX install it now with `apt install nginx`.
We ship an includable default configuration as part of our deb package, which
is located in `/etc/nginx/snippets/grouprise.conf` and contains rules
for serving the app via uWSGI, static file handling for media and assets
files, sensible cache settings, and a maintenance fallback site.
Copy the example server configuration from `/usr/share/doc/grouprise/examples/nginx.conf` to
`/etc/nginx/sites-available/grouprise` and modify it to your needs. The
`include snippets/grouprise.conf` line to will import the default configuration.
After you’re done reload NGINX with `service nginx reload`.
# grouprise Deployment
This guide helps you to install *grouprise* on Debian or one of its derivates like Ubuntu.
If you don’t want to use a Debian-based system or wish to install *grouprise* by hand see
the [separate instructions for manual deployments](./
We would also like to support Docker deployments, but have not enough knowledge in that
specific domain and some reservations regarding security. We will however gladly accept
any documentation on this matter, so feel free to open a merge/pull request.
## Installation with apt
You can install *grouprise* from our deb repository.
Execute the following lines as root on the server host:
# This installs the https-transport. Debian only supports http-based repositories by default.
apt update && apt install apt-transport-https
# This registers our gpg key, so apt won’t reject our packages as untrusted.
wget -qO- | apt-key add -
# This adds our deb repository to the list of repositories in your system.
echo "deb unstable main" >/etc/apt/sources.list.d/grouprise.list
# Update the package index and install grouprise
apt update && apt install grouprise
## Configuration
This is outlined in the separate [configuration documentation](./
Follow the [Quick Steps](./ if you just want to
get started fast.
## Manual Installation
This is outlined in the separate [documentation on manual deployments](./
# Manual Deployment
This guide describes the manual installation of *grouprise* using the sources.
Filesystem paths and some commands may be Debian specific but should be
easily adaptable to other Linux or BSD Distributions.
## Download the Sources
The latest stable release is available on
[](, which
you can download as a zip or tar file (they all contain the same content).
Extract the file and place the content of the extracted directory
in `/usr/local/share/grouprise`.
## Install System Dependencies
Dependencies mentioned in this section refer to Debian package names, which
can be installed with `apt`. If you’re installating *grouprise* on an OS
other than Debian or one of its many derivates like Ubuntu, you have to find
the appropriate equivalents for your system’s package manager. A good starting
point may be the Debian [package search](
that offers information about each package’s sources and website.
The following software is required when installing from sources:
* `make`
* `nodejs`
* `npm`
* `pip`
* `python3`
* `virtualenv`
* `wget`
We recommend a proper DBMS for running *grouprise*. Our recommendation is PostgreSQL, but
[any other option supported by Django](
should be fine too. Install the following packages for our recommendation:
* `postgresql`
* `python3-psycopg2`
Apart from that you’ll need an application server supporting the WSGI protocol
and a web server. Our recommendations are uWSGI and NGINX. We ship includable
configurations for both, so that any custom configuration is kept to a minimum.
Install the following packages for our recommendation:
* `nginx`
* `uwsgi`
* `uwsgi-plugin-python3`
## Additional System Dependencies and Functionality
Even though most of the application dependencies can be handled via the
virtualenv created in the section below, we recommend that you install
some of them with your systems package manager. Refer to the
[control](/debian/control) file for a list of packages. Everything starting
with `python3-` can and should be installed directly from the operating system.
This is not necessary but it is always a good idea to reduce the number of
manually installed and managed dependencies to increase overall security. Your
OS usually does a much better job at keeping dependencies up to date than a
single person ever could.
Some functionality requires additional packages. Those are:
* `python3-xapian` (for search)
* `redis-server` (for asynchronous mail-processing)
## Prepare Virtualenv and static Files
Unfortunately *grouprise* requires some libraries that are not available as
packages in Debian (and most likely other distributions). A virtualenv is a
simple way to install Python libraries without polluting directories that are
usually under control of the operating system and its package manager.
*grouprise* uses *Make* to ease these tasks for you. In order to create the
virtualenv and all other files necessary to run a proper *grouprise* instance
you’ll need to run the default make target in the directory *grouprise* was
installed in. If you’ve followed the defaults in the first step this should
come down too a few commands:
cd /usr/local/share/grouprise
make virtualenv_create
. build/venv/bin/activate
## Configuration
The what, how and why of *grouprise* configuration is outlined in the
[configuration documentation](./, but you’ll need to create
a few files and symlinks to make it work.
1. Copy the `/usr/local/share/grouprise/grouprise/`
file to `/usr/local/share/grouprise/grouprise/`. All application
settings should be made there instead of `/etc/grouprise/`.
2. Copy `debian/grouprise.uwsgi.ini` to `/etc/uwsgi/apps-available/grouprise.ini`.
Adapt the settings to your needs and symlink it to the `/etc/uwsgi/apps-enabled`
You may also want to create a separate user and group for running grouprise and
set the corresponding `uid` setting in the uWSGI configuration.
# grouprise settings file
# see
import os
import subprocess
from stadt.settings.default import *
from grouprise.core.assets import add_javascript_reference, add_javascript_inline, add_csp_directive, add_meta
# see
ALLOWED_HOSTS = ['', 'localhost']
# dies wird von nginx gesetzt
'default': {
'ENGINE': 'django.db.backends.postgresql',
'HOST': 'localhost',
'NAME': 'grouprise',
'USER': 'grouprise',
'PASSWORD': 'xxxxx',
('Admins', ''),
DEFAULT_FROM_EMAIL = 'noreply@localhost'
FROM_EMAIL_WITH_SLUG = 'noreply+{slug}@localhost'
ANSWERABLE_FROM_EMAIL = 'noreply@localhost'
DEFAULT_REPLY_TO_EMAIL = 'reply+{reply_key}@localhost'
STADTGESTALTEN_BOT_EMAIL = 'grouprise-bot@localhost'
SERVER_EMAIL = 'grouprise <noreply@localhost>'
GROUPRISE_POSTMASTER_EMAIL = 'postmaster@localhost'
# ENTITY_SLUG_BLACKLIST = [ 'all', 'alle', 'antwort', 'crew', 'facebook', 'gbr', 'info', 'kontakt', 'mail', 'noreply', 'postmaster', 'presse', 'reply', 'stadt', 'unknown', 'webmaster', 'www']
# set debug mode to false
DEBUG = False
# increase session cookie time to 1 year
SESSION_COOKIE_AGE = 60 * 60 * 24 * 365
'your claim 1',
'your claim 2',
# ...
# HAYSTACK_CONNECTIONS['default']['PATH'] = os.path.join(DATA_DIR, 'xapian_index')
from grouprise.common_settings import *
# Set this to a long (at least 50 characters) and
# random string containing letters, digits and special characters.
# This should contain the hosts under which you serve
# the grouprise application. Usually it should not contain
# more than one string.
# If you serve your grouprise instance under the domain
#, this list should contain ''.
......@@ -28,12 +35,12 @@ GROUPRISE = {
'CLAIMS': [],
# special users and groups
# email settings
'DEFAULT_DISTINCT_FROM_EMAIL': 'noreply+{slug}@localhost',
'DEFAULT_REPLY_TO_EMAIL': 'reply+{reply_key}@localhost',
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment