mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-06-25 03:38:59 +02:00
Compare commits
4 Commits
df538033d9
...
2997fb4f5f
Author | SHA1 | Date | |
---|---|---|---|
2997fb4f5f | |||
fe39a7f701 | |||
0eaaa73e23 | |||
a9c25a28c6 |
@ -649,7 +649,7 @@ defaults_applications:
|
||||
|
||||
## PHPMyAdmin
|
||||
phpmyadmin:
|
||||
version: "latest"
|
||||
version: "latest" # Use the latest phpmyadmin version
|
||||
autologin: false # This is a high security risk. Just activate this option if you know what you're doing
|
||||
oauth2_proxy:
|
||||
enabled: true
|
||||
@ -703,7 +703,6 @@ defaults_applications:
|
||||
matomo_tracking_enabled: "{{matomo_tracking_enabled_default}}" # Enables\Disables Matomo Tracking
|
||||
css_enabled: "{{css_enabled_default}}" # Enables\Disables Global CSS Style
|
||||
landingpage_iframe_enabled: true # Makes sense to make the documentary allways in iframe available
|
||||
|
||||
|
||||
## Taiga
|
||||
taiga:
|
||||
@ -714,7 +713,13 @@ defaults_applications:
|
||||
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
|
||||
oidc:
|
||||
enabled: True # Activate OIDC for Mastodon
|
||||
# Taiga doesn't have a functioning oidc support at the moment
|
||||
# See
|
||||
# - https://community.taiga.io/t/taiga-and-oidc-plugin/4866
|
||||
#
|
||||
# Due to this reason this plutin is deactivated atm
|
||||
enabled: False # De\Activate OIDC for Taiga
|
||||
|
||||
|
||||
## YOURLS
|
||||
yourls:
|
||||
|
@ -19,11 +19,11 @@ defaults_oidc:
|
||||
issuer_url: "{{_oidc_client_issuer_url}}" # Base URL of the OIDC provider (issuer)
|
||||
discovery_document: "{{_oidc_client_issuer_url}}/.well-known/openid-configuration" # URL for fetching the provider's configuration details
|
||||
authorize_url: "{{_oidc_client_issuer_url}}/protocol/openid-connect/auth" # Endpoint to start the authorization process
|
||||
toke_url: "{{_oidc_client_issuer_url}}/protocol/openid-connect/token" # Endpoint to exchange authorization codes for tokens (note: 'toke_url' may be a typo for 'token_url')
|
||||
token_url: "{{_oidc_client_issuer_url}}/protocol/openid-connect/token" # Endpoint to exchange authorization codes for tokens (note: 'token_url' may be a typo for 'token_url')
|
||||
user_info_url: "{{_oidc_client_issuer_url}}/protocol/openid-connect/userinfo" # Endpoint to retrieve user information
|
||||
logout_url: "{{_oidc_client_issuer_url}}/protocol/openid-connect/logout" # Endpoint to log out the user
|
||||
change_credentials: "{{_oidc_client_issuer_url}}account/account-security/signing-in" # URL for managing or changing user credentials
|
||||
|
||||
button_text: "SSO Login({{primary_domain | upper}})" # Default button text
|
||||
#############################################
|
||||
### LDAP ###
|
||||
#############################################
|
||||
@ -34,8 +34,6 @@ _ldap_dn_base: "dc={{primary_domain_sld}},dc={{primary_domain_tld}}"
|
||||
_ldap_server_port: "{% if applications.ldap.openldap.network.local | bool %}{{ ports.localhost.ldap.openldap }}{% else %}{{ ports.localhost.ldaps.openldap }}{% endif %}"
|
||||
|
||||
ldap:
|
||||
# Enables LDAP for all roles in play if true
|
||||
enabled: true
|
||||
# Distinguished Names (DN)
|
||||
dn:
|
||||
# Defines the base Distinguished Name (DN) for the LDAP directory, constructed from the second-level domain (SLD) and top-level domain (TLD).
|
||||
|
@ -294,4 +294,5 @@ OPENID_CONNECT_CLIENT_ID={{oidc.client.id}}
|
||||
OPENID_CONNECT_CLIENT_SECRET={{oidc.client.secret}}
|
||||
OPENID_CONNECT_ISSUER={{oidc.client.issuer_url}}
|
||||
OPENID_CONNECT_REDIRECT=https://{{domains[application_id]}}
|
||||
# OPENID_CONNECT_UID_FIELD=sub default
|
||||
{% endif %}
|
@ -60,7 +60,7 @@ SMTP_FROM_ADDRESS=Mastodon <{{system_email.from}}>
|
||||
# @see https://stackoverflow.com/questions/72081776/how-mastodon-configured-login-using-sso
|
||||
|
||||
OIDC_ENABLED={{ applications[application_id].oidc.enabled | string | lower }}
|
||||
OIDC_DISPLAY_NAME="{{primary_domain | upper}} SSO"
|
||||
OIDC_DISPLAY_NAME="{{oidc.button_text}}"
|
||||
OIDC_ISSUER={{oidc.client.issuer_url}}
|
||||
OIDC_DISCOVERY=true
|
||||
OIDC_SCOPE="openid,profile,email"
|
||||
|
@ -49,7 +49,7 @@ email:
|
||||
# @See https://matrix-org.github.io/synapse/latest/openid.html
|
||||
oidc_providers:
|
||||
- idp_id: keycloak
|
||||
idp_name: "{{primary_domain | upper}} SSO"
|
||||
idp_name: "{{oidc.button_text}}"
|
||||
issuer: "{{oidc.client.issuer_url}}"
|
||||
client_id: "{{oidc.client.id}}"
|
||||
client_secret: "{{oidc.client.secret}}"
|
||||
|
@ -36,7 +36,7 @@ return array (
|
||||
'oidc_login_default_quota' => '{{applications[application_id].default_quota}}',
|
||||
|
||||
// Login button text
|
||||
'oidc_login_button_text' => 'Log in with OpenID',
|
||||
'oidc_login_button_text' => '{{oidc.button_text}}',
|
||||
|
||||
// Hide the NextCloud password change form.
|
||||
'oidc_login_hide_password_form' => true,
|
||||
|
@ -29,7 +29,7 @@ plugin_configuration:
|
||||
title: "keycloak"
|
||||
style: "keycloak"
|
||||
authorizeUrl: "{{ oidc.client.authorize_url }}"
|
||||
tokenUrl: "{{ oidc.client.toke_url }}"
|
||||
tokenUrl: "{{ oidc.client.token_url }}"
|
||||
displayNameClaim: ""
|
||||
userInfoUrl: "{{ oidc.client.user_info_url }}"
|
||||
logoutUrl: "{{ oidc.client.logout_url }}"
|
||||
|
15
roles/docker-openproject/Development.md
Normal file
15
roles/docker-openproject/Development.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Development Notes
|
||||
|
||||
## Get Settings
|
||||
|
||||
## LDAP
|
||||
|
||||
```bash
|
||||
docker compose exec web bash -c 'cd /app && RAILS_ENV=production bundle exec rails runner "puts Setting.all.select { |s| s.name.start_with?(\"ldap\") }.map { |s| \"#{s.name} = #{s.value}\" }"'
|
||||
```
|
||||
|
||||
### All
|
||||
|
||||
```bash
|
||||
docker compose exec web bash -c 'cd /app && RAILS_ENV=production bundle exec rails runner "Setting.all.each { |s| puts \"#{s.name} = #{s.value}\" }"'
|
||||
```
|
@ -1,27 +1,34 @@
|
||||
# OpenProject Role
|
||||
# OpenProject 🧭
|
||||
|
||||
## Description
|
||||
|
||||
This role deploys [OpenProject](https://www.openproject.org/) using Docker Compose and provides a fully integrated experience for project collaboration with optional support for LDAP authentication and SMTP email delivery. Ideal for teams or individuals who want to get started with OpenProject quickly without manually setting up infrastructure.
|
||||
|
||||
## Overview
|
||||
|
||||
This role is designed to deploy the [OpenProject](https://www.openproject.org/) application using Docker. It includes tasks for setting up the environment, pulling the Docker repository, and configuring a reverse proxy with Nginx. It was developed by [Kevin Veen-Birkenbach](https://www.veen.world/)
|
||||
Designed for simplicity, this role automates everything needed to run OpenProject in a containerized environment. It configures essential services such as the application itself, a PostgreSQL database, reverse proxy, and optional LDAP integration for identity management.
|
||||
|
||||
## Handlers
|
||||
## Purpose
|
||||
|
||||
Defined in `handlers/main.yml`, the handler `recreate openproject` is used for recreating the OpenProject instance with specific environment settings.
|
||||
The purpose of this role is to reduce the complexity of setting up OpenProject with modern production-ready defaults. By combining Docker Compose and Ansible automation, it enables a hands-off setup for both small teams and larger internal infrastructures.
|
||||
|
||||
## Tasks
|
||||
## Features
|
||||
|
||||
Outlined in `tasks/main.yml`, the role includes tasks for:
|
||||
- 🐳 **Docker-First Deployment**: Uses Docker Compose to launch the entire OpenProject stack.
|
||||
- 🔒 **LDAP Integration (optional)**: Automatically connects to your LDAP server for centralized authentication.
|
||||
- 📬 **SMTP Configuration**: Sends notification emails via your own mail server.
|
||||
- 🧩 **OIDC Ready**: Prepared to extend with OpenID Connect login (e.g., Keycloak).
|
||||
- 🔄 **Plugin Support**: Supports custom plugin installation via a pluggable `Gemfile.plugins`.
|
||||
- 🛠️ **Role-Oriented Architecture**: Easily integrates with your infrastructure (e.g., database, reverse proxy).
|
||||
|
||||
- Including Nginx Docker proxy domain tasks.
|
||||
- Creating the repository directory.
|
||||
- Pulling the OpenProject Docker repository.
|
||||
- Warning if the repository is not reachable.
|
||||
- Copying the `.env` file from a template.
|
||||
## Developer Notes
|
||||
|
||||
## Usage
|
||||
See the [Development.md](./Development.md) file for how to inspect and modify live settings inside the container, including full LDAP and SMTP configuration via the Rails console.
|
||||
|
||||
To use this role, include it in your Ansible playbook and set the necessary variables, especially those required in the `.env` file template.
|
||||
## Credits 📝
|
||||
|
||||
## Notes
|
||||
Developed and maintained by **Kevin Veen-Birkenbach**
|
||||
Learn more at [www.veen.world](https://www.veen.world)
|
||||
|
||||
Ensure that Docker and Docker Compose are installed and configured correctly on the target machine. Also, ensure that the necessary ports are open and accessible.
|
||||
Part of the [CyMaIS Project](https://github.com/kevinveenbirkenbach/cymais)
|
||||
License: [CyMaIS NonCommercial License (CNCL)](https://s.veen.world/cncl)
|
27
roles/docker-openproject/meta/main.yml
Normal file
27
roles/docker-openproject/meta/main.yml
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
galaxy_info:
|
||||
author: "Kevin Veen-Birkenbach"
|
||||
description: "Deploys OpenProject with full Docker Compose integration and optional LDAP/SMTP/SSO setup."
|
||||
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:
|
||||
- openproject
|
||||
- project-management
|
||||
- docker
|
||||
- compose
|
||||
- ldap
|
||||
- sso
|
||||
- automation
|
||||
repository: https://s.veen.world/cymais
|
||||
issue_tracker_url: https://s.veen.world/cymaisissues
|
||||
documentation: https://s.veen.world/cymais
|
||||
dependencies: []
|
47
roles/docker-openproject/tasks/ldap.yml
Normal file
47
roles/docker-openproject/tasks/ldap.yml
Normal file
@ -0,0 +1,47 @@
|
||||
- name: "Create LDAP auth source"
|
||||
community.postgresql.postgresql_query:
|
||||
db: openproject
|
||||
login_user: postgres
|
||||
query: >
|
||||
INSERT INTO ldap_auth_sources
|
||||
(name, host, port, account, account_password, base_dn, attr_login,
|
||||
attr_firstname, attr_lastname, attr_mail, onthefly_register, attr_admin,
|
||||
created_at, updated_at, tls_mode, filter_string, verify_peer, tls_certificate_string)
|
||||
VALUES (
|
||||
'{{ openproject_ldap.name }}',
|
||||
'{{ openproject_ldap.host }}',
|
||||
{{ openproject_ldap.port }},
|
||||
'{{ openproject_ldap.account }}',
|
||||
'{{ openproject_ldap.account_password }}',
|
||||
'{{ openproject_ldap.base_dn }}',
|
||||
'{{ openproject_ldap.attr_login }}',
|
||||
'{{ openproject_ldap.attr_firstname }}',
|
||||
'{{ openproject_ldap.attr_lastname }}',
|
||||
'{{ openproject_ldap.attr_mail }}',
|
||||
{{ openproject_ldap.onthefly_register }},
|
||||
'{{ openproject_ldap.attr_admin }}',
|
||||
NOW(),
|
||||
NOW(),
|
||||
{{ openproject_ldap.tls_mode }},
|
||||
'{{ openproject_ldap.filter_string }}',
|
||||
{{ openproject_ldap.verify_peer }},
|
||||
'{{ openproject_ldap.tls_certificate_string }}'
|
||||
)
|
||||
ON CONFLICT (name) DO NOTHING;
|
||||
become: true
|
||||
vars_files:
|
||||
- vars/ldap.yml
|
||||
|
||||
- name: "Check existing LDAP sources"
|
||||
community.postgresql.postgresql_query:
|
||||
db: openproject
|
||||
login_user: postgres
|
||||
query: "SELECT id, name FROM ldap_auth_sources"
|
||||
register: ldap_entries
|
||||
when: enable_debug | bool
|
||||
|
||||
- name: "Debug LDAP entries"
|
||||
debug:
|
||||
var: ldap_entries
|
||||
when: enable_debug | bool
|
||||
|
@ -44,3 +44,21 @@
|
||||
|
||||
- name: "copy docker-compose.yml and env file"
|
||||
include_tasks: copy-docker-compose-and-env.yml
|
||||
|
||||
- name: flush docker service
|
||||
meta: flush_handlers
|
||||
|
||||
- name: "Set OpenProject settings via rails"
|
||||
vars:
|
||||
rails_env: "RAILS_ENV=production"
|
||||
rails_cmd: "bundle exec rails runner"
|
||||
docker_container:
|
||||
name: openproject-web
|
||||
command: >
|
||||
bash -c "cd /app &&
|
||||
{{ rails_env }} {{ rails_cmd }} 'Setting[:{{ item.key }}] = {{ item.value | to_json }}'"
|
||||
loop: "{{ openproject_settings | dict2items }}"
|
||||
|
||||
- name: Setup LDAP
|
||||
include_tasks: ldap.yml
|
||||
when: applications[application_id].ldap.enabled | bool
|
17
roles/docker-openproject/vars/ldap.yml
Normal file
17
roles/docker-openproject/vars/ldap.yml
Normal file
@ -0,0 +1,17 @@
|
||||
openproject_ldap:
|
||||
name: "{{ primary_domain }}" # Display name for the LDAP connection in OpenProject
|
||||
host: "{{ ldap.server.domain }}" # LDAP server address
|
||||
port: "{{ ldap.server.port }}" # LDAP server port (typically 389 or 636)
|
||||
account: "{{ ldap.dn.administrator }}" # Bind DN (used for authentication)
|
||||
account_password: "{{ ldap.bind_credential }}" # Bind password
|
||||
base_dn: "{{ ldap.dn.users }}" # Base DN for user search
|
||||
attr_login: "{{ ldap.attributes.user_id | default('uid') }}" # LDAP attribute used for login
|
||||
attr_firstname: "givenName" # LDAP attribute for first name
|
||||
attr_lastname: "sn" # LDAP attribute for last name
|
||||
attr_mail: "mail" # LDAP attribute for email
|
||||
attr_admin: "" # Optional: LDAP attribute for admin group (leave empty if unused)
|
||||
onthefly_register: true # Automatically create users on first login
|
||||
tls_mode: 0 # 0 = No TLS, 1 = TLS, 2 = STARTTLS
|
||||
verify_peer: false # Whether to verify the SSL certificate
|
||||
filter_string: "" # Optional: Custom filter for users (e.g., "(objectClass=person)")
|
||||
tls_certificate_string: "" # Optional: Client certificate string for TLS (usually left empty)
|
7
roles/docker-openproject/vars/settings.yml
Normal file
7
roles/docker-openproject/vars/settings.yml
Normal file
@ -0,0 +1,7 @@
|
||||
openproject_settings:
|
||||
email_delivery_method: "smtp"
|
||||
smtp_address: "{{ system_email.host }}"
|
||||
smtp_domain: "{{ system_email.domain }}"
|
||||
smtp_user_name: "{{ system_email.username }}"
|
||||
smtp_password: "{{ system_email.password }}"
|
||||
smtp_ssl: false
|
@ -1,7 +1,7 @@
|
||||
# Configuration @see https://hub.docker.com/_/phpmyadmin
|
||||
|
||||
PMA_HOST= central-mariadb
|
||||
{% if applications.[application_id].autologin | bool %}
|
||||
{% if applications[application_id].autologin | bool %}
|
||||
PMA_USER= root
|
||||
PMA_PASSWORD= "{{central_mariadb_root_password}}"
|
||||
{% endif %}
|
15
roles/docker-taiga/Development.md
Normal file
15
roles/docker-taiga/Development.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Development
|
||||
|
||||
## Build front container
|
||||
|
||||
```bash
|
||||
docker compose up -d --force-recreate taiga-front
|
||||
```
|
||||
|
||||
## Debug
|
||||
|
||||
Verify front configuration:
|
||||
|
||||
```bash
|
||||
docker compose exec -it taiga-front cat /usr/share/nginx/html/conf.json
|
||||
```
|
@ -34,7 +34,7 @@ By using this role, teams can set up Taiga in minutes on Arch Linux systems —
|
||||
## 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`.
|
||||
- 🔐 **OIDC (Single Sign-On):** Supported via [taiga-contrib-openid-auth (robrotheram)](https://github.com/robrotheram/taiga-contrib-openid-auth)
|
||||
- 📨 **Email Backend:** Supports SMTP and console backends for development.
|
||||
- 🔁 **Async & Realtime Events:** Includes RabbitMQ and support for Taiga’s event system.
|
||||
- 🌐 **Reverse Proxy Ready:** Integrates with Nginx using the `nginx-domain-setup` role.
|
||||
|
@ -47,8 +47,8 @@ services:
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
{% include 'templates/docker/container/networks.yml.j2' %}
|
||||
taiga:
|
||||
# volumes:
|
||||
# - ./conf.json:/usr/share/nginx/html/conf.json
|
||||
# volumes:
|
||||
# - {{ taiga_frontend_conf_path }}:/usr/share/nginx/html/conf.json:ro
|
||||
|
||||
taiga-events:
|
||||
image: taigaio/taiga-events:latest
|
||||
|
@ -50,13 +50,13 @@ ENABLE_TELEMETRY = True
|
||||
{% if applications[application_id].oidc.enabled %}
|
||||
# OICD
|
||||
# @See https://github.com/robrotheram/taiga-contrib-openid-auth
|
||||
ENABLE_OPENID="True"
|
||||
ENABLE_OPENID=True
|
||||
OPENID_URL="{{oidc.client.authorize_url}}"
|
||||
OPENID_USER_URL="{{oidc.client.user_info_url}}"
|
||||
OPENID_TOKEN_URL="{{oidc.client.token_url}}"
|
||||
OPENID_CLIENT_ID="{{oidc.client.id}}"
|
||||
OPENID_CLIENT_SECRET="{{oidc.client.secret}}"
|
||||
OPENID_NAME="SSO"
|
||||
OPENID_NAME="{{oidc.button_text}}"
|
||||
# Default Values
|
||||
#
|
||||
# OPENID_ID_FIELD="sub"
|
||||
|
@ -5,4 +5,5 @@ 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")
|
||||
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' }}"
|
||||
taiga_image_frontend: "{{ 'robrotheram/taiga-front-openid' if applications[application_id].oidc.enabled else 'taigaio/taiga-front' }}"
|
||||
taiga_frontend_conf_path: "{{docker_compose.directories.config}}conf.json"
|
||||
|
Loading…
x
Reference in New Issue
Block a user