Repository restructure

- moved all server related things into the folder `server`, so this
configuration is parallel to the client.
- All main "services" are now folders in the root directory
- Added Dockerfiles to each service (currently server and client)
- Added a docker compose configuration to start everything together.
Currently there are heavy dependencies into https://github.com/OpenSlides/openslides-docker-compose
- Resturctured the .gitignore. If someone needs something excluded,
please add it to the right section.
- Added initial build setup with Docker and docker-compose.
- removed setup.py. We won't deliver OpenSlides via pip anymore.
This commit is contained in:
FinnStutzenstein 2020-06-18 15:22:38 +02:00 committed by Finn Stutzenstein
parent 2c85bb28f1
commit 2bcab5d098
No known key found for this signature in database
GPG Key ID: 9042F605C6324654
410 changed files with 1071 additions and 536 deletions

108
.gitignore vendored
View File

@ -1,63 +1,9 @@
# General ## General
*.pyc *.pyc
*.swp *.swp
*.swo *.swo
*.log *.log
*~ *~
# Virtual Environment
.virtualenv*/*
.venv/*
# Javascript tools and libraries
node_modules/*
bower_components/*
# OS4-Submodules
/openslides-*
# OS3+
/server/
/haproxy/
# Local user data (settings, database, media, search index, static files)
personal_data/*
openslides/static/*
collected-static/*
# Package building/IDE
docs/_build/*
*.egg-info
build/*
dist/*
debug/*
.DS_Store
.idea
*.code-workspace
# Unit test and coverage reports
.coverage
tests/file/*
tests/db.sqlite3.test
.pytest_cache
# Plugin development
openslides_*
# Mypy cache for typechecking
.mypy_cache
# OpenSlides 3 Client
# compiled output
client/dist
client/tmp
client/out-tsc
client/documentation
# dependencies
client/node_modules
# IDEs and editors # IDEs and editors
/.idea /.idea
.project .project
@ -66,13 +12,50 @@ client/node_modules
*.launch *.launch
.settings/ .settings/
*.sublime-workspace *.sublime-workspace
# IDE - VSCode
.vscode/* .vscode/*
*.code-workspace
# System Files
.DS_Store
Thumbs.db
# Virtual Environment
.virtualenv*/*
.venv/*
# misc ## Compatibility
# OS4-Submodules
/openslides-*/
# Plugin development
openslides_*
## Server
# Local user data (settings, database, media, search index, static files)
personal_data/*
server/personal_data/*
server/openslides/static/*
# Unit test and coverage reports
.coverage
server/tests/file/*
server/tests/db.sqlite3.test
.pytest_cache
# Package building
*.egg-info
# Mypy cache for typechecking
.mypy_cache
## OpenSlides 3 Client
# Javascript tools and libraries
**/node_modules/*
**/bower_components/*
# compiled output
client/dist
client/static
client/tmp
client/out-tsc
# docs
client/documentation
Compodoc Compodoc
Compodocmodules Compodocmodules
# build artifacts
client/.sass-cache client/.sass-cache
client/connect.lock client/connect.lock
client/coverage client/coverage
@ -85,8 +68,9 @@ client/yarn.lock
package-lock.json package-lock.json
client/package-lock.json client/package-lock.json
cypress.json cypress.json
*-version.txt
# System Files ## Deployment
client/.DS_Store # Docker build artifacts
client/Thumbs.db *-version.txt
# secrets
docker/secrets/*.env

View File

@ -1,12 +1,12 @@
dist: xenial dist: xenial
sudo: true os: linux
cache: cache:
- directories: - directories:
- $HOME/.cache/pip - $HOME/.cache/pip
- client/node_modules - client/node_modules
matrix: jobs:
include: include:
- stage: "Dependencies" - stage: "Dependencies"
name: "Installing dependencies for python" name: "Installing dependencies for python"
@ -15,11 +15,12 @@ matrix:
- "3.6" - "3.6"
cache: cache:
pip: true pip: true
install: before_install:
- python --version - python --version
- pip install --upgrade setuptools pip - cd server
- pip install --upgrade --requirement requirements/development.txt install:
- pip install --upgrade .[big_mode] - pip install --upgrade pip
- pip install --upgrade --requirement requirements.txt
- pip freeze - pip freeze
script: skip script: skip
@ -36,15 +37,11 @@ matrix:
install: install:
- npm install - npm install
script: skip script: skip
- stage: "Run tests" - stage: "Run tests"
name: "Client: Testing" name: "Client: Testing"
language: node_js language: node_js
node_js: "12.18" node_js: "12.18"
apt:
sources:
- google-chrome
packages:
- google-chrome-stable
services: services:
- xvfb - xvfb
install: install:
@ -79,36 +76,6 @@ matrix:
- cd client - cd client
- npm run build-debug - npm run build-debug
- name: "Server: Tests Python 3.6"
language: python
python:
- "3.6"
script:
- mypy openslides/ tests/
- pytest --cov --cov-fail-under=75
- name: "Server: Tests Python 3.7"
language: python
python:
- "3.7"
script:
- flake8 openslides tests
- isort --check-only --diff --recursive openslides tests
- black --check --diff --target-version py36 openslides tests
- mypy openslides/ tests/
- pytest --cov --cov-fail-under=75
- name: "Server: Tests Python 3.8"
language: python
python:
- "3.8"
script:
- flake8 openslides tests
- isort --check-only --diff --recursive openslides tests
- black --check --diff --target-version py36 openslides tests
- mypy openslides/ tests/
- pytest --cov --cov-fail-under=75
- name: "Client: Linting" - name: "Client: Linting"
language: node_js language: node_js
node_js: "12.18" node_js: "12.18"
@ -123,13 +90,51 @@ matrix:
- cd client - cd client
- npm run prettify-check - npm run prettify-check
- name: "Server: Tests Python 3.6"
language: python
python:
- "3.6"
before_install:
- cd server
script:
- mypy openslides/ tests/
- pytest --cov --cov-fail-under=75
- name: "Server: Tests Python 3.7"
language: python
python:
- "3.7"
before_install:
- cd server
script:
- flake8 openslides tests
- isort --check-only --diff --recursive openslides tests
- black --check --diff --target-version py36 openslides tests
- mypy openslides/ tests/
- pytest --cov --cov-fail-under=75
- name: "Server: Tests Python 3.8"
language: python
python:
- "3.8"
before_install:
- cd server
script:
- flake8 openslides tests
- isort --check-only --diff --recursive openslides tests
- black --check --diff --target-version py36 openslides tests
- mypy openslides/ tests/
- pytest --cov --cov-fail-under=75
- name: "Server: Tests Startup Routine Python 3.7" - name: "Server: Tests Startup Routine Python 3.7"
language: python language: python
python: python:
- "3.7" - "3.7"
before_install:
- cd server
script: script:
- set -e - set -e
- python manage.py createsettings - python manage.py createsettings
- python manage.py migrate - python manage.py migrate
- python manage.py runserver --noreload & (sleep 15 && kill $(ps aux | grep 'manage.py runserver' | head -n -1 | awk '{print $2}')) - python manage.py runserver --noreload & (sleep 20 && kill $(ps aux | grep 'manage.py runserver' | head -n -1 | awk '{print $2}'))
- set +e - set +e

View File

@ -2,12 +2,12 @@
OpenSlides Development OpenSlides Development
======================== ========================
This instruction helps you to setup a development environment for OpenSlides. This instruction helps you to setup a development environment for OpenSlides. A
simple dev setup will be configured without the need of the docker-compose
setup. There are only the server running without a cache and a sqlite database
and the client as an development server.
Installation and start of the development version
=================================================
1. Installation on GNU/Linux or Mac OS X 1. Installation on GNU/Linux or Mac OS X
---------------------------------------- ----------------------------------------
@ -37,15 +37,30 @@ Clone current master version from `OpenSlides GitHub repository
c. Setup a virtual Python environment (optional) c. Setup a virtual Python environment (optional)
'''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''''''''''''''''''''
See step 1. b. in the installation section in the `README.rst You can setup a virtual Python environment using the virtual environment
<https://github.com/OpenSlides/OpenSlides/blob/master/README.rst>`_. (venv) package for Python to install OpenSlides as non-root user. This will
allow for encapsulated dependencies. They will be installed in the virtual
environment and not globally on your system.
Setup and activate the virtual environment::
d. Finish the server $ python3 -m venv .virtualenv
'''''''''''''''''''' $ source .virtualenv/bin/activate
You can exit the environment with::
$ deactivate
d. Server
'''''''''
Go into the server's directory::
$ cd server/
Install all required Python packages:: Install all required Python packages::
$ pip install --upgrade setuptools pip
$ pip install --requirement requirements.txt $ pip install --requirement requirements.txt
Create a settings file, run migrations and start the server:: Create a settings file, run migrations and start the server::
@ -54,41 +69,29 @@ Create a settings file, run migrations and start the server::
$ python manage.py migrate $ python manage.py migrate
$ python manage.py runserver $ python manage.py runserver
All you data (database, config, mediafiles) are stored in ``personal_data/var``.
To get help on the command line options run:: To get help on the command line options run::
$ python manage.py --help $ python manage.py --help
Later you might want to restart the server with one of the following commands. Later you might want to restart the server with one of the following commands.
To start OpenSlides with this command and to avoid opening new browser windows To run the OpenSlides server execute::
run::
$ python manage.py start --no-browser $ python manage.py runserver
When debugging something email related change the email backend to console:: When debugging something email related change the email backend to console::
$ python manage.py start --debug-email $ python manage.py runserver --debug-email
The server is available under http://localhost:8000. Especially the rest interface
might be important during development: http://localhost:8000/rest/ (The trailing
slash is important!).
e. Debugging the server e. Client
''''''''''''''''''''''' '''''''''
If you wish to have even further debugging, enable `django-extensions Go in the client's directory::
<https://django-extensions.readthedocs.io/>`_ in the ``settings.py`` by adding
``django_extensions`` to the list of ``INSTALLED_PLLUGINS``. Make sure, you
install the following packages::
$ pip install Werkzeug pyparsing pydot django-extensions
You can start the enhanced debugging-server via::
$ python manage.py runserver_plus
f. Setup and start the client
'''''''''''''''''''''''''''''
Go in the client's directory in a second command-line interface::
$ cd client/ $ cd client/
@ -97,14 +100,7 @@ Install all dependencies and start the development server::
$ npm install $ npm install
$ npm start $ npm start
Now the client is available under ``localhost:4200``. After a while, the client is available under http://localhost:4200.
If you want to provide the client statically, you can build it via::
$ npm run build
The build client files are availible from the root directory in
``openslides/static`` and can be provided via NGINX.
2. Installation on Windows 2. Installation on Windows
@ -140,12 +136,6 @@ a. Running server tests
To run some server tests see `.travis.yml To run some server tests see `.travis.yml
<https://github.com/OpenSlides/OpenSlides/blob/master/.travis.yml>`_. <https://github.com/OpenSlides/OpenSlides/blob/master/.travis.yml>`_.
You can generate an class-structure image when having `django_extensions`
enabled (see above)::
$ python manage.py graph_models -a -g -o my_project_visualized.png
b. Client tests and commands b. Client tests and commands
'''''''''''''''''''''''''''' ''''''''''''''''''''''''''''
@ -169,53 +159,23 @@ README.md using following command::
$ npm run licenses $ npm run licenses
OpenSlides in big mode 4. Notes for running OpenSlides in larger setups
====================== ------------------------------------------------
To install OpenSlides for big assemblies (in 'big mode') you have to setup some For productive setups refer to the docker-compose setup described in the main
additional components and configurations. In the 'big mode' you should use a webserver `README<https://github.com/OpenSlides/OpenSlides/blob/master/README.rst>`_.
like NGINX to serve the static and media files as proxy server in front of your OpenSlides
interface server. You should also use a database like PostgreSQL. Use Redis as channels backend,
cache backend and session engine. Finally you should use gunicorn with uvicorn as interface server.
While develpment it might be handy to use a cache and another database.
PostgreSQL is recommended and Redis necessary as a cache. Both can be set up in
the ``settings.py``. Please consider reading the `OpenSlides configuration
<https://github.com/OpenSlides/OpenSlides/blob/master/server/SETTINGS.rst>`_ page
to find out about all configurations, especially when using OpenSlides for big
assemblies.
1. Install and configure PostgreSQL and Redis If you followed the instructions and installed the pip requirements form the
--------------------------------------------- ``requirements.py`` all needed dependencies for another worker are installed.
Instead of running ``python manage.py runserver`` you can use daphne or gunicorn
Install `PostgreSQL <https://www.postgresql.org/>`_ and `Redis (the latter is used in the prod setup)::
<https://redis.io/>`_. For Ubuntu 18.04 e. g. run::
$ sudo apt-get install postgresql libpq-dev redis-server
Be sure that database and redis server is running. For Ubuntu 18.04 e. g. this
was done automatically if you used the package manager.
Then add database user and database. For Ubuntu 18.04 e. g. run::
$ sudo -u postgres createuser --pwprompt --createdb openslides
$ sudo -u postgres createdb --owner=openslides openslides
2. Change OpenSlides settings
-----------------------------
Create OpenSlides settings file if it does not exist::
$ python manage.py createsettings
Change OpenSlides settings file (usually called settings.py): Setup
`DATABASES` entry as mentioned in the settings file. Set `use_redis` to
`True`.
Populate your new database::
$ python manage.py migrate
3. Run OpenSlides
-----------------
To start Daphne run::
$ export DJANGO_SETTINGS_MODULE=settings $ export DJANGO_SETTINGS_MODULE=settings
$ export PYTHONPATH=personal_data/var/ $ export PYTHONPATH=personal_data/var/
@ -226,57 +186,3 @@ server::
$ gunicorn -w 4 -b 0.0.0.0:8000 -k uvicorn.workers.UvicornWorker openslides.asgi:application $ gunicorn -w 4 -b 0.0.0.0:8000 -k uvicorn.workers.UvicornWorker openslides.asgi:application
4. Use NGINX (optional)
-----------------------
When using NGINX as a proxy for delivering static files the performance of the
setup will increase.
This is an example ``nginx.conf`` configuration for Daphne listing on port
8000::
worker_processes 1;
events {
worker_connections 1024;
}
http {
server {
listen 80;
server_name localhost;
root $YOUR_OS_ROOT_FOLDER/openslides/static;
index index.html index.htm;
include /etc/nginx/mime.types;
client_max_body_size 100M;
gzip on;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
location / {
try_files $uri $uri/ /index.html;
}
location /apps {
proxy_pass http://localhost:8000;
}
location /media {
proxy_pass http://localhost:8000;
}
location /rest {
proxy_set_header Host $http_host;
proxy_pass http://localhost:8000;
}
location /ws {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
}

View File

@ -1,30 +0,0 @@
FROM python:3.7-slim
RUN mkdir /app
RUN apt -y update && \
apt -y upgrade && \
apt install -y libpq-dev curl wget xz-utils bzip2 git gcc gnupg2 make g++
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN apt -y install nodejs
RUN npm install -g @angular/cli@latest
RUN useradd -m openslides
RUN chown -R openslides /app
WORKDIR /app
COPY . /app
RUN rm -rf /app/.virtualenv* && \
rm -rf /app/client/node_modules
RUN chown -R openslides /app
# Installing python dependencies
RUN pip install -r requirements.txt
RUN rm -rf /var/lib/apt/lists/*
# installing client
USER openslides
RUN ng config -g cli.warnings.versionMismatch false && \
cd client && \
npm install
RUN cd client && \
npm run build && \
./node_modules/.bin/compodoc -t -p src/tsconfig.app.json -n 'OpenSlides Documentation' -d ../openslides/static/doc -e html

View File

@ -9,167 +9,62 @@ OpenSlides is a free, web based presentation and assembly system for
managing and projecting agenda, motions and elections of an assembly. See managing and projecting agenda, motions and elections of an assembly. See
https://openslides.com for more information. https://openslides.com for more information.
Installation Installation
============ ============
The OpenSlides server runs everywhere where Python is running (for example on The main deployment method is using docker and docker-compose. You just need
GNU/Linux, Mac or Windows). For the OpenSlides client a current web browser is required. both installed and no further dependencies. If you want a simpler setup or are
interesed in developing, please refer to `development instructions <https://github.com/OpenSlides/OpenSlides/blob/master/DEVELOPMENT.rst>`_.
Note: This is temporary and will be replace with nice scripts...
1. Installation on GNU/Linux or Mac OS X First, you have to clone this repository::
----------------------------------------
a. Check requirements $ git clone https://github.com/OpenSlides/OpenSlides.git
''''''''''''''''''''' $ cd OpenSlides/docker/
Make sure that you have installed `Python (>= 3.6) <https://www.python.org/>`_ You need to build the docker images for the client and server with this script::
on your system.
Additional you need build-essential packages, header files and a static $ ./build.sh
library for Python and also the pyvenv-3 binary package for python3.
E.g. run on Debian/Ubuntu:: We strongly recomment to set an initial admin password and create a second
non-admin user. Both are not strictly required (and a missing admin password will print warnings on the
startup), but if you want to have a secure setup, do::
$ sudo apt-get install build-essential python3-dev python3-venv $ cp secrets/admin.env.example secrets/admin.env
$ cp secrets/user.env.example secrets/user.env
$ vi secrets/admin.env
$ vi secrets/user.env
If the server and client are built, you can use ``docker-compose`` as usual
(except for the ``build`` method)::
b. Setup a virtual Python environment (optional) $ docker-compose up
'''''''''''''''''''''''''''''''''''''''''''''''' $ # or:
$ docker-compose up -d
$ docker-compose logs
$ # ...
$ docker-compose down
You can setup a virtual Python environment using the virtual environment OpenSlides is listening on port 8000. It can be changed in the
(venv) package for Python to install OpenSlides as non-root user. ``docker/docker-compose.yml``.
Create your OpenSlides directory and change to it:: Bugs, features and development
================================
$ mkdir OpenSlides
$ cd OpenSlides
Setup and activate the virtual environment::
$ python3 -m venv .virtualenv
$ source .virtualenv/bin/activate
$ pip install --upgrade setuptools pip
c. Install OpenSlides
'''''''''''''''''''''
To install OpenSlides just run::
$ pip install openslides
This installs the latest stable version. To install a specific (beta)
version use ``openslides==x.y``.
You can also use the package from the `OpenSlides website
<https://openslides.com/>`_. Download latest OpenSlides release as
compressed tar archive and run::
$ pip install openslides-x.y.tar.gz
This will install all required Python packages (see
``requirements/production.txt``).
d. Start OpenSlides
'''''''''''''''''''
To start OpenSlides simply run::
$ openslides
If you run this command the first time, a new database and the admin account
(Username: ``admin``, Password: ``admin``) will be created. Please change the
password after first login!
OpenSlides will start a webserver. It will also try to open the webinterface in
your default webbrowser. The server will try to listen on the local ip address
on port 8000. That means that the server will be available to everyone on your
local network (at least for commonly used network configurations).
If you use a virtual environment (see step b.), do not forget to activate
the environment before restart after you closed the terminal::
$ source .virtualenv/bin/activate
To get help on the command line options run::
$ openslides --help
You can store settings, database and other personal files in a local
subdirectory and use these files e. g. if you want to run multiple
instances of OpenSlides::
$ openslides start --local-installation
2. Installation on Windows
--------------------------
Follow the instructions above (1. Installation on GNU/Linux or Mac OS X) but care
of the following variations.
To get Python download and run the latest `Python 3.7 32-bit (x86) executable
installer <https://www.python.org/downloads/windows/>`_. Note that the 32-bit
installer is required even on a 64-bit Windows system. If you use the 64-bit
installer, step 1c of the instruction might fail unless you installed some
packages manually.
In some cases you have to install `MS Visual C++ 2015 build tools
<https://www.microsoft.com/en-us/download/details.aspx?id=48159>`_ before you
install the required python packages for OpenSlides (unfortunately Twisted
needs it).
To setup and activate the virtual environment in step 1b use::
> .virtualenv\Scripts\activate.bat
All other commands are the same as for GNU/Linux and Mac OS X.
3. Installation with Docker
---------------------------
The installation instruction for (1) and (2) described a way to use OpenSlides in a
'small mode' with max 10 concurrent clients. To install OpenSlides for big assemblies
('big mode') you have to setup some additional components and configurations.
The easiest way to run the OpenSlides 'big mode' environment (with PostgreSQL, Redis
and NGINX) with Docker Compose: use our docker compose suite. Follow the instruction in
the `openslides-docker-compose Repository <https://github.com/OpenSlides/openslides-docker-compose>`_.
To install and configure all components of our 'big mode' manually you can read the
`big-mode-instruction <https://github.com/OpenSlides/OpenSlides/blob/master/DEVELOPMENT.rst#openslides-in-big-mode>`_
Configuration
=============
Please consider reading the `OpenSlides configuration
<https://github.com/OpenSlides/OpenSlides/blob/master/SETTINGS.rst>`_ page to
find out about all configurations, especially when using OpenSlides for big
assemblies.
Development
===========
To setup a development environment for OpenSlides follow the instruction of
`DEVELOPMENT.rst
<https://github.com/OpenSlides/OpenSlides/blob/master/DEVELOPMENT.rst>`_.
Feel free to create issues here in GitHub! Please use the right templates for
bugs and features and using them correctly. Pull requests are also welcome; for
a general overview of the development setup refer the `development instructions <https://github.com/OpenSlides/OpenSlides/blob/master/DEVELOPMENT.rst>`_.
Used software Used software
============= =============
OpenSlides uses the following projects or parts of them: OpenSlides uses the following projects or parts of them:
* Several Python packages (see ``requirements/production.txt`` and ``requirements/big_mode.txt``). * Several Python packages (see ``server/requirements/production.txt`` and ``server/requirements/big_mode.txt``).
* Several JavaScript packages (see ``client/package.json``) * Several JavaScript packages (see ``client/package.json``)
License and authors License and authors
=================== ===================

2
client/.dockerignore Normal file
View File

@ -0,0 +1,2 @@
.git
**/node_modules

View File

@ -1,31 +1,5 @@
# OpenSlides 3 Client # OpenSlides 3 Client
Prototype application for OpenSlides 3.0 (Client).
Currently under constant heavy maintenance.
## Development Info
As an Angular project, Angular CLI is highly recommended to create components and services.
See https://angular.io/guide/quickstart for details.
### Contribution Info
Please respect the code-style defined in `.editorconf` and `.pretierrc`.
Code alignment should be automatically corrected by the pre-commit hooks.
Adjust your editor to the `.editorconfig` to avoid surprises.
See https://editorconfig.org/ for details.
### Pre-Commit Hooks
Before commiting, new code will automatically be aligned to the definitions set in the
`.prettierrc`.
Furthermore, new code has to pass linting.
Our pre-commit hooks are:
`pretty-quick --staged` and `lint`
See `package.json` for details.
### Documentation Info ### Documentation Info
The documentation can be generated by running `npm run compodoc`. The documentation can be generated by running `npm run compodoc`.
@ -38,16 +12,6 @@ command. If no port specified, it will try to use 8080.
Please document new code using JSDoc tags. Please document new code using JSDoc tags.
See https://compodoc.app/guides/jsdoc-tags.html for details. See https://compodoc.app/guides/jsdoc-tags.html for details.
### Development server
Run `npm start` for a development server. Navigate to `http://localhost:4200/`.
The app will automatically reload if you change any of the source files.
A running OpenSlides (2.2 or higher) instance is expected on port 8000.
Start OpenSlides as usual using
`python manage.py start --no-browser --host 0.0.0.0`
### Translation ### Translation
We are using ngx-translate for translation purposes. We are using ngx-translate for translation purposes.

View File

@ -17,7 +17,7 @@
"build": { "build": {
"builder": "@angular-devkit/build-angular:browser", "builder": "@angular-devkit/build-angular:browser",
"options": { "options": {
"outputPath": "../openslides/static", "outputPath": "static",
"index": "src/index.html", "index": "src/index.html",
"main": "src/main.ts", "main": "src/main.ts",
"polyfills": "src/polyfills.ts", "polyfills": "src/polyfills.ts",

9
client/build.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
cd "$(dirname "$0")"
printf "Client built on %s:\n\nBranch: %s\n\n%s\n" \
"$(date)" \
"$(git rev-parse --abbrev-ref HEAD)" \
"$(git show -s --format=raw)" > client-version.txt
docker build -f docker/Dockerfile . $@

23
client/docker/Dockerfile Normal file
View File

@ -0,0 +1,23 @@
FROM node:13 AS nodejs
RUN mkdir -p /build/app
WORKDIR /build/app
RUN useradd -m openslides
RUN chown -R openslides /build/app
USER root
RUN npm install -g @angular/cli@^9
RUN ng config -g cli.warnings.versionMismatch false
USER openslides
COPY package.json .
RUN npm install
COPY browserslist *.json ./
COPY src ./src
RUN npm run build
COPY client-version.txt static/
FROM nginx
COPY --from=nodejs /build/app/static /usr/share/nginx/html
COPY docker/nginx.conf /etc/nginx/nginx.conf

56
client/docker/nginx.conf Normal file
View File

@ -0,0 +1,56 @@
worker_processes auto;
events {
worker_connections 32000;
}
http {
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm;
include /etc/nginx/mime.types;
# Optimizations for OpenSlides
client_max_body_size 100M;
proxy_connect_timeout 300s;
proxy_read_timeout 300s;
proxy_set_header Host $http_host;
gzip on;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
location /apps {
proxy_pass http://server:8000;
}
location /media/ {
proxy_pass http://media:8000;
}
location /rest {
proxy_pass http://server:8000;
}
location /ws {
proxy_pass http://server:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location /server-version.txt {
proxy_pass http://server:8000;
}
location = /basic_status {
stub_status;
}
location / {
try_files $uri $uri/ /index.html;
}
}
}

4
docker/build.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
../server/build.sh -t openslides/openslides-server:latest
../client/build.sh -t openslides/openslides-client:latest
docker-compose build

162
docker/docker-compose.yml Normal file
View File

@ -0,0 +1,162 @@
version: '3.4'
# @Gernot: TODO env file
x-server-env: &default-server-env
SECRET_KEY: "TODO"
# @Gernot: TODO secret key generation. -> secret?
INSTANCE_DOMAIN: "http://example.com:8000"
x-pgnode: &default-pgnode
image: openslides/openslides-repmgr:latest
build: https://github.com/OpenSlides/openslides-docker-compose.git#:repmgr
networks:
- dbnet
labels:
org.openslides.role: "postgres"
restart: always
x-pgnode-env: &default-pgnode-env
REPMGR_RECONNECT_ATTEMPTS: 30
REPMGR_RECONNECT_INTERVAL: 10
services:
server:
image: openslides/openslides-server:latest
networks:
- front
- back
restart: always
# Below is the default command. You can uncomment it to override the
# number of workers, for example:
# command: "gunicorn -w 8 --preload -b 0.0.0.0:8000
# -k uvicorn.workers.UvicornWorker openslides.asgi:application"
#
# Uncomment the following line to use daphne instead of gunicorn:
# command: "daphne -b 0.0.0.0 -p 8000 openslides.asgi:application"
depends_on:
- postfix
- media
- pgbouncer
- redis
- redis-slave
- redis-channels
environment:
<< : *default-server-env
secrets:
- os_admin
- os_user
server-db-setup:
image: openslides/openslides-server:latest
networks:
- back
restart: always
entrypoint: /usr/local/sbin/entrypoint-db-setup
depends_on:
- pgbouncer
- redis
- redis-slave
- redis-channels
environment:
<< : *default-server-env
secrets:
- os_admin
- os_user
client:
image: openslides/openslides-client:latest
restart: always
depends_on:
- server
networks:
- front
ports:
- "127.0.0.1:8000:80"
pgnode1:
<< : *default-pgnode
environment:
<< : *default-pgnode-env
REPMGR_NODE_ID: 1
REPMGR_PRIMARY: # empty; this *is* the primary
volumes:
- "dbdata1:/var/lib/postgresql"
# Note: You can add more postgres nodes by copying the template
# and replacing all %X% with the number of the pgnode. Remember
# to add all pgnodes to the pgbouncer below!
# pgnode%X%:
# << : *default-pgnode
# environment:
# << : *default-pgnode-env
# REPMGR_NODE_ID: %X%
# REPMGR_PRIMARY: pgnode1
# volumes:
# - "dbdata%X%:/var/lib/postgresql"
pgbouncer:
# environment:
# - PG_NODE_LIST=pgnode1,pgnode2,pgnode3
image: openslides/openslides-pgbouncer:latest
build: https://github.com/OpenSlides/openslides-docker-compose.git#:pgbouncer
restart: always
networks:
back:
aliases:
- db
- postgres
dbnet:
postfix:
image: openslides/openslides-postfix:latest
build: https://github.com/OpenSlides/openslides-docker-compose.git#:postfix
restart: always
environment:
MYHOSTNAME: localhost
RELAYHOST: localhost
networks:
- back
redis:
image: redis:alpine
restart: always
networks:
- back
redis-slave:
image: redis:alpine
restart: always
command: ["redis-server", "--save", "", "--slaveof", "redis", "6379"]
depends_on:
- redis
networks:
- back
redis-channels:
image: redis:alpine
restart: always
networks:
- back
media:
image: openslides/openslides-media-service:latest
build: https://github.com/OpenSlides/openslides-media-service.git
environment:
- CHECK_REQUEST_URL=server:8000/check-media/
restart: always
networks:
front:
back:
# Override command to run more workers per task
# command: ["gunicorn", "-w", "4", "--preload", "-b",
# "0.0.0.0:8000", "src.mediaserver:app"]
volumes:
dbdata1:
dbdata2:
dbdata3:
networks:
front:
back:
dbnet:
secrets:
os_admin:
file: ./secrets/admin.env
os_user:
file: ./secrets/user.env
# vim: set ft=yaml sw=2 et:

View File

@ -0,0 +1,3 @@
## secrets/adminsecret.env is sourced by the server container to set the initial
## admin user password.
# OPENSLIDES_ADMIN_PASSWORD="<securepassword>"

View File

@ -0,0 +1,5 @@
## Example user credential configuration
# OPENSLIDES_USER_FIRSTNAME="John"
# OPENSLIDES_USER_LASTNAME="Doe"
# OPENSLIDES_USER_PASSWORD="<securepassword>"
# OPENSLIDES_USER_EMAIL="john@example.com"

83
haproxy/src/combined.pem Normal file
View File

@ -0,0 +1,83 @@
-----BEGIN CERTIFICATE-----
MIIFVzCCAz+gAwIBAgIUBcPjTF+PvAOcjrgx/udC/+W6ksowDQYJKoZIhvcNAQEL
BQAwOzELMAkGA1UEBhMCREUxGDAWBgNVBAoMD1NlbGZzaWduZWQgVGVzdDESMBAG
A1UEAwwJbG9jYWxob3N0MB4XDTIwMDgxNDA5MTEwN1oXDTMwMDgxMjA5MTEwN1ow
OzELMAkGA1UEBhMCREUxGDAWBgNVBAoMD1NlbGZzaWduZWQgVGVzdDESMBAGA1UE
AwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAk/TF
odKI6Bnnuxf3ePpvGkBgs9Aonmh18WRNzfyXsRTQVZD3e77NV0ac7w5cnAxGjHV7
bqOYS/D35D6vQcbEznHUIwril3GxAIXrAq2Vbu+vsb0MQ//VX6MjmbLfGTPvzMmX
B46MwcKYTDZn+qySSyrAsuBNgFlOXGKMi0bLkZlODC5kXsLBQVLVq48w45WJnmBc
FfXaYzivsFVfmKuuVMYHH/q1ftNcFlswyCr4C8zH8uyPP5ao2NBoS56NRT3bb7Rd
gELgvNQRGK/PiPrd87ikra8Tqh/YCm77339UEIFqNGf78sZIRXYKrWwjX8drxPSi
3qMpvGi9ZqCkS9Nk5teGoMSFQTymTO4RJs0VDEdtFSXkW6HKGOAglp0p2ahjYsfP
eeZ57rNSfz5y1U0f/xDjy6PdSSCWAt5mNmpIXJWT39NHVRkak47vEjOiSak7+u3v
e/lD5zFxXQUDMFF4UYCxg6OuTmP6B0wpwI/ub9AdQBUUc3XwnqNspg+kS1fvA6Vi
PRigwGF1wcz8oIsB0cqHpIbMUt2MOghc6t7vv1jwMWuGO6o1679txSllmQ65cNuP
UNRMD21ZuB4tlA8+RWllVlZ07Zhs/RWeYgPJuEbWfy58CViSUs8Wlt7my5xmMo5l
XtiPg1hK7OoqUSeSZPBiTc0Ow9gtp6V4dVqJXGMCAwEAAaNTMFEwHQYDVR0OBBYE
FKnj4+F+29npAiaq/9G1XmrHSrU8MB8GA1UdIwQYMBaAFKnj4+F+29npAiaq/9G1
XmrHSrU8MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAHpdUoBq
MorSgFSqIu8lI6sISpGfjPLQOAM7cN4ZvI4gVEx6eXqHl2rePrPkJi2auZ4f6xM2
2s7cb6t6i3MyiKgK3mWUqV+V6F8xfU0KGqI7d2aL6wTo9N9SunpwZNAzQ7O2W3M2
+liQj+mJhMLaIzbDk+2kybT2ox7kHNbxhww2NtRvqQogJPZWWUSCpYuVi9km1JLz
TEYumknnIAQHUdYUOoXRRj80jwxN6gFac33Dn/PZkC8ntyKpVNyFSKtD5Uj9Pj6z
5C/AnVjqJlLJ+/dowXtLOyvgUrTmIVhGxGWQ9y/JHWKJZhI7WNB2kNGU6UnLCcGX
2j5RpMoQY61KYBrJrAFFXd421EcGAtDufyuPAxdwppWXcRDxRrf7H6WU4rq8GewC
iETnxFUV5utzyzlUDklFS+JubHW5DkqrVHOYuYc5ZokQseTMJqoWWzNuQI5vPG9f
wSJLOqTSn9PvUC+25YKsyGR7SHhzbIVWDa6ctAQRGWo+1YnOOrdDW6IxewEn08Jg
MpHgvghQfTgSOYKXny5SFfG//dfEzauDEX0Ypc84DCy92NCcD8Y4ib7SkvkYvhz2
0CWbEBmWPLn/gVJ3gKrXrfzQuTBpAmiQ1bLXklSIbRuK7iK0kxccLK944QGm3KN9
F6Vo+CsgqLIwTXTE62cPfoJLM3+cYGygn7On
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
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
zY79cblfI1bop2NlQ7f3S/82OQWwX7E=
-----END PRIVATE KEY-----

View File

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
zY79cblfI1bop2NlQ7f3S/82OQWwX7E=
-----END PRIVATE KEY-----

31
haproxy/src/localhost.pem Normal file
View File

@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFVzCCAz+gAwIBAgIUBcPjTF+PvAOcjrgx/udC/+W6ksowDQYJKoZIhvcNAQEL
BQAwOzELMAkGA1UEBhMCREUxGDAWBgNVBAoMD1NlbGZzaWduZWQgVGVzdDESMBAG
A1UEAwwJbG9jYWxob3N0MB4XDTIwMDgxNDA5MTEwN1oXDTMwMDgxMjA5MTEwN1ow
OzELMAkGA1UEBhMCREUxGDAWBgNVBAoMD1NlbGZzaWduZWQgVGVzdDESMBAGA1UE
AwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAk/TF
odKI6Bnnuxf3ePpvGkBgs9Aonmh18WRNzfyXsRTQVZD3e77NV0ac7w5cnAxGjHV7
bqOYS/D35D6vQcbEznHUIwril3GxAIXrAq2Vbu+vsb0MQ//VX6MjmbLfGTPvzMmX
B46MwcKYTDZn+qySSyrAsuBNgFlOXGKMi0bLkZlODC5kXsLBQVLVq48w45WJnmBc
FfXaYzivsFVfmKuuVMYHH/q1ftNcFlswyCr4C8zH8uyPP5ao2NBoS56NRT3bb7Rd
gELgvNQRGK/PiPrd87ikra8Tqh/YCm77339UEIFqNGf78sZIRXYKrWwjX8drxPSi
3qMpvGi9ZqCkS9Nk5teGoMSFQTymTO4RJs0VDEdtFSXkW6HKGOAglp0p2ahjYsfP
eeZ57rNSfz5y1U0f/xDjy6PdSSCWAt5mNmpIXJWT39NHVRkak47vEjOiSak7+u3v
e/lD5zFxXQUDMFF4UYCxg6OuTmP6B0wpwI/ub9AdQBUUc3XwnqNspg+kS1fvA6Vi
PRigwGF1wcz8oIsB0cqHpIbMUt2MOghc6t7vv1jwMWuGO6o1679txSllmQ65cNuP
UNRMD21ZuB4tlA8+RWllVlZ07Zhs/RWeYgPJuEbWfy58CViSUs8Wlt7my5xmMo5l
XtiPg1hK7OoqUSeSZPBiTc0Ow9gtp6V4dVqJXGMCAwEAAaNTMFEwHQYDVR0OBBYE
FKnj4+F+29npAiaq/9G1XmrHSrU8MB8GA1UdIwQYMBaAFKnj4+F+29npAiaq/9G1
XmrHSrU8MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAHpdUoBq
MorSgFSqIu8lI6sISpGfjPLQOAM7cN4ZvI4gVEx6eXqHl2rePrPkJi2auZ4f6xM2
2s7cb6t6i3MyiKgK3mWUqV+V6F8xfU0KGqI7d2aL6wTo9N9SunpwZNAzQ7O2W3M2
+liQj+mJhMLaIzbDk+2kybT2ox7kHNbxhww2NtRvqQogJPZWWUSCpYuVi9km1JLz
TEYumknnIAQHUdYUOoXRRj80jwxN6gFac33Dn/PZkC8ntyKpVNyFSKtD5Uj9Pj6z
5C/AnVjqJlLJ+/dowXtLOyvgUrTmIVhGxGWQ9y/JHWKJZhI7WNB2kNGU6UnLCcGX
2j5RpMoQY61KYBrJrAFFXd421EcGAtDufyuPAxdwppWXcRDxRrf7H6WU4rq8GewC
iETnxFUV5utzyzlUDklFS+JubHW5DkqrVHOYuYc5ZokQseTMJqoWWzNuQI5vPG9f
wSJLOqTSn9PvUC+25YKsyGR7SHhzbIVWDa6ctAQRGWo+1YnOOrdDW6IxewEn08Jg
MpHgvghQfTgSOYKXny5SFfG//dfEzauDEX0Ypc84DCy92NCcD8Y4ib7SkvkYvhz2
0CWbEBmWPLn/gVJ3gKrXrfzQuTBpAmiQ1bLXklSIbRuK7iK0kxccLK944QGm3KN9
F6Vo+CsgqLIwTXTE62cPfoJLM3+cYGygn7On
-----END CERTIFICATE-----

View File

@ -1,32 +0,0 @@
from django.core.management.base import BaseCommand
from ...models import User
class Command(BaseCommand):
"""
Command to create an OpenSlides user.
"""
help = "Creates an OpenSlides user."
def add_arguments(self, parser):
parser.add_argument("first_name", help="The first name of the new user.")
parser.add_argument("last_name", help="The last name of the new user.")
parser.add_argument("username", help="The username of the new user.")
parser.add_argument("password", help="The password of the new user.")
parser.add_argument("groups_id", help="The group id of the new user.")
parser.add_argument("--email", help="The email address of the new user.")
def handle(self, *args, **options):
user_data = {
"first_name": options["first_name"],
"last_name": options["last_name"],
"default_password": options["password"],
"email": options["email"] or "",
}
user = User.objects.create_user(
options["username"], options["password"], skip_autoupdate=True, **user_data
)
if options["groups_id"].isdigit():
user.groups.add(int(options["groups_id"]))

2
server/.dockerignore Normal file
View File

@ -0,0 +1,2 @@
*.pyc
__pycache__/

18
server/build.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
cd "$(dirname "$0")"
printf "Server built on %s:\n\nBranch: %s\n\n%s\n" \
"$(date)" \
"$(git rev-parse --abbrev-ref HEAD)" \
"$(git show -s --format=raw)" > docker/server-version.txt
# @Gernot: TODO
# SECRET_KEY=$(head /dev/urandom | tr -dc 'A-Za-z0-9!"#$%&()*+,-./:;<=>?@[]^_`{|}~' | head -c 64)
# sed: \/& must be escaped...
# ESCAPED_SECRET_KEY=$(printf "%s\n" "$SECRET_KEY" | sed -e 's/[\/&]/\\&/g')
# sed -i \
# -e "/SECRET_KEY/s/%%secret-key%%/$ESCAPED_SECRET_KEY/" \
# docker/settings.py
docker build -f docker/Dockerfile . $@

67
server/docker/Dockerfile Normal file
View File

@ -0,0 +1,67 @@
FROM python:3.7-slim AS base
ENV DEBIAN_FRONTEND noninteractive
ENV DEBIAN_PRIORITY critical
ENV DEBCONF_NOWARNINGS yes
ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE 1
# Variables relevant for CMD
ENV DJANGO_SETTINGS_MODULE settings
ENV PYTHONPATH personal_data/var/
RUN mkdir -p /app
WORKDIR /app
RUN useradd -m openslides
RUN chown -R openslides /app
RUN apt-get -y update && apt-get -y upgrade && \
apt-get install --no-install-recommends -y \
apt-transport-https \
bzip2 \
curl \
g++ \
gcc \
git \
gnupg2 \
libpq-dev \
make \
postgresql-client \
rsync \
wait-for-it \
wget \
xz-utils
# Install additional tools
RUN apt-get install --no-install-recommends -y \
dnsutils \
iputils-ping \
netcat \
procps \
traceroute \
vim
# Install saml requirements
RUN apt-get install --no-install-recommends -y \
libxml2-dev \
libxmlsec1-dev \
libxmlsec1-openssl \
pkg-config
RUN rm -rf /var/lib/apt/lists/*
COPY requirements /app/requirements
RUN pip install -r requirements/production.txt -r requirements/big_mode.txt && \
rm -rf /root/.cache/pip
USER openslides
# the `empty` folder is used for the dummy http server für the migrate entrypoint to serve no files.
RUN mkdir /app/empty
COPY docker/entrypoint /usr/local/sbin/
COPY docker/entrypoint-db-setup /usr/local/sbin/
COPY docker/settings.py /app/personal_data/var/settings.py
COPY manage.py /app/
COPY openslides /app/openslides
COPY docker/server-version.txt /app/openslides/core/static/server-version.txt
ENTRYPOINT ["/usr/local/sbin/entrypoint"]
CMD ["gunicorn", "-w", "8", "--preload", "-b", "0.0.0.0:8000", "-k", \
"uvicorn.workers.UvicornWorker", "openslides.asgi:application"]

14
server/docker/entrypoint Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
set -e
# TODO: env variable for this host
wait-for-it -t 0 "server-db-setup:8000"
printf 'Executing server: "%s"\n' "$*"
# Expected commands are one of:
# - daphne -b 0.0.0.0 -p 8000 openslides.asgi:application
# - gunicorn -w 4 -b 0.0.0.0:8000 -k uvicorn.workers.UvicornWorker \
# openslides.asgi:application
exec $*

View File

@ -0,0 +1,77 @@
#!/bin/bash
set -e
warn_insecure_admin() {
cat <<-EOF
==============================================
WARNING
==============================================
WARNING: INSECURE ADMIN ACCOUNT CONFIGURATION!
EOF
sleep 10
}
# Configure database
# TODO: env variables??
echo "postgres:5432:instancecfg:openslides:openslides" > "${HOME}/.pgpass"
chmod 600 "${HOME}/.pgpass"
until pg_isready -h db; do
echo "Waiting for Postgres cluster to become available..."
sleep 3
done
# Wait for redis
wait-for-it redis:6379
wait-for-it redis-slave:6379
wait-for-it redis-channels:6379
echo 'running migrations'
python manage.py migrate
# Admin
if [[ -f /run/secrets/os_admin ]]; then
echo "Retrieving secure admin password"
source /run/secrets/os_admin
if [[ -n "${OPENSLIDES_ADMIN_PASSWORD}" ]]; then
echo "Changing admin password"
python manage.py changedefaultadminpassword "${OPENSLIDES_ADMIN_PASSWORD}"
else
warn_insecure_admin
fi
else
warn_insecure_admin
fi
# Main user
if [[ -f /run/secrets/os_user ]]; then
echo "Retrieving secure user credentials"
source /run/secrets/os_user
if [[ -n "${OPENSLIDES_USER_FIRSTNAME}" ]] &&
[[ -n "${OPENSLIDES_USER_LASTNAME}" ]] &&
[[ -n "${OPENSLIDES_USER_PASSWORD}" ]]; then
user_name="${OPENSLIDES_USER_FIRSTNAME} ${OPENSLIDES_USER_LASTNAME}"
echo "Adding user: ${user_name}"
# createopenslidesuser: error: the following arguments are required:
# first_name, last_name, username, password, groups_id
# email is optional
# userid forces to to only create a user with this id, if it not exists before.
python manage.py createopenslidesuser \
--userid 2 \
--email "${OPENSLIDES_USER_EMAIL:-}" \
"${OPENSLIDES_USER_FIRSTNAME}" \
"${OPENSLIDES_USER_LASTNAME}" \
"${user_name}" \
"${OPENSLIDES_USER_PASSWORD}" \
2
else
echo "Incomplete user account data. Skipping account creation."
fi
fi
echo "Done migrating and setting up user accounts..."
python -m http.server --directory /app/empty --bind 0.0.0.0 8000

170
server/docker/settings.py Normal file
View File

@ -0,0 +1,170 @@
"""
Settings file for OpenSlides.
For more information on this file, see
https://github.com/OpenSlides/OpenSlides/blob/master/SETTINGS.rst
"""
import os
from openslides.global_settings import *
class MissingEnvironmentVariable(Exception):
pass
undefined = object()
def get_env(name, default=undefined, cast=str):
env = os.environ.get(name)
default_extension = ""
if env is None:
env = default
default_extension = " (default)"
if env is undefined:
raise MissingEnvironmentVariable(name)
if cast is bool:
env = env in ("1", "true", "True")
else:
env = cast(env)
if env is None:
print(f"{name}={default_extension}", flush=True)
else:
print(f'{name}="{env}"{default_extension}', flush=True)
return env
# The directory for user specific data files
OPENSLIDES_USER_DATA_DIR = "/app/personal_data/var"
SECRET_KEY = get_env("SECRET_KEY")
DEBUG = False
# Controls the verbosity on errors during a reset password. If enabled, an error
# will be shown, if there does not exist a user with a given email address. So one
# can check, if a email is registered. If this is not wanted, disable verbose
# messages. An success message will always be shown.
RESET_PASSWORD_VERBOSE_ERRORS = get_env("RESET_PASSWORD_VERBOSE_ERRORS", True, bool)
AUTOUPDATE_DELAY = get_env("AUTOUPDATE_DELAY", 1, int)
# Email settings
# For SSL/TLS specific settings see https://docs.djangoproject.com/en/1.11/topics/email/#smtp-backend
EMAIL_HOST = get_env("EMAIL_HOST", "postfix")
EMAIL_PORT = get_env("EMAIL_PORT", 25, int)
EMAIL_HOST_USER = get_env("EMAIL_HOST_USER", "")
EMAIL_HOST_PASSWORD = get_env("EMAIL_HOST_PASSWORD", "")
DEFAULT_FROM_EMAIL = get_env("DEFAULT_FROM_EMAIL", "noreply@example.com")
# Increasing Upload size to 100mb (default is 2.5mb)
DATA_UPLOAD_MAX_MEMORY_SIZE = 104857600
# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "openslides",
"USER": get_env("DATABASE_USER", "openslides"),
"PASSWORD": get_env("DATABASE_PASSWORD", "openslides"),
"HOST": get_env("DATABASE_HOST", "db"),
"PORT": get_env("DATABASE_PORT", "5432"),
},
"mediafiles": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "mediafiledata",
"USER": get_env("DATABASE_USER", "openslides"),
"PASSWORD": get_env("DATABASE_PASSWORD", "openslides"),
"HOST": get_env("DATABASE_HOST", "db"),
"PORT": get_env("DATABASE_PORT", "5432"),
},
}
# Redis
REDIS_HOST = get_env("REDIS_HOST", "redis")
REDIS_PORT = get_env("REDIS_PORT", 6379, int)
REDIS_SLAVE_HOST = get_env("REDIS_SLAVE_HOST", "redis-slave")
REDIS_SLAVE_PORT = get_env("REDIS_SLAVE_PORT", 6379, int)
REDIS_CHANNLES_HOST = get_env("REDIS_CHANNLES_HOST", "redis-channels")
REDIS_CHANNLES_PORT = get_env("REDIS_CHANNLES_PORT", 6379, int)
REDIS_SLAVE_WAIT_TIMEOUT = get_env("REDIS_SLAVE_WAIT_TIMEOUT", 10000, int)
# Django Channels
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [(REDIS_CHANNLES_HOST, REDIS_CHANNLES_PORT)],
"capacity": 10000,
},
},
}
# Collection Cache
REDIS_ADDRESS = f"redis://{REDIS_HOST}:{REDIS_PORT}/0"
REDIS_READ_ONLY_ADDRESS = f"redis://{REDIS_SLAVE_HOST}:{REDIS_SLAVE_PORT}/0"
AMOUNT_REPLICAS = get_env("AMOUNT_REPLICAS", 1)
CONNECTION_POOL_LIMIT = get_env("CONNECTION_POOL_LIMIT", 100, int)
# Session backend
SESSION_ENGINE = "redis_sessions.session"
SESSION_REDIS = {
"host": REDIS_HOST,
"port": REDIS_PORT,
"db": 0,
"prefix": "session",
"socket_timeout": 2,
}
# SAML integration
ENABLE_SAML = get_env("ENABLE_SAML", False, bool)
if ENABLE_SAML:
INSTALLED_APPS += ["openslides.saml"]
# TODO: More saml stuff...
# Controls if electronic voting (means non-analog polls) are enabled.
ENABLE_ELECTRONIC_VOTING = get_env("ENABLE_ELECTRONIC_VOTING", False, bool)
# Jitsi integration
JITSI_DOMAIN = get_env("JITSI_DOMAIN", None)
JITSI_ROOM_NAME = get_env("JITSI_ROOM_NAME", None)
JITSI_PASSWORD = get_env("JITSI_PASSWORD", None)
TIME_ZONE = "Europe/Berlin"
STATICFILES_DIRS = [os.path.join(OPENSLIDES_USER_DATA_DIR, "static")] + STATICFILES_DIRS
STATIC_ROOT = os.path.join(OPENSLIDES_USER_DATA_DIR, "collected-static")
MEDIA_ROOT = os.path.join(OPENSLIDES_USER_DATA_DIR, "media", "")
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"gunicorn": {
"format": "{asctime} [{process:d}] [{levelname}] {name} {message}",
"style": "{",
"datefmt": "[%Y-%m-%d %H:%M:%S %z]",
},
},
"handlers": {
"console": {"class": "logging.StreamHandler", "formatter": "gunicorn",},
},
"loggers": {
"django": {
"handlers": ["console"],
"level": get_env("DJANGO_LOG_LEVEL", "INFO"),
},
"openslides": {
"handlers": ["console"],
"level": get_env("OPENSLIDES_LOG_LEVEL", "INFO"),
},
},
}
SETTINGS_FILEPATH = __file__

Some files were not shown because too many files have changed in this diff Show More