Compare commits

..

7 Commits

23 changed files with 477 additions and 131 deletions

View File

@ -66,7 +66,15 @@ defaults_applications:
matomo_tracking_enabled: "{{matomo_tracking_enabled_default}}" # Enables\Disables Matomo Tracking matomo_tracking_enabled: "{{matomo_tracking_enabled_default}}" # Enables\Disables Matomo Tracking
css_enabled: "{{css_enabled_default}}" # Enables\Disables Global CSS Style css_enabled: "{{css_enabled_default}}" # Enables\Disables Global CSS Style
landingpage_iframe_enabled: "{{landingpage_iframe_enabled_default}}" # Enables\Disables the possibility to embed this on landing page via iframe landingpage_iframe_enabled: "{{landingpage_iframe_enabled_default}}" # Enables\Disables the possibility to embed this on landing page via iframe
credentials:
# shared_secret: # Needs to be defined in inventory file
# etherpad_api_key: # Needs to be defined in inventory file
# rails_secret: # Needs to be defined in inventory file
# postgresql_secret: # Needs to be defined in inventory file
# fsesl_password: # Needs to be defined in inventory file
# turn_secret: # Needs to be defined in inventory file
urls:
api: "https://{{domains.bigbluebutton}}/bigbluebutton/" # API Address used by Nextcloud Integration
## Bluesky ## Bluesky
bluesky: bluesky:
users: users:
@ -197,7 +205,7 @@ defaults_applications:
import_realm: True # If True realm will be imported. If false skip. import_realm: True # If True realm will be imported. If false skip.
database: database:
central_storage: True # Activate Central Database Storage central_storage: True # Activate Central Database Storage
# database_password: # Needs to be defined in inventory file # database_password: # Needs to be defined in inventory file
# administrator_password: # Needs to be defined in inventory file # administrator_password: # Needs to be defined in inventory file
matomo_tracking_enabled: "{{matomo_tracking_enabled_default}}" # Enables\Disables Matomo Tracking matomo_tracking_enabled: "{{matomo_tracking_enabled_default}}" # Enables\Disables Matomo Tracking
css_enabled: "{{css_enabled_default}}" # Enables\Disables Global CSS Style css_enabled: "{{css_enabled_default}}" # Enables\Disables Global CSS Style
@ -699,12 +707,14 @@ defaults_applications:
## Taiga ## Taiga
taiga: taiga:
version: "latest" version: "latest"
database: database:
central_storage: True # Activate Central Database Storage central_storage: True # Activate Central Database Storage
matomo_tracking_enabled: "{{matomo_tracking_enabled_default}}" # Enables\Disables Matomo Tracking matomo_tracking_enabled: "{{matomo_tracking_enabled_default}}" # Enables\Disables Matomo Tracking
css_enabled: "{{css_enabled_default}}" # Enables\Disables Global CSS Style css_enabled: "{{css_enabled_default}}" # Enables\Disables Global CSS Style
landingpage_iframe_enabled: "{{landingpage_iframe_enabled_default}}" # Enables\Disables the possibility to embed this on landing page via iframe landingpage_iframe_enabled: "{{landingpage_iframe_enabled_default}}" # Enables\Disables the possibility to embed this on landing page via iframe
oidc:
enabled: True # Activate OIDC for Mastodon
## YOURLS ## YOURLS
yourls: yourls:
@ -716,10 +726,10 @@ defaults_applications:
enabled: true enabled: true
application: "application" application: "application"
port: "80" port: "80"
location: "/admin/" # Protects the admin area location: "/admin/" # Protects the admin area
# cookie_secret: None # Set via openssl rand -hex 16 # cookie_secret: None # Set via openssl rand -hex 16
database: database:
central_storage: True # Activate Central Database Storage central_storage: True # Activate Central Database Storage
matomo_tracking_enabled: "{{matomo_tracking_enabled_default}}" # Enables\Disables Matomo Tracking matomo_tracking_enabled: "{{matomo_tracking_enabled_default}}" # Enables\Disables Matomo Tracking
css_enabled: "{{css_enabled_default}}" # Enables\Disables Global CSS Style css_enabled: "{{css_enabled_default}}" # Enables\Disables Global CSS Style
landingpage_iframe_enabled: "{{landingpage_iframe_enabled_default}}" # Enables\Disables the possibility to embed this on landing page via iframe landingpage_iframe_enabled: "{{landingpage_iframe_enabled_default}}" # Enables\Disables the possibility to embed this on landing page via iframe

View File

@ -10,7 +10,7 @@
- name: Set fact for backup_docker_to_local_folder - name: Set fact for backup_docker_to_local_folder
set_fact: set_fact:
backup_docker_to_local_folder: "{{ pkgmgr_output.stdout }}" backup_docker_to_local_folder: "{{ pkgmgr_output.stdout }}/"
when: run_once_backup_docker_to_local is not defined when: run_once_backup_docker_to_local is not defined
- name: configure backup-docker-to-local-everything.cymais.service - name: configure backup-docker-to-local-everything.cymais.service

View File

@ -1,16 +0,0 @@
## Administration
## cleanup
```bash
docker compose down -v
```
## check container status
```bash
watch -n 2 "docker compose ps -a"
```
## database access
```bash
sudo docker-compose exec -it postgres psql -U postgres
```

View File

@ -1,19 +1,47 @@
# docker bigbluebutton # Docker BigBlueButton 📡
@TODO Database needs to be decoupled
Role to deploy [BigBlueButton](https://bigbluebutton.org/). ## Description
## SSO This Ansible role deploys [BigBlueButton](https://bigbluebutton.org/) using Docker Compose. It includes support for Greenlight, OIDC, LDAP, TURN/STUN, health checks, and a modular `.env` setup. This role is ideal for educational institutions and teams requiring a self-hosted video conferencing solution.
- https://docs.bigbluebutton.org/greenlight/v3/external-authentication/
## Other Resources > 🔧 **Note**: The database layer should be decoupled in a future release to improve modularity and integration.
- https://github.com/bigbluebutton/docker
- https://docs.bigbluebutton.org/greenlight/gl-install.html#setting-bigbluebutton-credentials ## Overview
- https://goneuland.de/big-blue-button-mit-docker-und-traefik-installieren/
- https://github.com/docker/compose/issues/4799 This role provides a fully automated deployment of [BigBlueButton](https://bigbluebutton.org/) using Docker Compose on Arch Linux. It manages the entire lifecycle of the deployment, from cloning the upstream Docker repository and generating the `.env` configuration to customizing `docker-compose.yml` for volume usage, WebSocket proxying, and optional LDAP/OIDC integration.
- https://www.cyberciti.biz/faq/linux-command-to-remove-virtual-interfaces-or-network-aliases/
- https://www.cyberciti.biz/faq/linux-restart-network-interface/ The setup includes conditional Greenlight activation, WebRTC support via TURN/STUN, and various fixes for known container orchestration issues. The role is modular and integrates seamlessly with the CyMaIS infrastructure, including reverse proxy configuration, domain management, and secrets templating.
- https://stackoverflow.com/questions/53347951/docker-network-not-found
- https://github.com/bigbluebutton/docker/issues/325 By default, BigBlueButton is deployed with best-practice hardening, modular secrets, and support for multiple authentication methods and scalable storage backends.
- https://mattdyson.org/blog/2024/11/self-hosting-bluesky-pds/
- https://atproto.com/specs/handle#handle-resolution @toto micoservice für dynamische did auflösung implementieren ## Features
- 🐳 **Docker-based** deployment via official [bigbluebutton/docker](https://github.com/bigbluebutton/docker)
- ✅ **Greenlight** (v3) frontend support
- 🔐 **SSO with OIDC & LDAP** (optional)
- 🧱 Automatic `.env` templating and domain/Nginx integration
- 🛠 Volume patching and Docker Compose customization
- 📬 SMTP integration and Greenlight admin creation
- 🧪 Workarounds for known Docker Compose or Etherpad issues
## Single Sign-On (SSO)
- Docs: [External Authentication](https://docs.bigbluebutton.org/greenlight/v3/external-authentication/)
- Supports:
- ✅ OpenID Connect (OIDC)
- ✅ LDAP (with custom DN and filters)
- 🧩 Custom OAuth2 flows via ENV vars
## System Requirements
- Arch Linux with Docker, Compose, and Nginx roles pre-installed
- DNS and reverse proxy configuration using `nginx-docker-reverse-proxy`
- Functional email system for Greenlight SMTP
## Important Resources
- [BigBlueButton Docker Docs](https://docs.bigbluebutton.org/greenlight/gl-install.html#setting-bigbluebutton-credentials)
- [Networking Fixes & Issues](https://stackoverflow.com/questions/53347951/docker-network-not-found)
- [Traefik + Docker Tutorial](https://goneuland.de/big-blue-button-mit-docker-und-traefik-installieren/)
- [Etherpad Healthcheck Bug](https://chatgpt.com/c/67a0fc7e-5104-800f-bb6b-3731e2f83b7b)
- [Virtual Interfaces Cleanup](https://www.cyberciti.biz/faq/linux-command-to-remove-virtual-interfaces-or-network-aliases/)

View File

@ -0,0 +1,6 @@
# Setup
## Passwords
```bash
docker run --rm ruby:latest ruby -rsecurerandom -e 'puts SecureRandom.hex(64)'
```

View File

@ -2,29 +2,35 @@
- name: create docker-compose.yml for bigbluebutton - name: create docker-compose.yml for bigbluebutton
command: command:
cmd: bash ./scripts/generate-compose cmd: bash ./scripts/generate-compose
chdir: "{{docker_compose.directories.instance}}" chdir: "{{ bbb_repository_directory }}"
environment: environment:
COMPOSE_HTTP_TIMEOUT: 600 COMPOSE_HTTP_TIMEOUT: 600
DOCKER_CLIENT_TIMEOUT: 600 DOCKER_CLIENT_TIMEOUT: 600
listen: setup bigbluebutton listen: setup bigbluebutton
- name: replace postgres bind mount by volume mount - name: Copy docker-compose.yml from origin to final location
replace: ansible.builtin.copy:
path: "{{docker_compose_file}}" src: "{{ docker_compose_file_origine }}"
regexp: '\./postgres-data:/var/lib/postgresql/data' dest: "{{ docker_compose_file_final }}"
replace: 'database:/var/lib/postgresql/data' remote_src: yes
listen: setup bigbluebutton listen: setup bigbluebutton
- name: replace greenlight bind mount by volume mount - name: Replace bind mounts by named volume mounts
replace: ansible.builtin.replace:
path: "{{docker_compose_file}}" path: "{{ docker_compose_file_final }}"
regexp: '\./greenlight-data:/usr/src/app/storage' regexp: "{{ item.regexp }}"
replace: 'greenlight:/usr/src/app/storage' replace: "{{ item.replace }}"
loop:
- { regexp: '\./data/postgres:/var/lib/postgresql/data', replace: 'database:/var/lib/postgresql/data' }
- { regexp: '\./data/bigbluebutton:/var/bigbluebutton', replace: 'bigbluebutton:/var/bigbluebutton' }
- { regexp: '\./data/freeswitch-meetings:/var/freeswitch/meetings', replace: 'freeswitch:/var/freeswitch/meetings' }
- { regexp: '\./data/greenlight:/usr/src/app/storage', replace: 'greenlight:/usr/src/app/storage' }
- { regexp: '\./data/mediasoup:/var/mediasoup', replace: 'mediasoup:/var/mediasoup' }
listen: setup bigbluebutton listen: setup bigbluebutton
- name: add volume to redis - name: add volume to redis
lineinfile: lineinfile:
path: "{{ docker_compose_file }}" path: "{{ docker_compose_file_final }}"
insertafter: "^\\s*redis:" insertafter: "^\\s*redis:"
line: " volumes:\n - redis:/data" line: " volumes:\n - redis:/data"
firstmatch: yes firstmatch: yes
@ -32,7 +38,7 @@
- name: add volume to coturn - name: add volume to coturn
lineinfile: lineinfile:
path: "{{ docker_compose_file }}" path: "{{ docker_compose_file_final }}"
insertafter: "- ./mod/coturn/turnserver.conf:/etc/coturn/turnserver.conf" insertafter: "- ./mod/coturn/turnserver.conf:/etc/coturn/turnserver.conf"
line: " - coturn:/var/lib/coturn" line: " - coturn:/var/lib/coturn"
listen: setup bigbluebutton listen: setup bigbluebutton
@ -40,30 +46,54 @@
# Implemented due to etherpad health bug. # Implemented due to etherpad health bug.
# @todo Remove when health check is working fine # @todo Remove when health check is working fine
# @see https://chatgpt.com/c/67a0fc7e-5104-800f-bb6b-3731e2f83b7b # @see https://chatgpt.com/c/67a0fc7e-5104-800f-bb6b-3731e2f83b7b
- name: "Update docker-compose.yml for Etherpad health check" #- name: "Update docker-compose.yml for Etherpad health check"
lineinfile: # lineinfile:
line: " healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://127.0.0.1:9001\"]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 10s" # line: " healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://127.0.0.1:9001\"]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 10s"
path: "{{docker_compose_file}}" # path: "{{docker_compose_file_final}}"
insertafter: "etherpad:" # insertafter: "etherpad:"
listen: setup bigbluebutton # listen: setup bigbluebutton
- name: add volumes to docker compose - name: Add volumes block after services in docker compose
blockinfile: blockinfile:
path: "{{docker_compose_file}}" path: "{{ docker_compose_file_final }}"
block: |2 block: |
volumes:
database: database:
greenlight: greenlight:
redis: redis:
coturn: coturn:
#freeswitch:
bigbluebutton:
marker: "# {mark} ANSIBLE MANAGED BLOCK FOR VOLUMES" marker: "# {mark} ANSIBLE MANAGED BLOCK FOR VOLUMES"
insertafter: "html5-static:" insertbefore: "^services:"
listen: setup bigbluebutton
- name: Replace all './' with '/services/' in docker-compose.yml
ansible.builtin.replace:
path: "{{ docker_compose_file_final }}"
regexp: '\./'
replace: './services/'
listen: setup bigbluebutton
- name: "Update healthcheck for bbb-graphql-server"
# This is neccessary because the healthcheck doesn't listen to the correct port
lineinfile:
line: " healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8085/healthz\"]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 10s"
path: "{{docker_compose_file_final}}"
insertafter: "bbb-graphql-server:"
listen: setup bigbluebutton
- name: docker compose pull bigbluebutton
command:
cmd: "docker-compose pull"
chdir: "{{ bbb_repository_directory }}"
listen: setup bigbluebutton listen: setup bigbluebutton
- name: docker compose up bigbluebutton - name: docker compose up bigbluebutton
command: command:
cmd: "docker-compose -p bigbluebutton up -d --force-recreate{% if mode_cleanup | bool %} --remove-orphans{% endif %}" cmd: "docker-compose -p bigbluebutton up -d --force-recreate{% if mode_cleanup | bool %} --remove-orphans{% endif %}"
# Don't use the --build flag here. This leads to bugs # Don't use the --build flag here. This leads to bugs
chdir: "{{docker_compose.directories.instance}}" chdir: "{{ docker_compose.directories.instance }}"
environment: environment:
COMPOSE_HTTP_TIMEOUT: 600 COMPOSE_HTTP_TIMEOUT: 600
DOCKER_CLIENT_TIMEOUT: 600 DOCKER_CLIENT_TIMEOUT: 600

View File

@ -0,0 +1,28 @@
---
galaxy_info:
author: "Kevin Veen-Birkenbach"
description: "Deploys BigBlueButton with Greenlight and SSO"
license: "CyMaIS NonCommercial License (CNCL)"
license_url: "https://s.veen.world/cncl"
company: |
Kevin Veen-Birkenbach
Consulting & Coaching Solutions
https://www.veen.world
min_ansible_version: "2.9"
platforms:
- name: Archlinux
versions:
- rolling
galaxy_tags:
- docker
- bigbluebutton
- conferencing
- education
- greenlight
- sso
- oidc
- ldap
- archlinux
repository: https://s.veen.world/cymais
issue_tracker_url: https://s.veen.world/cymaisissues
documentation: https://s.veen.world/cymais

View File

@ -3,24 +3,18 @@
include_role: include_role:
name: docker-compose name: docker-compose
# Leave this in the code until big blue button was working for a while.
# This is necessary due to the reason that big blue button wasn't fully tested after refactoring
#
#- name: "include task certbot-and-globals.yml"
# include_tasks: certbot-and-globals.yml
#
#- name: configure {{domains[application_id]}}.conf
# template:
# src: "nginx-proxy.conf.j2"
# dest: "{{nginx.directories.http.servers}}{{domains[application_id]}}.conf"
# notify: restart nginx
- name: "include role nginx-domain-setup for {{application_id}}" - name: "include role nginx-domain-setup for {{application_id}}"
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars:
domain: "{{ domains[application_id] }}" - name: pull docker repository
http_port: "{{ ports.localhost.http[application_id] }}" git:
repo: "https://github.com/bigbluebutton/docker.git"
dest: "{{ bbb_repository_directory }}"
update: yes
recursive: yes
version: main
notify: setup bigbluebutton
- name: configure websocket_upgrade.conf - name: configure websocket_upgrade.conf
copy: copy:
@ -28,20 +22,23 @@
dest: "{{nginx.directories.http.maps}}websocket_upgrade.conf" dest: "{{nginx.directories.http.maps}}websocket_upgrade.conf"
notify: restart nginx notify: restart nginx
- name: pull docker repository - name: "Remove directory {{ docker_compose.directories.env }}"
git: ansible.builtin.file:
repo: "https://github.com/bigbluebutton/docker.git" path: "{{ docker_compose.directories.env }}"
dest: "{{docker_compose.directories.instance}}" state: absent
update: yes
recursive: yes
version: main
notify: setup bigbluebutton
ignore_errors: true
- name: deploy .env - name: deploy .env
template: src=env.j2 dest={{docker_compose.directories.instance}}/.env template:
src: env.j2
dest: "{{ bbb_env_file_origine }}"
notify: setup bigbluebutton notify: setup bigbluebutton
- name: Create symbolic link from .env file to target location
ansible.builtin.file:
src: "{{ bbb_env_file_origine }}"
dest: "{{ bbb_env_file_link }}"
state: link
- name: flush docker service - name: flush docker service
meta: flush_handlers meta: flush_handlers
@ -53,7 +50,7 @@
- name: create admin - name: create admin
command: command:
cmd: docker compose exec greenlight bundle exec rake admin:create cmd: docker compose exec greenlight bundle exec rake admin:create
chdir: "{{docker_compose.directories.instance}}" chdir: "{{ docker_compose.directories.instance }}"
when: applications.bigbluebutton.setup | bool when: applications.bigbluebutton.setup | bool
ignore_errors: true ignore_errors: true
register: admin_creation_result register: admin_creation_result

View File

@ -28,11 +28,11 @@ RECORDING_MAX_AGE_DAYS=365
# SECRETS # SECRETS
# ==================================== # ====================================
# important! change these to any random values # important! change these to any random values
SHARED_SECRET={{bigbluebutton_shared_secret}} SHARED_SECRET={{applications.bigbluebutton.shared_secret}}
ETHERPAD_API_KEY={{bigbluebutton_etherpad_api_key}} ETHERPAD_API_KEY={{applications.bigbluebutton.etherpad_api_key}}
RAILS_SECRET={{bigbluebutton_rails_secret}} RAILS_SECRET={{applications.bigbluebutton.rails_secret}}
POSTGRESQL_SECRET={{bigbluebutton_postgresql_secret}} POSTGRESQL_SECRET={{applications.bigbluebutton.postgresql_secret}}
FSESL_PASSWORD={{bigbluebutton_fsesl_password}} FSESL_PASSWORD={{applications.bigbluebutton.fsesl_password}}
@ -54,7 +54,7 @@ STUN_PORT={{ ports.public.stun[application_id] }}
# TURN SERVER # TURN SERVER
# uncomment and adjust following two lines to add an external TURN server # uncomment and adjust following two lines to add an external TURN server
TURN_SERVER=turns:{{domains[application_id]}}:{{ ports.public.turn[application_id] }}?transport=tcp TURN_SERVER=turns:{{domains[application_id]}}:{{ ports.public.turn[application_id] }}?transport=tcp
TURN_SECRET={{bigbluebutton_turn_secret}} TURN_SECRET={{applications.bigbluebutton.turn_secret}}
# Allowed SIP IPs # Allowed SIP IPs
# due to high traffic caused by bots, by default the SIP port is blocked. # due to high traffic caused by bots, by default the SIP port is blocked.

View File

@ -1,6 +1,12 @@
application_id: "bigbluebutton" application_id: "bigbluebutton"
docker_compose_file: "{{docker_compose.directories.instance}}docker-compose.yml" bbb_repository_directory: "{{ docker_compose.directories.services }}"
database_instance: "bigbluebutton" docker_compose_file_origine: "{{ docker_compose.directories.services }}docker-compose.yml"
database_name: "greenlight-v3" docker_compose_file_final: "{{ docker_compose.directories.instance }}docker-compose.yml"
database_username: "postgres" database_instance: "bigbluebutton"
database_password: "{{bigbluebutton_postgresql_secret}}" database_name: "greenlight-v3"
database_username: "postgres"
database_password: "{{applications.bigbluebutton.postgresql_secret}}"
domain: "{{ domains[application_id] }}"
http_port: "{{ ports.localhost.http[application_id] }}"
bbb_env_file_link: "{{ docker_compose.directories.instance }}.env"
bbb_env_file_origine: "{{ bbb_repository_directory }}.env"

View File

@ -0,0 +1,13 @@
# Docker Compose
## Delete all containers, networks and volumes
```bash
docker compose down -v
```
## Show the state of all containers
```bash
watch -n 2 "docker compose ps -a"
```

View File

@ -0,0 +1,14 @@
# Debug
## Bind for 127.0.0.1:XXXX failed: port is already allocated
If their are port allocated messages ``Bind for 127.0.0.1:XXXX failed: port is already allocated"`` execute the following command:
```bash
find /opt/docker -maxdepth 1 -type d -exec bash -c '[ -f "{}/docker-compose.yml" ] && echo "Stopping: {}" && docker compose -f "{}/docker-compose.yml" down' \; &
systemctl restart docker
find /opt/docker -maxdepth 1 -type d -exec bash -c '[ -f "{}/docker-compose.yml" ] && echo "Starting: {}" && docker compose -f "{}/docker-compose.yml" up -d' \; &
```
Then try to run the ansible script again.

View File

@ -0,0 +1,35 @@
# Docker Compose 🧱
## Description
This Ansible role manages Docker Compose project structures and workflows for applications on Arch Linux. It creates dedicated instance directories, manages `.env` and `docker-compose.yml` files, and provides automation logic for project reset, rebuild, and startup sequences.
Refer to the [Docker Compose documentation](https://docs.docker.com/compose/), the [Arch Wiki Docker](https://wiki.archlinux.org/title/Docker), and [Compose CLI reference](https://docs.docker.com/compose/cli-command/) for more details.
## Overview
This role creates a flexible directory layout for managing Docker Compose projects across environments. It ensures directories are initialized, optionally reset, and kept clean using internal flags like `mode_reset` or `mode_cleanup`.
## Purpose
To offer a centralized, extensible system for managing containerized applications using Docker Compose within the CyMaIS architecture. The role allows easy integration of services, secrets, configurations, and custom behaviors per application.
## Features
- **Dynamic Directory Structure:** Creates per-application instance folders for Compose setups.
- **Reset Logic:** Cleans previous Compose project files and data when `mode_reset` is enabled.
- **Handlers for Runtime Control:** Automatically builds, sets up, or restarts containers based on handlers.
- **Template-ready Service Files:** Predefined service base and health check templates.
- **Integration Support:** Compatible with `nginx-docker-reverse-proxy` and other CyMaIS service roles.
## Administration Tips
For administration tips checkout [this](Administration.md).
## Credits 📝
Developed and maintained by **Kevin Veen-Birkenbach**
Learn more at [www.veen.world](https://www.veen.world)
Part of the [CyMaIS Project](https://github.com/kevinveenbirkenbach/cymais)
License: [CyMaIS NonCommercial License (CNCL)](https://s.veen.world/cncl)

View File

@ -1,2 +1,28 @@
---
galaxy_info:
author: "Kevin Veen-Birkenbach"
description: "Manages Docker Compose project structure and execution logic on Arch Linux."
license: "CyMaIS NonCommercial License (CNCL)"
license_url: "https://s.veen.world/cncl"
company: |
Kevin Veen-Birkenbach
Consulting & Coaching Solutions
https://www.veen.world
min_ansible_version: "2.9"
platforms:
- name: Archlinux
versions:
- rolling
galaxy_tags:
- docker
- compose
- container
- infrastructure
- devops
- automation
- archlinux
repository: https://s.veen.world/cymais
issue_tracker_url: https://s.veen.world/cymaisissues
documentation: https://s.veen.world/cymais
dependencies: dependencies:
- nginx-docker-reverse-proxy - nginx-docker-reverse-proxy

View File

@ -0,0 +1,7 @@
plugin_configuration:
- appid: "bbb"
configkey: "api.secret"
configvalue: "{{ applications.bigbluebutton.credentials.shared_secret }}"
- appid: "bbb"
configkey: "api.url"
configvalue: "{{ applications.bigbluebutton.urls.api }}"

View File

@ -1,3 +1,5 @@
# Administration
## Root Access ## Root Access
To access the database via the root account execute the following on the server: To access the database via the root account execute the following on the server:
```bash ```bash

View File

@ -0,0 +1,92 @@
# PostgreSQL Docker Upgrade: Major Version Migration
This guide explains how to safely upgrade a PostgreSQL Docker container from one major version to another (e.g., version 12 to 16) using a **dump and restore** method. This is the recommended approach in Docker environments.
---
## ⚠️ Important
PostgreSQL data directories are **not compatible across major versions**. You cannot just point a newer version to the old data volume. You must export and re-import your data.
---
## 💾 Step 1: Start a temporary container with your current PostgreSQL version
Replace `<old-version>` with your current PostgreSQL version (e.g., `12`).
```bash
docker run --rm -d \
--name pg-old \
-v pgdata:/var/lib/postgresql/data \
postgres:<old-version>
```
This container mounts your old data volume and runs the matching PostgreSQL version.
---
## ⬇️ Step 2: Dump all databases
```bash
docker exec pg-old pg_dumpall -U postgres > backup.sql
```
Stop the old container:
```bash
docker stop pg-old
```
---
## 💥 Step 3: Remove the old data volume
```bash
docker volume rm pgdata
```
⚠️ This will permanently delete your old PostgreSQL data files. Make sure you have a successful backup (`backup.sql`) before running this!
---
## 📦 Step 4: Start a new container with your target PostgreSQL version
Replace `<new-version>` with the version you want to upgrade to (e.g., `16`).
```bash
docker run --rm -d \
--name pg-new \
-v pgdata:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=secret \
postgres:<new-version>
```
This creates a clean PostgreSQL instance with a fresh data directory.
---
## ⬆️ Step 5: Restore your data
```bash
cat backup.sql | docker exec -i pg-new psql -U postgres
```
This restores all roles, databases, and data into your new PostgreSQL instance.
---
## ✅ Done!
You now have the target PostgreSQL version running with your old data successfully restored.
---
## 📝 Tips
- Always test this procedure in a staging environment before running it in production.
- You can automate this with Ansible or a custom script.
- For large databases, consider using `pg_dump` per database and `pg_restore` with parallel jobs.
---
## 🔗 References
- [PostgreSQL Backup Documentation](https://www.postgresql.org/docs/current/backup-dump.html)
- [PostgreSQL Docker Image](https://hub.docker.com/_/postgres)

View File

@ -1,31 +1,52 @@
# Docker Taiga Role 🐳📋 # Docker Taiga 🐳📋
This Ansible role sets up and configures a Taiga project management platform using Docker. It includes tasks for setting up the database, Nginx proxy, and updating the repository with necessary files. ## Description
## Tasks [Taiga](https://www.taiga.io/) is a powerful and intuitive open-source project management platform tailored for agile teams. Whether you're practicing Scrum, Kanban, or a custom hybrid workflow, Taiga offers a rich, customizable environment to plan, track, and collaborate on your projects — without the complexity of enterprise tools or the vendor lock-in of SaaS platforms.
The main tasks included in this role are: This Ansible role deploys Taiga in a Docker-based environment, allowing fast, reproducible, and secure installations. It also optionally integrates [OpenID Connect (OIDC)](https://openid.net/connect/) for single sign-on via providers like Keycloak.
- Setting up the database. ---
- Configuring Nginx as a proxy.
- Updating the repository with necessary files.
## Variables ## Why Taiga?
Key variables used in this role include the Docker Compose project name, database type and password, and the repository address. Taiga is ideal for developers, designers, and agile teams who want:
## Templates - ✅ **Beautiful UI:** Clean, modern, and responsive interface.
- 📌 **Agile Workflows:** Supports Scrum, Kanban, Scrumban, and Epics.
- 🗃️ **Backlog & Sprint Management:** Create user stories, tasks, and sprints with ease.
- 📈 **Burn-down Charts & Metrics:** Monitor velocity and progress.
- 🔄 **Custom Workflows:** Define your own states, priorities, and permissions.
- 📎 **Attachments & Wiki:** Collaborate with file uploads and internal documentation.
- 🔐 **SSO/Authentication Plugins:** OpenID Connect, LDAP, GitHub, GitLab and more.
- 🌍 **Multilingual UI:** Used by teams worldwide.
The role includes several Jinja2 templates to configure the environment and Docker Compose setup, including: ---
- **docker-compose-inits.yml.j2** ## Purpose
- **.env.j2**
- **docker-compose.yml.j2** This role automates the deployment and configuration of a complete, production-ready Taiga stack using Docker Compose. It ensures integration with common infrastructure tools such as Nginx, PostgreSQL, and RabbitMQ, while optionally enabling OpenID Connect authentication for enterprise-grade SSO.
By using this role, teams can set up Taiga in minutes on Arch Linux systems — whether in a homelab, dev environment, or production cluster.
---
## Features
- 🐳 **Docker-Based Deployment:** Easy containerized setup of backend, frontend, async workers, and events service.
- 🛡️ **OIDC Support:** Seamless login integration with providers like Keycloak when `applications[application_id].oidc.enabled` is `true`.
- 📨 **Email Backend:** Supports SMTP and console backends for development.
- 🔁 **Async & Realtime Events:** Includes RabbitMQ and support for Taigas event system.
- 🌐 **Reverse Proxy Ready:** Integrates with Nginx using the `nginx-domain-setup` role.
- 🧩 **Composable Design:** Integrates cleanly with other CyMaIS infrastructure roles.
---
## Author ## Author
This role was created by Kevin Veen-Birkenbach. You can reach him at [kevin@veen.world](mailto:kevin@veen.world). Visit his website at [veen.world](https://www.veen.world/). Developed and maintained by **Kevin Veen-Birkenbach**
Email: [kevin@veen.world](mailto:kevin@veen.world)
Website: [veen.world](https://www.veen.world)
## Note Part of the [CyMaIS Project](https://github.com/kevinveenbirkenbach/cymais)
License: [CyMaIS NonCommercial License (CNCL)](https://s.veen.world/cncl)
This README was created with the assistance of ChatGPT. [Link to conversation](https://chatgpt.com/share/fee718ab-cfe1-46f3-b97f-8f8c896ffd11).

View File

@ -0,0 +1,26 @@
---
galaxy_info:
author: "Kevin Veen-Birkenbach"
description: "Deploy and configure the Taiga project management platform, with OpenID Connect support."
license: "CyMaIS NonCommercial License (CNCL)"
license_url: "https://s.veen.world/cncl"
company: |
Kevin Veen-Birkenbach
Consulting & Coaching Solutions
https://www.veen.world
min_ansible_version: "2.9"
platforms:
- name: Archlinux
versions:
- rolling
galaxy_tags:
- taiga
- docker
- project-management
- oidc
- openid
- archlinux
- cymais
repository: https://s.veen.world/cymais
issue_tracker_url: https://s.veen.world/cymaisissues
documentation: https://s.veen.world/cymais

View File

@ -2,7 +2,7 @@ services:
{% include 'roles/docker-central-database/templates/services/' + database_type + '.yml.j2' %} {% include 'roles/docker-central-database/templates/services/' + database_type + '.yml.j2' %}
taiga-back: taiga-back:
{% include 'roles/docker-compose/templates/services/base.yml.j2' %} {% include 'roles/docker-compose/templates/services/base.yml.j2' %}
image: taigaio/taiga-back:{{applications.taiga.version}} image: {{taiga_image_backend}}:{{applications.taiga.version}}
volumes: volumes:
# These volumens will be used by taiga-back and taiga-async. # These volumens will be used by taiga-back and taiga-async.
- static-data:/taiga-back/static - static-data:/taiga-back/static
@ -18,7 +18,7 @@ services:
taiga-async: taiga-async:
{% include 'roles/docker-compose/templates/services/base.yml.j2' %} {% include 'roles/docker-compose/templates/services/base.yml.j2' %}
image: taigaio/taiga-back:latest image: {{taiga_image_backend}}:{{applications.taiga.version}}
entrypoint: ["/taiga-back/docker/async_entrypoint.sh"] entrypoint: ["/taiga-back/docker/async_entrypoint.sh"]
volumes: volumes:
# These volumens will be used by taiga-back and taiga-async. # These volumens will be used by taiga-back and taiga-async.
@ -43,7 +43,7 @@ services:
taiga: taiga:
taiga-front: taiga-front:
image: taigaio/taiga-front:latest image: {{taiga_image_frontend}}:{{applications.taiga.version}}
{% include 'roles/docker-compose/templates/services/base.yml.j2' %} {% include 'roles/docker-compose/templates/services/base.yml.j2' %}
{% include 'templates/docker/container/networks.yml.j2' %} {% include 'templates/docker/container/networks.yml.j2' %}
taiga: taiga:

View File

@ -46,3 +46,22 @@ MAX_AGE = 360
# Taiga's Telemetry - Variable to enable or disable the anonymous telemetry # Taiga's Telemetry - Variable to enable or disable the anonymous telemetry
ENABLE_TELEMETRY = True ENABLE_TELEMETRY = True
{% if applications[application_id].oidc.enabled %}
# OICD
# @See https://github.com/robrotheram/taiga-contrib-openid-auth
ENABLE_OPENID="True"
OPENID_URL="{{oidc.client.authorize_url}}"
OPENID_USER_URL="{{oidc.client.user_info_url}}"
OPENID_TOKEN_URL="{{oidc.client.torken_url}}"
OPENID_CLIENT_ID="{{oidc.client.id}}"
OPENID_CLIENT_SECRET="{{oidc.client.secret}}"
OPENID_NAME="SSO"
# Default Values
#
# OPENID_ID_FIELD="sub"
# OPENID_USERNAME_FIELD="preferred_username"
# OPENID_FULLNAME_FIELD="name"
# OPENID_EMAIL_FIELD="email"
# OPENID_SCOPE="openid email"
{% endif %}

View File

@ -1,6 +1,8 @@
application_id: "taiga" application_id: "taiga"
database_type: "postgres" database_type: "postgres"
database_password: "{{taiga_database_password}}" database_password: "{{taiga_database_password}}"
docker_repository_address: "https://github.com/taigaio/taiga-docker" docker_repository_address: "https://github.com/taigaio/taiga-docker"
email_backend: "smtp" ## use an SMTP server or display the emails in the console (either "smtp" or "console") email_backend: "smtp" ## use an SMTP server or display the emails in the console (either "smtp" or "console")
docker_compose_init: "{{docker_compose.directories.instance}}docker-compose-inits.yml.j2" docker_compose_init: "{{docker_compose.directories.instance}}docker-compose-inits.yml.j2"
taiga_image_backend: "{{ 'robrotheram/taiga-back-openid' if applications[application_id].oidc.enabled else 'taigaio/taiga-back' }}"
taiga_image_frontend: "{{ 'robrotheram/taiga-front-openid' if applications[application_id].oidc.enabled else 'taigaio/taiga-front' }}"

View File

@ -1,7 +1,7 @@
--- ---
galaxy_info: galaxy_info:
author: "Kevin Veen-Birkenbach" author: "Kevin Veen-Birkenbach"
description: "Installs the GNU Compiler Collection (GCC)" description: "Installs the GNU Compiler Collection (GCC)."
license: "CyMaIS NonCommercial License (CNCL)" license: "CyMaIS NonCommercial License (CNCL)"
license_url: "https://s.veen.world/cncl" license_url: "https://s.veen.world/cncl"
company: | company: |