Prod setup

This commit is contained in:
Finn Stutzenstein 2020-10-05 10:43:43 +02:00
parent 399bf389d6
commit 9372386979
No known key found for this signature in database
GPG Key ID: 9042F605C6324654
24 changed files with 1461 additions and 194 deletions

8
.gitignore vendored
View File

@ -5,12 +5,15 @@
*~
.DS_Store
.idea
.env
*.code-workspace
# certs
*.pem
# Deployment
/docker/docker-compose.yml
/docker/docker-stack.yml
# Old OS3 files and folders
.coverage
.mypy_cache
@ -29,5 +32,4 @@ tests
.vscode/
package-lock.json
server/
docker/
docker/keys

View File

@ -1,5 +1,3 @@
SHELL := /bin/bash
run-system-tests:
echo "TODO: write complete system tests"
@ -11,21 +9,14 @@ build-dev:
make -C haproxy build-dev
run-dev: | build-dev
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up
docker-compose -f docker/docker-compose.dev.yml up
stop-dev:
docker-compose -f docker-compose.yml -f docker-compose.dev.yml down
docker-compose -f docker/docker-compose.dev.yml down
copy-node-modules:
docker-compose -f docker-compose.yml -f docker-compose.dev.yml exec client bash -c "cp -r /app/node_modules/ /app/src/"
docker-compose -f docker/docker-compose.dev.yml exec client bash -c "cp -r /app/node_modules/ /app/src/"
mv openslides-client/client/src/node_modules/ openslides-client/client/
build-prod:
git submodule status | awk '{ gsub(/[^0-9a-f]/, "", $$1); gsub("-","_",$$2); print toupper($$2)"_COMMIT_HASH="$$1 }' > .env
docker-compose -f docker-compose.yml -f docker-compose.prod.yml build
run-prod: | build-prod
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up
reload-haproxy:
docker-compose -f docker-compose.yml -f docker-compose.dev.yml kill -s HUP haproxy
docker-compose -f docker/docker-compose.dev.yml kill -s HUP haproxy

View File

@ -32,6 +32,25 @@ For a non-development setup, clone this repo and run it via docker compose. The
For a development setup, refer to [the development docs](DEVELOPMENT.md)
## Productive environment
Setup the repository (may be already done)
$ git clone git@github.com:OpenSlides/OpenSlides.git
$ cd OpenSlides
$ git checkout openslides4-dev
$ git submodule update --init
Prod setup. `./build.sh` may take a while.
$ cd docker
$ ./build.sh
$ ./setup-prod.sh
$ docker-compose up
Navigate to https://localhost:8000
## Used software
OpenSlides uses the following projects or parts of them:

View File

@ -1,3 +1,3 @@
#!/bin/bash
cd "$(dirname $0)"
docker-compose -f docker-compose.yml -f docker-compose.dev.yml $@
docker-compose -f docker/docker-compose.dev.yml $@

View File

@ -1,100 +0,0 @@
version: "3"
services:
datastore-reader:
build:
context: "https://github.com/OpenSlides/openslides-datastore-service.git"
args:
GIT_CHECKOUT: "${OPENSLIDES_DATASTORE_SERVICE_COMMIT_HASH}"
MODULE: "reader"
PORT: "${OPENSLIDES_DATASTORE_READER_PORT}"
image: openslides-datastore-reader
networks:
- backend
- datastore-reader
- postgres
datastore-writer:
build:
context: "https://github.com/OpenSlides/openslides-datastore-service.git"
args:
GIT_CHECKOUT: "${OPENSLIDES_DATASTORE_SERVICE_COMMIT_HASH}"
MODULE: "writer"
PORT: "${OPENSLIDES_DATASTORE_WRITER_PORT}"
image: openslides-datastore-writer
networks:
- backend
- postgres
- message-bus
postgres:
networks:
- postgres
client:
build:
context: "https://github.com/OpenSlides/openslides-client.git"
args:
GIT_CHECKOUT: "${OPENSLIDES_CLIENT_COMMIT_HASH}"
image: openslides-client
networks:
- frontend
backend:
networks:
- frontend
- backend
autoupdate:
networks:
- frontend
- backend
- message-bus
auth:
build:
context: "https://github.com/OpenSlides/openslides-auth-service.git"
args:
GIT_CHECKOUT: "${OPENSLDIES_AUTH_SERVICE_COMMIT_HASH}"
PORT: "${OPENSLDIES_AUTH_SERVICE_PORT}"
image: openslides-auth
networks:
- datastore-reader
- auth
cache:
networks:
- auth
message-bus:
networks:
- message-bus
media:
# TODO: build
image: openslides-media
networks:
- frontend
- backend
- postgres
haproxy:
build: ./haproxy
image: openslides-haproxy
networks:
- uplink
- frontend
# Setup: host <-uplink-> haproxy <-frontend-> services that are reachable from the client <-backend-> services that are internal-only
# There are special networks for some services only, e.g. postgres only for the postgresql, datastore reader and datastore writer
networks:
uplink:
frontend:
internal: true
backend:
internal: true
postgres:
internal: true
datastore-reader:
internal: true
message-bus:
internal: true
auth:
internal: true

View File

@ -1,71 +0,0 @@
version: "3"
services:
# DATASTORE SECTION
datastore-reader:
depends_on:
- postgres
env_file: services.env
environment:
- NUM_WORKERS=8
datastore-writer:
depends_on:
- postgres
- message-bus
env_file: services.env
# CLIENT
client:
depends_on:
- backend
- autoupdate
# BACKEND
backend:
depends_on:
- datastore-reader
- datastore-writer
env_file: services.env
# AUTOUPDATE
autoupdate:
depends_on:
- datastore-reader
- message-bus
env_file: services.env
# AUTH
auth:
depends_on:
- datastore-reader
- cache
env_file: services.env
cache:
image: redis:latest
# MEDIA
media:
depends_on:
- backend
- postgres
env_file: services.env
# PERSISTENCE
postgres:
image: postgres:11
environment:
- POSTGRES_USER=openslides
- POSTGRES_PASSWORD=openslides
- POSTGRES_DB=openslides
# SHARED
message-bus:
image: redis:latest
# UPLINK
haproxy:
depends_on:
- client
- backend
- autoupdate
ports:
- "8000:8000"

31
docker/.env Normal file
View File

@ -0,0 +1,31 @@
# OpenSlides instance configuration
#
# As well as environment variables for various services, this file contains
# variables used to persist custom settings for docker-compose.yml or
# docker-stack.yml. See the preamble of a docker-compose.yml.m4 or
# docker-stack.yml.m4 template for more information.
#
# Most variables are listed here only to facilitate discovery of the available
# options. Empty values cause the template's defaults to be inserted.
# General
# -------
INSTANCE_DOMAIN=
PROJECT_STACK_NAME=
EXTERNAL_HTTP_PORT=
DEFAULT_DOCKER_REGISTRY=
# Docker Images
# -------------
DOCKER_OPENSLIDES_BACKEND_NAME=
DOCKER_OPENSLIDES_BACKEND_TAG=
DOCKER_OPENSLIDES_FRONTEND_NAME=
DOCKER_OPENSLIDES_FRONTEND_TAG=
# Service Replication
# -------------------
# TODO!!
OPENSLIDES_BACKEND_SERVICE_REPLICAS=
OPENSLIDES_FRONTEND_SERVICE_REPLICAS=
REDIS_RO_SERVICE_REPLICAS=
MEDIA_SERVICE_REPLICAS=

152
docker/build.sh Executable file
View File

@ -0,0 +1,152 @@
#!/bin/bash
set -e
HOME=$(dirname "$(realpath "${BASH_SOURCE[0]}")")
declare -A TARGETS
TARGETS=(
[haproxy]="$HOME/../haproxy/"
[client]="$HOME/../openslides-client/"
[backend]="$HOME/../openslides-backend/"
[auth]="$HOME/../openslides-auth-service/"
[autoupdate]="$HOME/../openslides-autoupdate-service/"
[datastore-reader]="$HOME/../openslides-datastore-service/reader"
[datastore-writer]="$HOME/../openslides-datastore-service/writer"
[media]="$HOME/../openslides-media-service/"
#[pgbouncer]="https://github.com/OpenSlides/openslides-docker-compose.git#:pgbouncer"
#[postfix]="https://github.com/OpenSlides/openslides-docker-compose.git#:postfix"
#[repmgr]="https://github.com/OpenSlides/openslides-docker-compose.git#:repmgr"
)
DOCKER_REPOSITORY="openslides"
DOCKER_TAG="latest"
CONFIG="/etc/osinstancectl"
OPTIONS=()
BUILT_IMAGES=()
DEFAULT_TARGETS=(haproxy client backend auth autoupdate datastore-reader datastore-writer media)
usage() {
cat << EOF
Usage: $(basename ${BASH_SOURCE[0]}) [<options>] <service>...
Options:
-D, --docker-repo Specify a Docker repository
(default: unspecified, i.e., system default)
-t, --tag Tag the Docker image (default: $DOCKER_TAG)
--ask-push Offer to push newly built images to registry
--no-cache Pass --no-cache to docker-build
EOF
}
# Config file
if [[ -f "$CONFIG" ]]; then
echo "Found ${CONFIG} file."
source "$CONFIG"
fi
shortopt="hr:D:t:"
longopt="help,docker-repo:,tag:,ask-push,no-cache"
ARGS=$(getopt -o "$shortopt" -l "$longopt" -n "$ME" -- "$@")
if [ $? -ne 0 ]; then usage; exit 1; fi
eval set -- "$ARGS";
unset ARGS
# Parse options
while true; do
case "$1" in
-D|--docker-repo)
DOCKER_REPOSITORY="$2"
shift 2
;;
-t|--tag)
DOCKER_TAG="$2"
shift 2
;;
--ask-push)
ASK_PUSH=1
shift 1
;;
--no-cache)
OPTIONS+="--no-cache"
shift 1
;;
-h|--help) usage; exit 0 ;;
--) shift ; break ;;
*) usage; exit 1 ;;
esac
done
SELECTED_TARGETS=($@)
[[ "${#SELECTED_TARGETS[@]}" -ge 1 ]] || SELECTED_TARGETS=("${DEFAULT_TARGETS[@]}")
[[ "${SELECTED_TARGETS[@]}" != "all" ]] || SELECTED_TARGETS=("${!TARGETS[@]}")
for i in "${SELECTED_TARGETS[@]}"; do
loc="${TARGETS[$i]}"
[[ -n "$loc" ]] || {
echo "ERROR: Cannot build ${i}: not configured."
continue
}
img_name="openslides-${i}"
img="${img_name}:${DOCKER_TAG}"
if [[ -n "$DOCKER_REPOSITORY" ]]; then
img="${DOCKER_REPOSITORY}/${img}"
fi
echo "Building $img..."
cd $loc
{
printf '{\n'
printf '\t"service": "%s,\n' "${i}"
printf '\t"date": "%s",\n' "$(date)"
printf '\t"commit": "%s",\n' "$(git rev-parse HEAD)"
printf '\t"commit-abbrev": "%s",\n' "$(git rev-parse --abbrev-ref HEAD)"
printf '}\n'
} > version.json
# Special instructions for local services
build_script="${loc}/build.sh"
if [[ -f "$build_script" ]]; then
( . "$build_script" )
else
docker build --tag "$img" --pull "${OPTIONS[@]}" "$loc"
fi
rm version.json
BUILT_IMAGES+=("$img ON")
done
if [[ "${#BUILT_IMAGES[@]}" -ge 1 ]]; then
printf "\nSuccessfully built images:\n\n"
for i in "${BUILT_IMAGES[@]}"; do
read -r img x <<< "$i"
printf " - $img\n"
done
else
echo "No images were built."
exit 3
fi
[[ "$ASK_PUSH" ]] || exit 0
if hash whiptail > /dev/null 2>&1; then
while read img; do
echo "Pushing ${img}."
docker push "$img"
done < <( whiptail --title "OpenSlides build script" \
--checklist "Select images to push to their registry." \
25 78 16 --separate-output --noitem --clear \
${BUILT_IMAGES[@]} \
3>&2 2>&1 1>&3 )
else
echo
for i in "${BUILT_IMAGES[@]}"; do
read -r img x <<< "$i"
read -p "Push image '$img' to repository? [Y/n] " REPL
case "$REPL" in
N|n|No|no|NO) exit 0;;
*) docker push "$img" ;;
esac
done
fi

View File

@ -0,0 +1,87 @@
version: "3"
services:
datastore-reader:
image: openslides-datastore-reader-dev
depends_on:
- postgres
env_file: services.env
environment:
- NUM_WORKERS=8
volumes:
- ../openslides-datastore-service/shared/shared:/app/shared
- ../openslides-datastore-service/reader/reader:/app/reader
datastore-writer:
image: openslides-datastore-writer-dev
depends_on:
- postgres
- message-bus
env_file: services.env
volumes:
- ../openslides-datastore-service/shared/shared:/app/shared
- ../openslides-datastore-service/writer/writer:/app/writer
- ../openslides-datastore-service/cli:/app/cli
environment:
- DATASTORE_ENABLE_DEV_ENVIRONMENT=1
- COMMAND=create_initial_data
- DATASTORE_INITIAL_DATA_FILE=https://raw.githubusercontent.com/OpenSlides/OpenSlides/openslides4-dev/docs/example-data.json
postgres:
image: postgres:11
environment:
- POSTGRES_USER=openslides
- POSTGRES_PASSWORD=openslides
- POSTGRES_DB=openslides
client:
image: openslides-client-dev
depends_on:
- backend
- autoupdate
env_file: services.env
volumes:
- ../openslides-client/client/src:/app/src
backend:
image: openslides-backend-dev
depends_on:
- datastore-reader
- datastore-writer
env_file: services.env
volumes:
- ../openslides-backend/openslides_backend:/srv/code/openslides_backend
autoupdate:
image: openslides-autoupdate-dev
depends_on:
- datastore-reader
- message-bus
env_file: services.env
volumes:
- ../openslides-autoupdate-service/cmd:/root/cmd
- ../openslides-autoupdate-service/internal:/root/internal
auth:
image: openslides-auth-dev
depends_on:
- datastore-reader
- cache
env_file: services.env
volumes:
- ../openslides-auth-service/auth/src:/app/src
cache:
image: redis:latest
media:
image: openslides-media-dev
depends_on:
- backend
- postgres
env_file: services.env
volumes:
- ../openslides-media-service/src:/app/src
message-bus:
image: redis:latest
haproxy:
image: openslides-haproxy-dev
depends_on:
- client
- backend
- autoupdate
ports:
- "8000:8000"
volumes:
- ../haproxy/src:/usr/local/etc/haproxy

View File

@ -0,0 +1,193 @@
dnl This is a YAML template file. Simply translate it with m4 to create
dnl a standard configuration. Customizations can and should be added in .env
dnl by setting the appropriate variables.
dnl
dnl Usage:
dnl m4 docker-compose.yml.m4 > docker-compose.yml
dnl ( set -a; source .env; m4 docker-compose.yml.m4 ) > docker-compose.yml
dnl
dnl ----------------------------------------
divert(-1)dnl
define(`read_env', `esyscmd(`printf "%s" "$$1"')')
define(`ifenvelse', `ifelse(read_env(`$1'),, `$2', read_env(`$1'))')
define(`BACKEND_IMAGE',
ifenvelse(`DEFAULT_DOCKER_REGISTRY', openslides)/dnl
ifenvelse(`DOCKER_OPENSLIDES_BACKEND_NAME', openslides-backend):dnl
ifenvelse(`DOCKER_OPENSLIDES_BACKEND_TAG', latest))
define(`HAPROXY_IMAGE',
ifenvelse(`DEFAULT_DOCKER_REGISTRY', openslides)/dnl
ifenvelse(`DOCKER_OPENSLIDES_HAPROXY_NAME', openslides-haproxy):dnl
ifenvelse(`DOCKER_OPENSLIDES_HAPROXY_TAG', latest))
define(`CLIENT_IMAGE',
ifenvelse(`DEFAULT_DOCKER_REGISTRY', openslides)/dnl
ifenvelse(`DOCKER_OPENSLIDES_CLIENT_NAME', openslides-client):dnl
ifenvelse(`DOCKER_OPENSLIDES_CLIENT_TAG', latest))
define(`AUTH_IMAGE',
ifenvelse(`DEFAULT_DOCKER_REGISTRY', openslides)/dnl
ifenvelse(`DOCKER_OPENSLIDES_AUTH_NAME', openslides-auth):dnl
ifenvelse(`DOCKER_OPENSLIDES_AUTH_TAG', latest))
define(`AUTOUPDATE_IMAGE',
ifenvelse(`DEFAULT_DOCKER_REGISTRY', openslides)/dnl
ifenvelse(`DOCKER_OPENSLIDES_AUTOUPDATE_NAME', openslides-autoupdate):dnl
ifenvelse(`DOCKER_OPENSLIDES_AUTOUPDATE_TAG', latest))
define(`DATASTORE_READER_IMAGE',
ifenvelse(`DEFAULT_DOCKER_REGISTRY', openslides)/dnl
ifenvelse(`DOCKER_OPENSLIDES_DATASTORE_READER_NAME', openslides-datastore-reader):dnl
ifenvelse(`DOCKER_OPENSLIDES_DATASTORE_READER_TAG', latest))
define(`DATASTORE_WRITER_IMAGE',
ifenvelse(`DEFAULT_DOCKER_REGISTRY', openslides)/dnl
ifenvelse(`DOCKER_OPENSLIDES_DATASTORE_WRITER_NAME', openslides-datastore-writer):dnl
ifenvelse(`DOCKER_OPENSLIDES_DATASTORE_WRITER_TAG', latest))
define(`MEDIA_IMAGE',
ifenvelse(`DEFAULT_DOCKER_REGISTRY', openslides)/dnl
ifenvelse(`DOCKER_OPENSLIDES_MEDIA_NAME', openslides-media):dnl
ifenvelse(`DOCKER_OPENSLIDES_MEDIA_TAG', latest))
define(`PROJECT_DIR', ifdef(`PROJECT_DIR',PROJECT_DIR,.))
define(`ADMIN_SECRET_AVAILABLE', `syscmd(`test -f 'PROJECT_DIR`/secrets/admin.env')sysval')
define(`USER_SECRET_AVAILABLE', `syscmd(`test -f 'PROJECT_DIR`/secrets/user.env')sysval')
divert(0)dnl
dnl ----------------------------------------
# This configuration was created from a template file. Before making changes,
# please make sure that you do not have a process in place that would override
# your changes in the future. The accompanying .env file might be the correct
# place for customizations instead.
version: '3.4'
services:
haproxy:
image: HAPROXY_IMAGE
depends_on:
- client
- backend
- autoupdate
- auth
- media
networks:
- uplink
- frontend
ports:
- "127.0.0.1:ifenvelse(`EXTERNAL_HTTP_PORT', 8000):8000"
client:
image: CLIENT_IMAGE
networks:
- frontend
depends_on:
- backend
- autoupdate
backend:
image: BACKEND_IMAGE
depends_on:
- datastore-reader
- datastore-writer
env_file: services.env
networks:
- frontend
- backend
datastore-reader:
image: DATASTORE_READER_IMAGE
depends_on:
- postgres
env_file: services.env
environment:
- NUM_WORKERS=8
networks:
- backend
- datastore-reader
- postgres
datastore-writer:
image: DATASTORE_WRITER_IMAGE
depends_on:
- postgres
- message-bus
env_file: services.env
networks:
- backend
- postgres
- message-bus
environment:
- COMMAND=create_initial_data
- DATASTORE_INITIAL_DATA_FILE=/data/initial-data.json
volumes:
- ./initial-data.json:/data/initial-data.json
postgres:
image: postgres:11
environment:
- POSTGRES_USER=openslides
- POSTGRES_PASSWORD=openslides
- POSTGRES_DB=openslides
networks:
- postgres
autoupdate:
image: AUTOUPDATE_IMAGE
depends_on:
- datastore-reader
- message-bus
env_file: services.env
networks:
- frontend
- backend
- message-bus
auth:
image: AUTH_IMAGE
depends_on:
- datastore-reader
- message-bus
- cache
env_file: services.env
networks:
- datastore-reader
- frontend
- message-bus
- auth
volumes:
- ./keys:/keys
cache:
image: redis:latest
networks:
- auth
message-bus:
image: redis:latest
networks:
- message-bus
media:
image: MEDIA_IMAGE
depends_on:
- backend
- postgres
env_file: services.env
networks:
- frontend
- backend
- postgres
# Setup: host <-uplink-> haproxy <-frontend-> services that are reachable from the client <-backend-> services that are internal-only
# There are special networks for some services only, e.g. postgres only for the postgresql, datastore reader and datastore writer
networks:
uplink:
frontend:
internal: true
backend:
internal: true
postgres:
internal: true
datastore-reader:
internal: true
message-bus:
internal: true
auth:
internal: true
dnl secrets:
dnl ifelse(ADMIN_SECRET_AVAILABLE, 0,os_admin:
dnl file: ./secrets/admin.env)
dnl ifelse(USER_SECRET_AVAILABLE, 0,os_user:
dnl file: ./secrets/user.env)

276
docker/docker-stack.yml.m4 Normal file
View File

@ -0,0 +1,276 @@
dnl This is a YAML template file. Simply translate it with m4 to create
dnl a standard configuration. Customizations can and should be added in .env
dnl by setting the appropriate variables.
dnl
dnl Usage:
dnl m4 docker-stack.yml.m4 > docker-stack.yml
dnl ( set -a; source .env; m4 docker-stack.yml.m4 ) > docker-stack.yml
dnl
dnl ----------------------------------------
divert(-1)dnl
define(`read_env', `esyscmd(`printf "%s" "$$1"')')
define(`ifenvelse', `ifelse(read_env(`$1'),, `$2', read_env(`$1'))')
define(`BACKEND_IMAGE',
ifenvelse(`DOCKER_OPENSLIDES_BACKEND_NAME', openslides/openslides-server):dnl
ifenvelse(`DOCKER_OPENSLIDES_BACKEND_TAG', latest))
define(`FRONTEND_IMAGE',
ifenvelse(`DOCKER_OPENSLIDES_FRONTEND_NAME', openslides/openslides-client):dnl
ifenvelse(`DOCKER_OPENSLIDES_FRONTEND_TAG', latest))
define(`PRIMARY_DB', `ifenvelse(`PGNODE_REPMGR_PRIMARY', pgnode1)')
define(`PGBOUNCER_NODELIST',
`ifelse(read_env(`PGNODE_2_ENABLED'), 1, `,pgnode2')`'dnl
ifelse(read_env(`PGNODE_3_ENABLED'), 1, `,pgnode3')')
define(`PROJECT_DIR', ifdef(`PROJECT_DIR',PROJECT_DIR,.))
define(`ADMIN_SECRET_AVAILABLE', `syscmd(`test -f 'PROJECT_DIR`/secrets/adminsecret.env')sysval')
define(`USER_SECRET_AVAILABLE', `syscmd(`test -f 'PROJECT_DIR`/secrets/usersecret.env')sysval')
divert(0)dnl
dnl ----------------------------------------
# This configuration was created from a template file. Before making changes,
# please make sure that you do not have a process in place that would override
# your changes in the future. The accompanying .env file might be the correct
# place for customizations instead.
version: '3.4'
x-osserver:
&default-osserver
image: BACKEND_IMAGE
networks:
- front
- back
x-osserver-env: &default-osserver-env
AMOUNT_REPLICAS: ifenvelse(`REDIS_RO_SERVICE_REPLICAS', 3)
AUTOUPDATE_DELAY: ifenvelse(`AUTOUPDATE_DELAY', 1)
CONNECTION_POOL_LIMIT: ifenvelse(`CONNECTION_POOL_LIMIT', 100)
DATABASE_HOST: "ifenvelse(`DATABASE_HOST', pgbouncer)"
DATABASE_PASSWORD: "ifenvelse(`DATABASE_PASSWORD', openslides)"
DATABASE_PORT: ifenvelse(`DATABASE_PORT', 5432)
DATABASE_USER: "ifenvelse(`DATABASE_USER', openslides)"
DEFAULT_FROM_EMAIL: "ifenvelse(`DEFAULT_FROM_EMAIL', noreply@example.com)"
DJANGO_LOG_LEVEL: "ifenvelse(`DJANGO_LOG_LEVEL', INFO)"
EMAIL_HOST: "ifenvelse(`EMAIL_HOST', postfix)"
EMAIL_HOST_PASSWORD: "ifenvelse(`EMAIL_HOST_PASSWORD',)"
EMAIL_HOST_USER: "ifenvelse(`EMAIL_HOST_USER',)"
EMAIL_PORT: ifenvelse(`EMAIL_PORT', 25)
ENABLE_ELECTRONIC_VOTING: "ifenvelse(`ENABLE_ELECTRONIC_VOTING', False)"
ENABLE_SAML: "ifenvelse(`ENABLE_SAML', False)"
INSTANCE_DOMAIN: "ifenvelse(`INSTANCE_DOMAIN', http://example.com:8000)"
JITSI_DOMAIN: "ifenvelse(`JITSI_DOMAIN',)"
JITSI_ROOM_PASSWORD: "ifenvelse(`JITSI_ROOM_PASSWORD',)"
JITSI_ROOM_NAME: "ifenvelse(`JITSI_ROOM_NAME',)"
OPENSLIDES_LOG_LEVEL: "ifenvelse(`OPENSLIDES_LOG_LEVEL', INFO)"
REDIS_CHANNLES_HOST: "ifenvelse(`REDIS_CHANNLES_HOST', redis-channels)"
REDIS_CHANNLES_PORT: ifenvelse(`REDIS_CHANNLES_PORT', 6379)
REDIS_HOST: "ifenvelse(`REDIS_HOST', redis)"
REDIS_PORT: ifenvelse(`REDIS_PORT', 6379)
REDIS_SLAVE_HOST: "ifenvelse(`REDIS_SLAVE_HOST', redis-slave)"
REDIS_SLAVE_PORT: ifenvelse(`REDIS_SLAVE_PORT', 6379)
REDIS_SLAVE_WAIT_TIMEOUT: ifenvelse(`REDIS_SLAVE_WAIT_TIMEOUT', 10000)
RESET_PASSWORD_VERBOSE_ERRORS: "ifenvelse(`RESET_PASSWORD_VERBOSE_ERRORS', False)"
x-pgnode: &default-pgnode
image: ifenvelse(`DEFAULT_DOCKER_REGISTRY', openslides)/openslides-repmgr:latest
networks:
- dbnet
labels:
org.openslides.role: "postgres"
deploy:
replicas: 1
x-pgnode-env: &default-pgnode-env
REPMGR_RECONNECT_ATTEMPTS: 30
REPMGR_RECONNECT_INTERVAL: 10
REPMGR_WAL_ARCHIVE: "ifenvelse(`PGNODE_WAL_ARCHIVING', on)"
services:
server:
<< : *default-osserver
# 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"
environment:
<< : *default-osserver-env
secrets:
- django
ifelse(read_env(`ENABLE_SAML'), `True',- saml_cert
- saml_key
- saml_config)
deploy:
restart_policy:
condition: on-failure
delay: 5s
replicas: ifenvelse(`OPENSLIDES_BACKEND_SERVICE_REPLICAS', 1)
server-setup:
<< : *default-osserver
entrypoint: /usr/local/sbin/entrypoint-db-setup
environment:
<< : *default-osserver-env
secrets:
- django
ifelse(ADMIN_SECRET_AVAILABLE, 0,- os_admin)
ifelse(USER_SECRET_AVAILABLE, 0,- os_user)
ifelse(read_env(`ENABLE_SAML'), `True',- saml_cert
- saml_key
- saml_config)
client:
image: FRONTEND_IMAGE
networks:
- front
ports:
- "0.0.0.0:ifenvelse(`EXTERNAL_HTTP_PORT', 8000):80"
deploy:
replicas: ifenvelse(`OPENSLIDES_FRONTEND_SERVICE_REPLICAS', 1)
restart_policy:
condition: on-failure
delay: 5s
pgnode1:
<< : *default-pgnode
environment:
<< : *default-pgnode-env
REPMGR_NODE_ID: 1
REPMGR_PRIMARY: ifelse(PRIMARY_DB, pgnode1, `# This is the primary', PRIMARY_DB)
deploy:
placement:
constraints: ifenvelse(`PGNODE_1_PLACEMENT_CONSTR', [node.labels.openslides-db == dbnode1])
volumes:
- "dbdata1:/var/lib/postgresql"
ifelse(read_env(`PGNODE_2_ENABLED'), 1, `'
pgnode2:
<< : *default-pgnode
environment:
<< : *default-pgnode-env
REPMGR_NODE_ID: 2
REPMGR_PRIMARY: ifelse(PRIMARY_DB, pgnode2, `# This is the primary', PRIMARY_DB)
deploy:
placement:
constraints: ifenvelse(`PGNODE_2_PLACEMENT_CONSTR', [node.labels.openslides-db == dbnode2])
volumes:
- "dbdata2:/var/lib/postgresql")
ifelse(read_env(`PGNODE_3_ENABLED'), 1, `'
pgnode3:
<< : *default-pgnode
environment:
<< : *default-pgnode-env
REPMGR_NODE_ID: 3
REPMGR_PRIMARY: ifelse(PRIMARY_DB, pgnode3, `# This is the primary', PRIMARY_DB)
deploy:
placement:
constraints: ifenvelse(`PGNODE_3_PLACEMENT_CONSTR', [node.labels.openslides-db == dbnode3])
volumes:
- "dbdata3:/var/lib/postgresql")
pgbouncer:
environment:
- PG_NODE_LIST=pgnode1`'PGBOUNCER_NODELIST
image: ifenvelse(`DEFAULT_DOCKER_REGISTRY', openslides)/openslides-pgbouncer:latest
networks:
back:
aliases:
- db
- postgres
dbnet:
deploy:
restart_policy:
condition: on-failure
delay: 10s
placement:
constraints: ifenvelse(`PGBOUNCER_PLACEMENT_CONSTR', [node.role == manager])
postfix:
image: ifenvelse(`DEFAULT_DOCKER_REGISTRY', openslides)/openslides-postfix:latest
environment:
MYHOSTNAME: "ifenvelse(`POSTFIX_MYHOSTNAME', localhost)"
RELAYHOST: "ifenvelse(`POSTFIX_RELAYHOST', localhost)"
networks:
- back
deploy:
restart_policy:
condition: on-failure
delay: 5s
replicas: 1
placement:
constraints: [node.role == manager]
redis:
image: redis:alpine
networks:
back:
aliases:
- rediscache
deploy:
replicas: 1
restart_policy:
condition: on-failure
delay: 5s
redis-slave:
image: redis:alpine
command: ["redis-server", "--save", "", "--slaveof", "redis", "6379"]
networks:
back:
aliases:
- rediscache-slave
deploy:
replicas: ifenvelse(`REDIS_RO_SERVICE_REPLICAS', 3)
restart_policy:
condition: on-failure
delay: 5s
redis-channels:
image: redis:alpine
networks:
back:
deploy:
replicas: 1
restart_policy:
condition: on-failure
delay: 5s
media:
image: ifenvelse(`DEFAULT_DOCKER_REGISTRY', openslides)/openslides-media-service:latest
environment:
- CHECK_REQUEST_URL=server:8000/check-media/
deploy:
replicas: ifenvelse(`MEDIA_SERVICE_REPLICAS', 8)
restart_policy:
condition: on-failure
delay: 10s
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:
ifelse(read_env(`PGNODE_2_ENABLED'), 1, ` dbdata2:')
ifelse(read_env(`PGNODE_3_ENABLED'), 1, ` dbdata3:')
networks:
front:
back:
driver_opts:
encrypted: ""
dbnet:
driver_opts:
encrypted: ""
secrets:
django:
file: ./secrets/django.env
ifelse(ADMIN_SECRET_AVAILABLE, 0,os_admin:
file: ./secrets/adminsecret.env)
ifelse(USER_SECRET_AVAILABLE, 0,os_user:
file: ./secrets/usersecret.env)
ifelse(read_env(`ENABLE_SAML'), `True', saml_cert:
file: ./secrets/saml/sp.crt
saml_key:
file: ./secrets/saml/sp.key
saml_config:
file: ./secrets/saml/saml_settings.json)
# vim: set sw=2 et:

627
docker/initial-data.json Normal file
View File

@ -0,0 +1,627 @@
{
"organisation": [
{
"id": 1,
"legal_notice": "<a href=\"http://www.openslides.org\">OpenSlides</a> is a free web based presentation and assembly system for visualizing and controlling agenda, motions and elections of an assembly.",
"openslides_theme": "openslides-theme",
"committee_ids": [1],
"role_ids": [1],
"superadmin_role_id": 1,
"resource_ids": []
}],
"user": [
{
"id": 1,
"username": "admin",
"title": "",
"first_name": "",
"last_name": "Administrator",
"is_active": true,
"is_committee": false,
"password": "1422e767c5e08bb7196844025a0f98e1x61Ey612Kl2gpFL56FT9weDnpSo4AV8j8+qx2AuTHdRyY036xxzTTrw10Wq3+4qQyB+XURPWx1ONxp3Y3pB37A==",
"default_password": "admin",
"about_me": "",
"gender": "",
"comment": "",
"number": "",
"structure_level": "",
"email": "",
"last_email_send": null,
"vote_weight": "1.000000",
"role_id": 1,
"is_present_in_meeting_ids": [],
"meeting_id": null,
"guest_meeting_ids": [],
"committee_as_member_ids": [],
"committee_as_manager_ids": [],
"projection_ids": [],
"current_projector_ids": [],
"group_$_ids": ["1"],
"group_1_ids": [2],
"speaker_$_ids": [],
"personal_note_$_ids": [],
"supported_motion_$_ids": [],
"submitted_motion_$_ids": [],
"motion_poll_voted_$_ids": [],
"motion_vote_$_ids": [],
"assignment_candidate_$_ids": [],
"assignment_poll_voted_$_ids": [],
"assignment_option_$_ids": [],
"assignment_vote_$_ids": []
}],
"role": [
{
"id": 1,
"name": "Superadmin role",
"permissions": [],
"organisation_id": 1,
"superadmin_role_for_organisation_id": 1,
"user_ids": [1]
}],
"resource": [],
"committee": [
{
"id": 1,
"name": "Default committee",
"description": "Add description here",
"meeting_ids": [1],
"template_meeting_id": null,
"default_meeting_id": 1,
"member_ids": [],
"manager_ids": [],
"forward_to_committee_ids": [],
"receive_forwardings_from_committee_ids": [],
"organisation_id": 1
}],
"meeting": [
{
"id": 1,
"url_name": "os3_test",
"template_for_committee_id": null,
"enable_anonymous": false,
"name": "OpenSlides - Die Veranstaltung (Teil II)",
"description": "Presentation and assembly system",
"location": "",
"start_time": 0,
"end_time": 0,
"welcome_title": "Welcome to OpenSlides",
"welcome_text": "[Space for your welcome text.]",
"custom_translations": [],
"conference_show": false,
"conference_auto_connect": false,
"conference_los_restriction": false,
"conference_stream_url": "",
"projector_default_countdown_time": 60,
"projector_countdown_warning_time": 0,
"export_csv_encoding": "utf-8",
"export_csv_separator": ",",
"export_pdf_pagenumber_alignment": "center",
"export_pdf_fontsize": "10",
"export_pdf_pagesize": "A4",
"agenda_show_subtitles": false,
"agenda_enable_numbering": true,
"agenda_number_prefix": "",
"agenda_numeral_system": "arabic",
"agenda_item_creation": "default_yes",
"agenda_new_items_default_visibility": "2",
"agenda_show_internal_items_on_projector": false,
"list_of_speakers_amount_last_on_projector": 1,
"list_of_speakers_amount_next_on_projector": -1,
"list_of_speakers_couple_countdown": false,
"list_of_speakers_show_amount_of_speakers_on_slide": true,
"list_of_speakers_present_users_only": false,
"list_of_speakers_show_first_contribution": false,
"motions_default_workflow_id": 1,
"motions_statute_amendment_workflow_id": 1,
"motions_preamble": "The assembly may decide:",
"motions_default_line_numbering": "none",
"motions_line_length": 90,
"motions_reason_required": false,
"motions_enable_text_on_projector": true,
"motions_enable_reason_on_projector": true,
"motions_enable_sidebox_on_projector": false,
"motions_enable_recommendation_on_projector": true,
"motions_show_referring_motions": true,
"motions_show_sequential_numbers": true,
"motions_recommendations_by": "",
"motions_statute_recommendations_by": "",
"motions_recommendation_text_mode": "original",
"motions_default_sorting": "number",
"motions_number_type": "per_category",
"motions_number_min_digits": 1,
"motions_number_with_blank": false,
"motions_statutes_enabled": true,
"motions_amendments_enabled": true,
"motions_amendments_in_main_list": true,
"motions_amendments_of_amendments": false,
"motions_amendments_prefix": "-",
"motions_amendments_text_mode": "freestyle",
"motions_amendments_multiple_paragraphs": true,
"motions_supporters_min_amount": 1,
"motions_supporters_autoremove": false,
"motions_export_title": "Motions",
"motions_export_preamble": "",
"motions_export_submitter_recommendation": false,
"motions_export_follow_recommendation": false,
"motion_poll_ballot_paper_selection": "CUSTOM_NUMBER",
"motion_poll_ballot_paper_number": 8,
"motion_poll_default_type": "analog",
"motion_poll_default_100_percent_base": "YNA",
"motion_poll_default_majority_method": "simple",
"motion_poll_default_group_ids": [2, 3],
"users_sort_by": "first_name",
"users_enable_presence_view": true,
"users_enable_vote_weight": true,
"users_allow_self_set_present": true,
"users_pdf_welcometitle": "Welcome to OpenSlides",
"users_pdf_welcometext": "[Place for your welcome and help text.]",
"users_pdf_url": "http://example.com:8000",
"users_pdf_wlan_ssid": "",
"users_pdf_wlan_password": "",
"users_pdf_wlan_encryption": "",
"users_email_sender": "noreply@yourdomain.com",
"users_email_replyto": "",
"users_email_subject": "Your login for {event_name}",
"users_email_body": "Dear {name},\n\nthis is your OpenSlides login for the event {event_name}:\n\n {url}\n username: {username}\n password: {password}\n\nThis email was generated automatically.",
"assignments_export_title": "Elections",
"assignments_export_preamble": "",
"assignment_poll_add_candidates_to_list_of_speakers": true,
"assignment_poll_sort_poll_result_by_votes": true,
"assignment_poll_default_type": "nominal",
"assignment_poll_default_method": "votes",
"assignment_poll_default_100_percent_base": "valid",
"assignment_poll_default_majority_method": "simple",
"assignment_poll_default_group_ids": [3, 5],
"projector_ids": [1],
"projectiondefault_ids": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
"projector_message_ids": [],
"projector_countdown_ids": [],
"tag_ids": [],
"agenda_item_ids": [],
"list_of_speakers_ids": [],
"topic_ids": [],
"group_ids": [1, 2, 3, 5, 6],
"mediafile_ids": [],
"motion_ids": [],
"motion_comment_section_ids": [],
"motion_category_ids": [],
"motion_block_ids": [],
"motion_workflow_ids": [1],
"motion_statute_paragraph_ids": [],
"motion_poll_ids": [],
"assignment_ids": [],
"assignment_poll_ids": [],
"logo_$_id": [],
"font_$_id": [],
"committee_id": 1,
"default_meeting_for_committee_id": 1,
"present_user_ids": [],
"temorary_user_ids": [],
"guest_ids": [],
"user_ids": [],
"reference_projector_id": 2,
"default_group_id": 1,
"superadmin_group_id": 2
}],
"group": [
{
"id": 1,
"name": "Default",
"superadmin_group_for_meeting_id": null,
"default_group_for_meeting_id": 1,
"permissions": [
"agenda.can_see",
"agenda.can_see_internal_items",
"assignments.can_see",
"core.can_see_frontpage",
"core.can_see_projector",
"mediafiles.can_see",
"motions.can_see",
"users.can_see_name"
],
"user_ids": [],
"mediafile_access_group_ids": [],
"read_comment_section_ids": [],
"write_comment_section_ids": [],
"motion_poll_ids": [],
"assignment_poll_ids": [],
"used_as_motion_poll_default_id": null,
"used_as_assignment_poll_default_id": null,
"meeting_id": 1
},
{
"id": 2,
"name": "Admin",
"superadmin_group_for_meeting_id": 1,
"default_group_for_meeting_id": null,
"permissions": [],
"user_ids": [],
"mediafile_access_group_ids": [],
"mediafile_inherited_access_group_ids": [],
"read_comment_section_ids": [],
"write_comment_section_ids": [],
"motion_poll_ids": [],
"assignment_poll_ids": [],
"used_as_motion_poll_default_id": 1,
"used_as_assignment_poll_default_id": null,
"meeting_id": 1
},
{
"id": 3,
"name": "Staff",
"superadmin_group_for_meeting_id": null,
"default_group_for_meeting_id": null,
"permissions": [
"agenda.can_manage",
"agenda.can_see",
"agenda.can_see_internal_items",
"agenda.can_be_speaker",
"assignments.can_manage",
"assignments.can_nominate_other",
"assignments.can_nominate_self",
"assignments.can_see",
"core.can_manage_projector",
"core.can_see_frontpage",
"core.can_see_projector",
"core.can_manage_tags",
"mediafiles.can_manage",
"mediafiles.can_see",
"motions.can_create",
"motions.can_manage",
"motions.can_see",
"users.can_manage",
"users.can_see_extra_data",
"users.can_see_name"
],
"user_ids": [],
"mediafile_access_group_ids": [],
"mediafile_inherited_access_group_ids": [],
"read_comment_section_ids": [],
"write_comment_section_ids": [],
"motion_poll_ids": [],
"assignment_poll_ids": [],
"used_as_motion_poll_default_id": 1,
"used_as_assignment_poll_default_id": 1,
"meeting_id": 1
},
{
"id": 5,
"name": "Committees",
"superadmin_group_for_meeting_id": null,
"default_group_for_meeting_id": null,
"permissions": [
"agenda.can_see",
"agenda.can_see_internal_items",
"assignments.can_see",
"core.can_see_frontpage",
"core.can_see_projector",
"mediafiles.can_see",
"motions.can_create",
"motions.can_see",
"motions.can_support",
"users.can_see_name"
],
"user_ids": [],
"mediafile_access_group_ids": [],
"read_comment_section_ids": [],
"write_comment_section_ids": [],
"motion_poll_ids": [],
"assignment_poll_ids": [],
"used_as_motion_poll_default_id": null,
"used_as_assignment_poll_default_id": 1,
"meeting_id": 1
},
{
"id": 6,
"name": "Delegates",
"superadmin_group_for_meeting_id": null,
"default_group_for_meeting_id": null,
"permissions": [
"agenda.can_see",
"agenda.can_see_internal_items",
"agenda.can_be_speaker",
"assignments.can_nominate_other",
"assignments.can_nominate_self",
"assignments.can_see",
"core.can_see_frontpage",
"core.can_see_projector",
"mediafiles.can_see",
"motions.can_create",
"motions.can_manage",
"motions.can_see",
"motions.can_support",
"users.can_see_name"
],
"user_ids": [],
"mediafile_access_group_ids": [],
"read_comment_section_ids": [],
"write_comment_section_ids": [],
"motion_poll_ids": [],
"assignment_poll_ids": [],
"used_as_motion_poll_default_id": null,
"used_as_assignment_poll_default_id": null,
"meeting_id": 1
}],
"personal_note": [],
"tag": [],
"agenda_item": [],
"list_of_speakers": [],
"speaker": [],
"topic": [],
"motion": [],
"motion_submitter": [],
"motion_comment": [],
"motion_comment_section": [],
"motion_category": [],
"motion_block": [],
"motion_change_recommendation": [],
"motion_state": [
{
"id": 1,
"name": "submitted",
"recommendation_label": null,
"css_class": "lightblue",
"restrictions": [],
"allow_support": true,
"allow_create_poll": true,
"allow_submitter_edit": true,
"set_number": true,
"show_state_extension_field": false,
"merge_amendment_into_final": 0,
"show_recommendation_extension_field": false,
"next_state_ids": [2, 3, 4],
"previous_state_ids": [],
"motion_ids": [],
"motion_recommendation_ids": [],
"workflow_id": 1,
"first_state_of_workflow_id": 1
},
{
"id": 2,
"name": "accepted",
"recommendation_label": "Acceptance",
"css_class": "green",
"restrictions": [],
"allow_support": false,
"allow_create_poll": false,
"allow_submitter_edit": false,
"set_number": true,
"show_state_extension_field": false,
"merge_amendment_into_final": 0,
"show_recommendation_extension_field": false,
"next_state_ids": [],
"previous_state_ids": [1],
"motion_ids": [],
"motion_recommendation_ids": [],
"workflow_id": 1,
"first_state_of_workflow_id": null
},
{
"id": 3,
"name": "rejected",
"recommendation_label": "Rejection",
"css_class": "red",
"restrictions": [],
"allow_support": false,
"allow_create_poll": false,
"allow_submitter_edit": false,
"set_number": true,
"show_state_extension_field": false,
"merge_amendment_into_final": 0,
"show_recommendation_extension_field": false,
"next_state_ids": [],
"previous_state_ids": [1],
"motion_ids": [],
"motion_recommendation_ids": [],
"workflow_id": 1,
"first_state_of_workflow_id": null
},
{
"id": 4,
"name": "not decided",
"recommendation_label": "No decision",
"css_class": "grey",
"restrictions": [],
"allow_support": false,
"allow_create_poll": false,
"allow_submitter_edit": false,
"set_number": true,
"show_state_extension_field": false,
"merge_amendment_into_final": 0,
"show_recommendation_extension_field": false,
"next_state_ids": [],
"previous_state_ids": [1],
"motion_ids": [],
"motion_recommendation_ids": [],
"workflow_id": 1,
"first_state_of_workflow_id": null
}
],
"motion_workflow": [
{
"id": 1,
"name": "Simple Workflow",
"state_ids": [1, 2, 3, 4],
"first_state_id": 1,
"default_workflow_meeting_id": 1,
"default_statute_amendments_meeting_id": 1,
"meeting_id": 1
}],
"motion_statute_paragraph": [],
"motion_poll": [],
"motion_option": [],
"motion_vote": [],
"assignment": [],
"assignment_candidate": [],
"assignment_poll": [],
"assignment_option": [],
"assignment_vote": [],
"mediafile": [],
"projector": [
{
"id": 1,
"name": "Default projector",
"scale": 0,
"scroll": 0,
"width": 1220,
"aspect_ratio_numerator": 4,
"aspect_ratio_denominator": 3,
"color": "#000000",
"background_color": "#ffffff",
"header_background_color": "#317796",
"header_font_color": "#f5f5f5",
"header_h1_color": "#317796",
"chyron_background_color": "#317796",
"chyron_font_color": "#ffffff",
"show_header_footer": true,
"show_title": true,
"show_logo": true,
"current_projection_ids": [],
"current_element_ids": [],
"preview_projection_ids": [],
"history_projection_ids": [],
"used_as_reference_projector_meeting_id": null,
"projectiondefault_ids": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
"meeting_id": 1
}],
"projection": [],
"projectiondefault": [
{
"id": 1,
"name": "agenda_all_items",
"display_name": "Agenda",
"projector_id": 1,
"meeting_id": 1
},
{
"id": 2,
"name": "topics",
"display_name": "Topics",
"projector_id": 1,
"meeting_id": 1
},
{
"id": 3,
"name": "agenda_list_of_speakers",
"display_name": "List of speakers",
"projector_id": 1,
"meeting_id": 1
},
{
"id": 4,
"name": "agenda_current_list_of_speakers",
"display_name": "Current list of speakers",
"projector_id": 1,
"meeting_id": 1
},
{
"id": 5,
"name": "motions",
"display_name": "Motions",
"projector_id": 1,
"meeting_id": 1
},
{
"id": 6,
"name": "motionBlocks",
"display_name": "Motion blocks",
"projector_id": 1,
"meeting_id": 1
},
{
"id": 7,
"name": "assignments",
"display_name": "Elections",
"projector_id": 1,
"meeting_id": 1
},
{
"id": 8,
"name": "users",
"display_name": "Participants",
"projector_id": 1,
"meeting_id": 1
},
{
"id": 9,
"name": "mediafiles",
"display_name": "Files",
"projector_id": 1,
"meeting_id": 1
},
{
"id": 10,
"name": "messages",
"display_name": "Messages",
"projector_id": 1,
"meeting_id": 1
},
{
"id": 11,
"name": "countdowns",
"display_name": "Countdowns",
"projector_id": 1,
"meeting_id": 1
},
{
"id": 12,
"name": "assignment_poll",
"display_name": "Assignment poll",
"projector_id": 1,
"meeting_id": 1
},
{
"id": 13,
"name": "motion_poll",
"display_name": "Motion Poll",
"projector_id": 1,
"meeting_id": 1
}],
"projector_message": [],
"projector_countdown": []
}

14
docker/reset-admin-password.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
set -e
# hash the new password
response=$(docker-compose exec auth curl --header "Content-Type: application/json" -d '{"toHash": "admin"}' http://localhost:9004/internal/auth/hash)
hash=$(jq .hash <<< $response)
# Set user/1/password to $hash
request_data_prefix='{"user_id": 1, "information": {}, "locked_fields": {}, "events": [{"type": "update", "fqid": "user/1", "fields": {"password":'
request_data="$request_data_prefix $hash}}]}"
docker-compose exec backend curl --header "Content-Type: application/json" -d "$request_data" http://datastore-writer:9011/internal/datastore/writer/write
echo "Done"

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"

23
docker/services.env Normal file
View File

@ -0,0 +1,23 @@
MESSAGE_BUS_HOST=message-bus
MESSAGE_BUS_PORT=6379
DATASTORE_READER_HOST=datastore-reader
DATASTORE_READER_PORT=9010
DATASTORE_WRITER_HOST=datastore-writer
DATASTORE_WRITER_PORT=9011
DATASTORE_DATABASE_HOST=postgres
ACTION_HOST=backend
ACTION_PORT=9002
PRESENTER_HOST=backend
PRESENTER_PORT=9003
AUTH_HOST=auth
AUTH_PORT=9004
CACHE_HOST=cache
CACHE_PORT=6379
MEDIA_HOST=media
MEDIA_PORT=9006
MEDIA_DATABASE_HOST=postgres
MEDIA_DATABASE_NAME=openslides

11
docker/setup-prod.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
# Create keys for auth, if they do not exist
if [ ! -d keys ]; then
mkdir keys
ssh-keygen -f keys/rsa-token.key -t rsa -b 2048 -P ""
ssh-keygen -f keys/rsa-cookie.key -t rsa -b 2048 -P ""
fi
( set -a; source .env; m4 docker-compose.yml.m4 ) > docker-compose.yml

View File

@ -1,4 +1,5 @@
FROM haproxy:2.0-alpine
COPY src/haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
COPY src/prod-haproxy.cfg /usr/local/etc/haproxy/prod-haproxy.cfg
CMD ["haproxy", "-f", "/usr/local/etc/haproxy/haproxy.cfg", "-f", "/usr/local/etc/haproxy/prod-haproxy.cfg"]
COPY src/haproxy.prod.cfg /usr/local/etc/haproxy/haproxy.prod.cfg
COPY src/combined.pem /usr/local/etc/haproxy/combined.pem
CMD ["haproxy", "-f", "/usr/local/etc/haproxy/haproxy.cfg", "-f", "/usr/local/etc/haproxy/haproxy.prod.cfg"]

View File

@ -1,5 +1,5 @@
FROM haproxy:2.0-alpine
COPY src/haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
COPY src/dev-haproxy.cfg /usr/local/etc/haproxy/dev-haproxy.cfg
COPY src/haproxy.dev.cfg /usr/local/etc/haproxy/haproxy.dev.cfg
COPY src/combined.pem /usr/local/etc/haproxy/combined.pem
CMD ["haproxy", "-f", "/usr/local/etc/haproxy/haproxy.cfg", "-f", "/usr/local/etc/haproxy/dev-haproxy.cfg"]
CMD ["haproxy", "-f", "/usr/local/etc/haproxy/haproxy.cfg", "-f", "/usr/local/etc/haproxy/haproxy.dev.cfg"]

3
haproxy/build.sh Executable file
View File

@ -0,0 +1,3 @@
./prepare-cert.sh
docker build --tag "${img:-openslides/openslides-haproxy:latest}" \
--pull "${OPTIONS[@]}" .

@ -1 +1 @@
Subproject commit e22160c0b953fbbe01eb1e79c72bdf0701d5e288
Subproject commit 12af349d2d90246d3492939278d09872c2f40f44

@ -1 +1 @@
Subproject commit 32b809bc2d6a046b267e01fb2dd641d9eff64093
Subproject commit 9938ed0e73793f98aac2d2d5ef246f2301e85855