Compare commits

...

15 Commits

Author SHA1 Message Date
73d5651eea web-app-taiga: refactor OIDC gating + defaults
- Introduced dedicated variables in vars/main.yml:
  * TAIGA_FLAVOR_TAIGAIO
  * TAIGA_TAIGAIO_ENABLED
- Replaced inline Jinja2 get_app_conf checks with TAIGA_TAIGAIO_ENABLED for
  consistency in tasks, docker-compose template and env file.
- Adjusted env.j2 to use TAIGA_TAIGAIO_ENABLED instead of direct flavor checks.
- Enabled css by default (true instead of false).
- Cleaned up spacing/indentation in config and env.

This improves readability, reduces duplicated logic, and makes it easier to
maintain both OIDC flavors (robrotheram, taigaio).

Conversation: https://chatgpt.com/share/68af65b3-27c0-800f-964f-ff4f2d96ff5d
2025-08-27 22:08:35 +02:00
12a267827d Refactor websocket and Taiga variables
- Introduce WEBSOCKET_PROTOCOL derived from WEB_PROTOCOL (wss if https, else ws).
- Replace hardcoded websocket URLs in EspoCRM, Nextcloud and Taiga with {{ WEBSOCKET_PROTOCOL }}.
- Fix mautrix-imessage to use ws:// for internal synapse:8008.
- Standardize Pixelfed OIDC env spacing.
- Refactor Taiga variables to TAIGA_* naming convention and clean up EMAIL_BACKEND definition.

See: https://chatgpt.com/share/68af62fa-4dcc-800f-9aaf-cff746daab1e
2025-08-27 21:57:04 +02:00
c6cd6430bb Refactor Joomla role to new docker.* schema
- Move image definition from images.joomla to docker.services.joomla
- Add container name, container_port variable, and healthcheck
- Introduce JOOMLA_IMAGE, JOOMLA_VERSION, JOOMLA_CONTAINER, JOOMLA_VOLUME in vars
- Use volume mapping via docker.volumes.data

See: https://chatgpt.com/share/68af55a9-6514-800f-b6f7-1dc86356936e
2025-08-27 21:00:08 +02:00
67b2ebf001 Encapsulated code to pass performance tests 2025-08-27 20:58:00 +02:00
ebb6660473 Renamed Gitea variables 2025-08-27 20:49:35 +02:00
f62d09d8f1 Handle Let's Encrypt maintenance errors gracefully
- Extend certbundle task to ignore 'The service is down for maintenance or had an internal error'
  as a fatal failure.
- Add debug/warning output when this error occurs, so playbook does not stop but logs the issue.
- Ensure changed_when does not mark run as changed if only maintenance error was hit.

Ref: https://chatgpt.com/share/68af4e15-24cc-800f-b1dd-6a5f2380e35a
2025-08-27 20:28:25 +02:00
de159db918 web-app-wordpress: move msmtp configuration from Docker image to docker-compose mount
- Removed COPY of msmtp configuration from Dockerfile to avoid baking secrets/config into the image
- Added volume mount for host-side msmtp config ({{ WORDPRESS_HOST_MSMTP_CONF }}) in docker-compose.yml
- Keeps PHP upload.ini handling inside the image, but externalizes sensitive mail configuration
- Increases flexibility and avoids rebuilds when msmtp config changes

Ref: https://chatgpt.com/share/68af3c51-0544-800f-b76f-b2660c43addb
2025-08-27 19:12:03 +02:00
e2c2cf4bcf Updated sys-svc-msmtp execution condition 2025-08-27 18:12:49 +02:00
6e1e1ad5c5 Renamed pixelfed parameter 2025-08-27 18:11:31 +02:00
06baa4b03a Added correct validation handling 2025-08-27 18:10:49 +02:00
73e7fbdc8a refactor(web-app-wordpress): unify variable naming to uppercase WORDPRESS_* style
- Replaced all lowercase wordpress_* variables with uppercase WORDPRESS_* equivalents
- Ensured consistency across tasks, templates, and vars
- Improves readability and aligns with naming conventions

Conversation: https://chatgpt.com/share/68af29b5-8e7c-800f-bd12-48cc5956311c
2025-08-27 17:52:38 +02:00
bae2bc21ec Optimized system services included suppress option and solved bugs 2025-08-27 17:34:59 +02:00
a8f4dea9d2 Solved matrix name bug 2025-08-27 16:39:07 +02:00
5aaf2d28dc Refactor path handling, service conditions and dependencies
- Fixed incorrect filter usage in docker-compose handler (proper use of | path_join).
- Improved LetsEncrypt template by joining paths with filenames instead of appending manually.
- Enhanced sys-svc-msmtp task with an additional condition to only run if no-reply mailu_token exists.
- Updated Keycloak meta to depend on Mailu (ensuring token generation before setup).
- Refactored Keycloak import path variables to use path_join consistently.
- Adjusted Mailu meta dependency to run after Matomo instead of Keycloak.

See: https://chatgpt.com/share/68af13e6-edc0-800f-b76a-a5f427837173
2025-08-27 16:19:57 +02:00
5287bb4d74 Refactor Akaunting role and CSP handling
- Improved CSP filter to properly include web-svc-cdn and use protocol-aware domains
- Added Todo.md with redis and OIDC notes
- Enhanced Akaunting role config with CSP flags and redis option
- Updated schema to include app_key validation
- Reworked tasks to handle first-run marker logic cleanly
- Fixed docker-compose template (marker, healthcheck, setup flag)
- Expanded env.j2 with cache, email, proxy, and redis options
- Added javascript.js.j2 template for SSO warning
- Introduced structured vars for Akaunting role
- Removed deprecated update-repository-with-files.yml task

See conversation: https://chatgpt.com/share/68af00df-2c74-800f-90b6-6ac5b29acdcb
2025-08-27 14:58:44 +02:00
62 changed files with 423 additions and 337 deletions

View File

@@ -198,6 +198,7 @@ def main():
"MODE_CLEANUP": args.cleanup,
"MODE_LOGS": args.logs,
"MODE_DEBUG": args.debug,
"MODE_ASSERT": not args.skip_validation,
"host_type": args.host_type
}

View File

@@ -131,14 +131,18 @@ class FilterModule(object):
flags = self.get_csp_flags(applications, application_id, directive)
tokens += flags
# Matomo integration
if (
self.is_feature_enabled(applications, matomo_feature_name, application_id)
and directive in ['script-src-elem', 'connect-src']
):
matomo_domain = domains.get('web-app-matomo')[0]
if matomo_domain:
tokens.append(f"{web_protocol}://{matomo_domain}")
if directive in ['script-src-elem', 'connect-src']:
# Matomo integration
if self.is_feature_enabled(applications, matomo_feature_name, application_id):
matomo_domain = domains.get('web-app-matomo')[0]
if matomo_domain:
tokens.append(f"{web_protocol}://{matomo_domain}")
# Allow the loading of js from the cdn
if self.is_feature_enabled(applications, 'logout', application_id) or self.is_feature_enabled(applications, 'desktop', application_id):
domain = domains.get('web-svc-cdn')[0]
tokens.append(f"{web_protocol}://{domain}")
# ReCaptcha integration: allow loading scripts from Google if feature enabled
if self.is_feature_enabled(applications, 'recaptcha', application_id):
@@ -146,12 +150,6 @@ class FilterModule(object):
tokens.append('https://www.gstatic.com')
tokens.append('https://www.google.com')
# Allow the loading of js from the cdn
if directive == 'script-src-elem':
if self.is_feature_enabled(applications, 'logout', application_id) or self.is_feature_enabled(applications, 'desktop', application_id):
domain = domains.get('web-svc-cdn')[0]
tokens.append(f"{domain}")
if directive == 'frame-ancestors':
# Enable loading via ancestors
if self.is_feature_enabled(applications, 'desktop', application_id):
@@ -163,11 +161,11 @@ class FilterModule(object):
# Allow logout via infinito logout proxy
domain = domains.get('web-svc-logout')[0]
tokens.append(f"{domain}")
tokens.append(f"{web_protocol}://{domain}")
# Allow logout via keycloak app
domain = domains.get('web-app-keycloak')[0]
tokens.append(f"{domain}")
tokens.append(f"{web_protocol}://{domain}")
# whitelist
tokens += self.get_csp_whitelist(applications, application_id, directive)

View File

@@ -26,6 +26,9 @@ HOST_DECIMAL_MARK: ","
WEB_PROTOCOL: "https" # Web protocol type. Use https or http. If you run local you need to change it to http
WEB_PORT: "{{ 443 if WEB_PROTOCOL == 'https' else 80 }}" # Default port web applications will listen to
# Websocket
WEBSOCKET_PROTOCOL: "{{ 'wss' if WEB_PROTOCOL == 'https' else 'ws' }}"
# Domain
PRIMARY_DOMAIN: "localhost" # Primary Domain of the server

View File

@@ -21,7 +21,7 @@ defaults_service_provider:
if 'web-app-bluesky' in group_names else '' }}
email: "{{ users.contact.username ~ '@' ~ PRIMARY_DOMAIN if 'web-app-mailu' in group_names else '' }}"
mastodon: "{{ '@' ~ users.contact.username ~ '@' ~ domains | get_domain('web-app-mastodon') if 'web-app-mastodon' in group_names else '' }}"
matrix: "{{ '@' ~ users.contact.username ~ ':' ~ domains['web-app-matrix'].synapse if 'web-app-matrix' in group_names else '' }}"
matrix: "{{ '@' ~ users.contact.username ~ ':' ~ applications | get_app_conf('web-app-matrix', 'server_name') if 'web-app-matrix' in group_names else '' }}"
peertube: "{{ '@' ~ users.contact.username ~ '@' ~ domains | get_domain('web-app-peertube') if 'web-app-peertube' in group_names else '' }}"
pixelfed: "{{ '@' ~ users.contact.username ~ '@' ~ domains | get_domain('web-app-pixelfed') if 'web-app-pixelfed' in group_names else '' }}"
phone: "+0 000 000 404"

View File

@@ -15,7 +15,7 @@
- name: docker compose pull
shell: |
set -euo pipefail
lock="{{ [ PATH_DOCKER_COMPOSE_PULL_LOCK_DIR | docker_compose.directories.instance ] path_join | hash('sha1') }}"
lock="{{ [ PATH_DOCKER_COMPOSE_PULL_LOCK_DIR | docker_compose.directories.instance ] | path_join | hash('sha1') }}"
if [ ! -e "$lock" ]; then
mkdir -p "$(dirname "$lock")"
docker compose pull

View File

@@ -1,3 +1,3 @@
ssl_certificate {{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/fullchain.pem;
ssl_certificate_key {{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/privkey.pem;
ssl_trusted_certificate {{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/chain.pem;
ssl_certificate {{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder, 'fullchain.pem'] | path_join }};
ssl_certificate_key {{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder, 'privkey.pem' ] | path_join }};
ssl_trusted_certificate {{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder, 'chain.pem' ] | path_join }};

View File

@@ -0,0 +1,38 @@
# Necessary to have this seperat file to pass performance tests
- name: Install certbundle
include_role:
name: pkgmgr-install
vars:
package_name: certbundle
- name: Generate SAN certificate with certbundle
command: >-
certbundle
--domains "{{ current_play_domains_all | join(',') }}"
--certbot-email "{{ users.administrator.email }}"
--certbot-acme-challenge-method "{{ CERTBOT_ACME_CHALLENGE_METHOD }}"
--chunk-size 100
{% if CERTBOT_ACME_CHALLENGE_METHOD != 'webroot' %}
--certbot-credentials-file "{{ CERTBOT_CREDENTIALS_FILE }}"
--certbot-dns-propagation-seconds "{{ CERTBOT_DNS_PROPAGATION_WAIT_SECONDS }}"
{% else %}
--letsencrypt-webroot-path "{{ LETSENCRYPT_WEBROOT_PATH }}"
{% endif %}
{{ '--mode-test' if MODE_TEST | bool else '' }}
register: certbundle_result
changed_when: "'Certificate not yet due for renewal' not in certbundle_result.stdout"
failed_when: >
certbundle_result.rc != 0
and 'too many certificates' not in (certbundle_result.stderr | lower | default(''))
and 'the service is down for maintenance or had an internal error' not in (certbundle_result.stderr | lower | default(''))
- name: Warn if LetsEncrypt was down
when: "'the service is down for maintenance or had an internal error' in (certbundle_result.stderr | lower | default(''))"
debug:
msg: >
WARNING: Let's Encrypt responded with "service down for maintenance / internal error".
Certificate request skipped; please retry later.
- name: run the san tasks once
set_fact:
run_once_san_certs: true

View File

@@ -1,31 +1,3 @@
- block:
- name: Install certbundle
include_role:
name: pkgmgr-install
vars:
package_name: certbundle
- name: Generate SAN certificate with certbundle
command: >-
certbundle
--domains "{{ current_play_domains_all | join(',') }}"
--certbot-email "{{ users.administrator.email }}"
--certbot-acme-challenge-method "{{ CERTBOT_ACME_CHALLENGE_METHOD }}"
--chunk-size 100
{% if CERTBOT_ACME_CHALLENGE_METHOD != 'webroot' %}
--certbot-credentials-file "{{ CERTBOT_CREDENTIALS_FILE }}"
--certbot-dns-propagation-seconds "{{ CERTBOT_DNS_PROPAGATION_WAIT_SECONDS }}"
{% else %}
--letsencrypt-webroot-path "{{ LETSENCRYPT_WEBROOT_PATH }}"
{% endif %}
{{ '--mode-test' if MODE_TEST | bool else '' }}
register: certbundle_result
changed_when: "'Certificate not yet due for renewal' not in certbundle_result.stdout"
failed_when: >
certbundle_result.rc != 0
and 'too many certificates' not in certbundle_result.stderr
- name: run the san tasks once
set_fact:
run_once_san_certs: true
# Neccessary encapsulation to pass performance tests
- include_tasks: "_san.yml"
when: run_once_san_certs is not defined

View File

@@ -6,6 +6,7 @@
- include_role:
name: sys-service
vars:
system_service_on_calendar: "{{SYS_SCHEDULE_HEALTH_JOURNALCTL}}"
system_service_timer_enabled: true
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
system_service_on_calendar: "{{ SYS_SCHEDULE_HEALTH_JOURNALCTL }}"
system_service_timer_enabled: true
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
# system_service_suppress_flush: true # There are almost allways errors in the journalctl logs so suppression is neccessary to let playbook run

View File

@@ -12,7 +12,8 @@
- include_role:
name: sys-service
vars:
system_service_copy_files: false
system_service_on_calendar: "{{SYS_SCHEDULE_REPAIR_BTRFS_AUTO_BALANCER}}"
system_service_timer_enabled: true
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
system_service_copy_files: false
system_service_on_calendar: "{{ SYS_SCHEDULE_REPAIR_BTRFS_AUTO_BALANCER }}"
system_service_timer_enabled: true
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
system_service_tpl_exec_start: "/bin/sh -c 'btrfs-auto-balancer 90 10'"

View File

@@ -1,7 +0,0 @@
[Unit]
Description=auto balance btrfs
OnFailure={{ SYS_SERVICE_ON_FAILURE_COMPOSE }}
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'btrfs-auto-balancer 90 10'

View File

@@ -1,3 +1,4 @@
SYS_SERVICE_ALL_ENABLED: "{{ MODE_DEBUG }}"
SYS_SERVICE_DEFAULT_STATE: "{{ 'restarted' if MODE_DEBUG else omit }}"
SYS_SERVICE_DEFAULT_RUNTIME: "86400s" # Maximum total runtime a service is allowed to run before being stopped
SYS_SERVICE_DEFAULT_RUNTIME: "86400s" # Maximum total runtime a service is allowed to run before being stopped
SYS_SERVICE_SUPPRESS_FLUSH: [] # Services where the flush should be suppressed

View File

@@ -46,5 +46,5 @@
command: /bin/true
notify: refresh systemctl service
when: not system_service_uses_at
when: SYS_SERVICE_ALL_ENABLED | bool or system_force_flush | bool
when: (SYS_SERVICE_ALL_ENABLED | bool or system_force_flush | bool) and not system_service_suppress_flush | bool

View File

@@ -6,9 +6,10 @@ system_service_role_dir: "{{ [ playbook_dir, 'roles', system_service_role_
system_service_script_dir: "{{ [ PATH_SYSTEMCTL_SCRIPTS, system_service_id ] | path_join }}"
## Settings
system_force_flush: false # When set to true it activates the flushing of services :)
system_service_copy_files: true # When set to false file copying will be skipped
system_service_timer_enabled: false # When set to true timer will be loaded
system_force_flush: false # When set to true it activates the flushing of services :)
system_service_suppress_flush: "{{ (system_service_id in SYS_SERVICE_SUPPRESS_FLUSH) | bool }}" # When set to true it suppresses the flushing of services
system_service_copy_files: true # When set to false file copying will be skipped
system_service_timer_enabled: false # When set to true timer will be loaded
system_service_state: "{{ SYS_SERVICE_DEFAULT_STATE }}"
# Dynamic Loaded ( Just available when dependencies are loaded )

View File

@@ -2,4 +2,4 @@
- include_tasks: 01_core.yml
- set_fact:
run_once_sys_svc_msmtp: true
when: run_once_sys_svc_msmtp is not defined
when: run_once_sys_svc_msmtp is not defined

View File

@@ -0,0 +1,3 @@
# To-dos
- Enable redis
- Enable OIDC

View File

@@ -7,11 +7,26 @@ features:
css: true
desktop: true
central_database: true
logout: true
logout: true
javascript: true
server:
domains:
canonical:
- "accounting.{{ PRIMARY_DOMAIN }}"
csp:
flags:
script-src-elem:
unsafe-inline: true
script-src:
unsafe-inline: true
unsafe-eval: true
style-src:
unsafe-inline: true
whitelist:
font-src:
- "data:"
connect-src:
- https://akaunting.com
docker:
services:
database:
@@ -22,6 +37,8 @@ docker:
image: docker.io/akaunting/akaunting
version: latest
name: akaunting
redis:
enabled: false # Set to true to activate redis for akaunting
volumes:
data: akaunting_data
credentials: {}

View File

@@ -2,4 +2,8 @@ credentials:
setup_admin_password:
description: "Initial admin user password for Akaunting"
algorithm: "sha256"
validation: "^[a-f0-9]{64}$"
validation: "^[a-f0-9]{64}$"
app_key:
description: "Laravel application key (base64 encoded 32-byte key, prefixed with 'base64:')"
algorithm: "base64_prefixed_32"
validation: "^base64:[A-Za-z0-9+/=]{43,}$"

View File

@@ -1,18 +1,24 @@
---
- name: "Akaunting | Check if first run (marker exists?)"
ansible.builtin.stat:
path: "{{ AKAUNTING_SETUP_MARKER }}"
register: akaunting_marker_stat
- name: "Akaunting | Decide if setup should be enabled"
ansible.builtin.set_fact:
akaunting_setup_enabled: "{{ not akaunting_marker_stat.stat.exists }}"
- name: "For '{{ application_id }}': load docker, db and proxy"
include_role:
include_role:
name: cmp-db-docker-proxy
- name: "include tasks update-repository-with-files.yml"
include_tasks: utils/update-repository-with-files.yml
vars:
detached_files:
- "docker-compose.yml"
# Forward flag into compose templating
cmp_extra_facts:
akaunting_setup_enabled: "{{ akaunting_setup_enabled }}"
- name: "For '{{ application_id }}': create {{ docker_compose.files.env }}"
template:
src: "env.j2"
dest: "{{ docker_compose.files.env }}"
mode: "0770"
force: yes
notify: docker compose up
- name: "Akaunting | Create first-run marker to disable future setup"
ansible.builtin.file:
path: "{{ AKAUNTING_SETUP_MARKER }}"
state: touch
mode: "0644"
when: akaunting_setup_enabled | bool

View File

@@ -2,22 +2,26 @@
application:
{% include 'roles/docker-container/templates/base.yml.j2' %}
container_name: {{ akaunting_name }}
image: "{{ akaunting_image }}:{{ akaunting_version }}"
{% set container_port = 80 %}
container_name: {{ AKAUNTING_CONTAINER }}
image: "{{ AKAUNTING_IMAGE }}:{{ AKAUNTING_VERSION }}"
build:
context: .
context: {{ docker_repository_path }}
dockerfile: Dockerfile
ports:
- 127.0.0.1:{{ ports.localhost.http[application_id] }}:80
- 127.0.0.1:{{ ports.localhost.http[application_id] }}:{{ container_port }}
volumes:
- data:/var/www/html
{% if akaunting_setup_enabled | bool %}
environment:
- AKAUNTING_SETUP
- AKAUNTING_SETUP=true
{% endif %}
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
data:
name: {{ akaunting_volume }}
name: {{ AKAUNTING_VOLUME }}
{% include 'roles/docker-compose/templates/networks.yml.j2' %}

View File

@@ -1,22 +1,55 @@
# You should change this to match your reverse proxy DNS name and protocol
APP_URL={{ domains | get_url(application_id, WEB_PROTOCOL) }}
# https://github.com/akaunting/akaunting/blob/master/.env.example
APP_URL={{ AKAUNTING_URL }}
# Locales
LOCALE={{ HOST_LL }}
TIMEZONE={{ HOST_TIMEZONE }}
# Environment
APP_DEBUG={{ MODE_DEBUG | lower }}
APP_ENV={{ ENVIRONMENT }}
# Don't change this unless you rename your database container or use rootless podman, in case of using rootless podman you should set it to 127.0.0.1 (NOT localhost)
DB_HOST={{ database_host }}
# Change these to match env/db.env
DB_DATABASE={{ database_name }}
DB_USERNAME={{ database_username }}
DB_PASSWORD={{ database_password }}
# You should change this to a random string of three numbers or letters followed by an underscore
DB_PORT={{ database_port }}
DB_CONNECTION=mysql
DB_PREFIX=asd_
# Proxy
TRUSTED_PROXIES=*
TRUSTED_HEADERS=X_FORWARDED_FOR,X_FORWARDED_HOST,X_FORWARDED_PORT,X_FORWARDED_PROTO
# These define the first company to exist on this instance. They are only used during setup.
COMPANY_NAME={{applications | get_app_conf(application_id, 'company.name', True)}}
COMPANY_EMAIL={{applications | get_app_conf(application_id, 'company.email', True)}}
COMPANY_NAME={{ AKAUNTING_COMPANY_NAME }}
COMPANY_EMAIL={{ AKAUNTING_COMPANY_EMAIL }}
# Credentials
APP_KEY={{ AKAUNTING_APP_KEY }}
# This will be the first administrative user created on setup.
ADMIN_EMAIL={{applications.akaunting.setup_admin_email}}
ADMIN_PASSWORD={{applications | get_app_conf(application_id, 'credentials.setup_admin_password', True)}}
ADMIN_EMAIL={{ AKAUNTING_ADMIN_EMAIL }}
ADMIN_PASSWORD={{ AKAUNTING_ADMIN_PASSWORD }}
# Cache
CACHE_DRIVER={{ AKAUNTING_CACHE_DRIVER }}
SESSION_DRIVER={{ AKAUNTING_CACHE_DRIVER }}
QUEUE_CONNECTION={{ 'sync' if AKAUNTING_CACHE_DRIVER == 'file' else AKAUNTING_CACHE_DRIVER }}
{% if AKAUNTING_CACHE_DRIVER == 'redis' %}
REDIS_CLIENT=phpredis
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
{% endif %}
# Email
MAIL_MAILER={{ 'smtp' if SYSTEM_EMAIL.SMTP else 'sendmail' }}
MAIL_HOST={{ SYSTEM_EMAIL.HOST }}
MAIL_PORT={{ SYSTEM_EMAIL.PORT }}
MAIL_USERNAME={{ users['no-reply'].email }}
MAIL_PASSWORD={{ users['no-reply'].mailu_token }}
MAIL_ENCRYPTION={{ SYSTEM_EMAIL.TLS | ternary("tls","null") }}
MAIL_FROM_ADDRESS={{ AKAUNTING_COMPANY_EMAIL }}
MAIL_FROM_NAME={{ AKAUNTING_COMPANY_NAME }}

View File

@@ -0,0 +1 @@
{% include 'templates/roles/web-app/templates/javascripts/sso_warning.js.j2' %}

View File

@@ -1,8 +1,28 @@
application_id: "web-app-akaunting"
database_type: "mariadb"
database_password: "{{ applications | get_app_conf(application_id, 'credentials.database_password', True) }}"
docker_repository_address: "https://github.com/akaunting/docker.git"
akaunting_version: "{{ applications | get_app_conf(application_id, 'docker.services.akaunting.version', True) }}"
akaunting_image: "{{ applications | get_app_conf(application_id, 'docker.services.akaunting.image', True) }}"
akaunting_name: "{{ applications | get_app_conf(application_id, 'docker.services.akaunting.name', True) }}"
akaunting_volume: "{{ applications | get_app_conf(application_id, 'docker.volumes.data', True) }}"
# General
application_id: "web-app-akaunting"
js_application_name: "Akaunting"
# Database
database_type: "mariadb"
database_password: "{{ applications | get_app_conf(application_id, 'credentials.database_password') }}"
# Docker
docker_repository_address: "https://github.com/akaunting/docker.git"
docker_pull_git_repository: true
docker_repository_branch: "master"
docker_compose_skipp_file_creation: false
# Akaunting
AKAUNTING_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
AKAUNTING_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.akaunting.version') }}"
AKAUNTING_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.akaunting.image') }}"
AKAUNTING_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.akaunting.name') }}"
AKAUNTING_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
AKAUNTING_COMPANY_NAME: "{{ applications | get_app_conf(application_id, 'company.name') }}"
AKAUNTING_COMPANY_EMAIL: "{{ applications | get_app_conf(application_id, 'company.email') }}"
AKAUNTING_ADMIN_EMAIL: "{{ applications | get_app_conf(application_id, 'setup_admin_email') }}"
AKAUNTING_ADMIN_PASSWORD: "{{ applications | get_app_conf(application_id, 'credentials.setup_admin_password') }}"
AKAUNTING_SETUP_MARKER: "/var/lib/docker/volumes/{{ AKAUNTING_VOLUME }}/_data/.akaunting_installed"
AKAUNTING_APP_KEY: "{{ applications | get_app_conf(application_id, 'credentials.app_key') }}"
AKAUNTING_CACHE_DRIVER: "{{ 'redis' if applications | get_app_conf(application_id, 'docker.services.redis.enabled') else 'file' }}"

View File

@@ -18,7 +18,7 @@ server:
unsafe-eval: true
whitelist:
connect-src:
- wss://espocrm.{{ PRIMARY_DOMAIN }}
- {{ WEBSOCKET_PROTOCOL }}://espocrm.{{ PRIMARY_DOMAIN }}
- "data:"
frame-src:
- https://s.espocrm.com/

View File

@@ -28,7 +28,7 @@
driver: journald
environment:
- ESPOCRM_CONFIG_USE_WEB_SOCKET=true
- ESPOCRM_CONFIG_WEB_SOCKET_URL=wss://{{ domains | get_domain(application_id) }}/ws
- ESPOCRM_CONFIG_WEB_SOCKET_URL={{ WEBSOCKET_PROTOCOL }}://{{ domains | get_domain(application_id) }}/ws
- ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBSCRIBER_DSN=tcp://*:7777
- ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBMISSION_DSN=tcp://websocket:7777
entrypoint: docker-websocket.sh

View File

@@ -4,26 +4,26 @@
- name: Patch Gitea DB host in app.ini
command: >
docker exec -i --user {{ gitea_user }} {{ gitea_container }}
sed -ri "s|^(HOST\s*=\s*).*$|\1{{ database_host }}:{{ database_port }}|" {{ gitea_config }}
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }}
sed -ri "s|^(HOST\s*=\s*).*$|\1{{ database_host }}:{{ database_port }}|" {{ GITEA_CONFIG }}
notify: docker compose up
- name: Patch Gitea DB name in app.ini
command: >
docker exec -i --user {{ gitea_user }} {{ gitea_container }}
sed -ri "s|^(NAME\s*=\s*).*$|\1{{ database_name }}|" {{ gitea_config }}
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }}
sed -ri "s|^(NAME\s*=\s*).*$|\1{{ database_name }}|" {{ GITEA_CONFIG }}
notify: docker compose up
- name: Patch Gitea DB user in app.ini
command: >
docker exec -i --user {{ gitea_user }} {{ gitea_container }}
sed -ri "s|^(USER\s*=\s*).*$|\1{{ database_username }}|" {{ gitea_config }}
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }}
sed -ri "s|^(USER\s*=\s*).*$|\1{{ database_username }}|" {{ GITEA_CONFIG }}
notify: docker compose up
- name: Patch Gitea DB password in app.ini
command: >
docker exec -i --user {{ gitea_user }} {{ gitea_container }}
sed -ri "s|^(PASSWD\s*=\s*).*$|\1{{ database_password }}|" {{ gitea_config }}
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }}
sed -ri "s|^(PASSWD\s*=\s*).*$|\1{{ database_password }}|" {{ GITEA_CONFIG }}
notify: docker compose up
- name: "Flush database patches"

View File

@@ -1,6 +1,6 @@
- name: "Lookup existing LDAP auth source ID"
shell: |
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }} \
gitea admin auth list \
| awk -v name="LDAP ({{ PRIMARY_DOMAIN }})" '$0 ~ name {print $1; exit}'
args:
@@ -11,7 +11,7 @@
- name: "Delete existing LDAP auth source if present"
shell: |
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }} \
gitea admin auth delete --id {{ ldap_source_id_raw.stdout }}
args:
chdir: "{{ docker_compose.directories.instance }}"

View File

@@ -1,7 +1,7 @@
- name: "Lookup existing OIDC auth source ID"
shell: |
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }} \
gitea admin auth list \
| awk -v name="{{ OIDC.BUTTON_TEXT }}" '$0 ~ name {print $1; exit}'
args:
@@ -12,7 +12,7 @@
- name: "Delete existing OIDC auth source if present"
shell: |
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }} \
gitea admin auth delete --id {{ oidc_source_id_raw.stdout }}
args:
chdir: "{{ docker_compose.directories.instance }}"

View File

@@ -15,7 +15,7 @@
- name: "Run DB migrations inside Gitea container"
shell: |
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }} \
/app/gitea/gitea migrate
args:
chdir: "{{ docker_compose.directories.instance }}"
@@ -24,13 +24,13 @@
- name: "Create initial admin user"
shell: |
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }} \
/app/gitea/gitea admin user create \
--admin \
--username "{{ users.administrator.username }}" \
--password "{{ users.administrator.password }}" \
--email "{{ users.administrator.email }}" \
-c {{ gitea_config }}
-c {{ GITEA_CONFIG }}
args:
chdir: "{{ docker_compose.directories.instance }}"
register: create_admin

View File

@@ -1,8 +1,8 @@
- name: "Add LDAP Authentication Source"
shell: |
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }} \
gitea admin auth add-ldap \
{{ gitea_ldap_auth_args | join(' ') }}
{{ GITEA_LDAP_AUTH_ARGS | join(' ') }}
args:
chdir: "{{ docker_compose.directories.instance }}"
register: ldap_manage
@@ -10,7 +10,7 @@
- name: "Lookup existing LDAP auth source ID"
shell: |
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }} \
gitea admin auth list \
| tail -n +2 \
| grep -F "LDAP ({{ PRIMARY_DOMAIN }})" \
@@ -29,10 +29,10 @@
- name: "Update LDAP Authentication Source"
shell: |
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }} \
gitea admin auth update-ldap \
--id {{ ldap_source_id }} \
{{ gitea_ldap_auth_args | join(' ') }}
{{ GITEA_LDAP_AUTH_ARGS | join(' ') }}
args:
chdir: "{{ docker_compose.directories.instance }}"
register: ldap_manage

View File

@@ -1,6 +1,6 @@
- name: "Add Keycloak OIDC Provider"
shell: |
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }} \
gitea admin auth add-oauth \
--provider openidConnect \
--name "{{ OIDC.BUTTON_TEXT }}" \
@@ -15,7 +15,7 @@
- name: "Lookup existing Keycloak auth source ID"
shell: |
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }} \
/app/gitea/gitea admin auth list \
| tail -n +2 \
| grep -F "{{ OIDC.BUTTON_TEXT }}" \
@@ -34,7 +34,7 @@
- name: "Update Keycloak OIDC Provider"
shell: |
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
docker exec -i --user {{ GITEA_USER }} {{ GITEA_CONTAINER }} \
gitea admin auth update-oauth \
--id {{ oidc_source_id }}\
--provider openidConnect \

View File

@@ -2,8 +2,8 @@
application:
{% include 'roles/docker-container/templates/base.yml.j2' %}
image: "{{ gitea_image }}:{{ gitea_version }}"
container_name: "{{ gitea_container }}"
image: "{{ GITEA_IMAGE }}:{{ GITEA_VERSION }}"
container_name: "{{ GITEA_CONTAINER }}"
ports:
- "127.0.0.1:{{ ports.localhost.http[application_id] }}:{{ container_port }}"
- "{{ports.public.ssh[application_id]}}:22"
@@ -17,6 +17,6 @@
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
data:
name: {{ gitea_volume }}
name: {{ GITEA_VOLUME }}
{% include 'roles/docker-compose/templates/networks.yml.j2' %}

View File

@@ -1,6 +1,13 @@
application_id: "web-app-gitea"
database_type: "mariadb"
gitea_ldap_auth_args:
# General
application_id: "web-app-gitea"
database_type: "mariadb"
# Docker
container_port: "{{ applications | get_app_conf(application_id, 'docker.services.gitea.port') }}"
docker_compose_flush_handlers: true
# Gitea
GITEA_LDAP_AUTH_ARGS:
- '--name "LDAP ({{ PRIMARY_DOMAIN }})"'
- '--host "{{ ldap.server.domain }}"'
- '--port {{ ldap.server.port }}'
@@ -15,13 +22,9 @@ gitea_ldap_auth_args:
- '--email-attribute "{{ ldap.user.attributes.mail }}"'
- '--public-ssh-key-attribute "{{ ldap.user.attributes.ssh_public_key }}"'
- '--synchronize-users'
gitea_version: "{{ applications | get_app_conf(application_id, 'docker.services.gitea.version', True) }}"
gitea_image: "{{ applications | get_app_conf(application_id, 'docker.services.gitea.image', True) }}"
gitea_container: "{{ applications | get_app_conf(application_id, 'docker.services.gitea.name', True) }}"
gitea_volume: "{{ applications | get_app_conf(application_id, 'docker.volumes.data', True) }}"
gitea_user: "git"
gitea_config: "/data/gitea/conf/app.ini"
container_port: "{{ applications | get_app_conf(application_id, 'docker.services.gitea.port', True) }}"
docker_compose_flush_handlers: true
GITEA_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.gitea.version') }}"
GITEA_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.gitea.image') }}"
GITEA_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.gitea.name') }}"
GITEA_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
GITEA_USER: "git"
GITEA_CONFIG: "/data/gitea/conf/app.ini"

View File

@@ -1,5 +1,3 @@
images:
joomla: "joomla:latest"
features:
matomo: true
css: true
@@ -14,3 +12,9 @@ docker:
services:
database:
enabled: true
joomla:
image: joomla
version: latest
name: joomla
volumes:
data: "joomla_data"

View File

@@ -1,15 +1,18 @@
{% include 'roles/docker-compose/templates/base.yml.j2' %}
application:
image: "{{ applications | get_app_conf(application_id, 'images.joomla', True) }}"
image: "{{ JOOMLA_IMAGE }}:{{ JOOMLA_VERSION }}"
container_name: "{{ JOOMLA_CONTAINER }}"
{% include 'roles/docker-container/templates/base.yml.j2' %}
volumes:
- data:/var/www/html
ports:
- "127.0.0.1:{{ ports.localhost.http[application_id] }}:80"
- "127.0.0.1:{{ ports.localhost.http[application_id] }}:{{ container_port }}"
{% include 'roles/docker-container/templates/healthcheck/curl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
data:
name: {{ JOOMLA_VOLUME }}
{% include 'roles/docker-compose/templates/networks.yml.j2' %}

View File

@@ -1,2 +1,10 @@
# General
application_id: "web-app-joomla"
database_type: "postgres"
database_type: "postgres"
container_port: 80
# Joomla
JOOMLA_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.joomla.version') }}"
JOOMLA_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.joomla.image') }}"
JOOMLA_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.joomla.name') }}"
JOOMLA_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"

View File

@@ -21,3 +21,4 @@ galaxy_info:
class: "fa-solid fa-lock"
run_after:
- web-app-matomo
- web-app-mailu # Token must be generated

View File

@@ -23,10 +23,10 @@ KEYCLOAK_HEALTH_ENABLED: true
## Import
KEYCLOAK_REALM_IMPORT_ENABLED: "{{ applications | get_app_conf(application_id, 'actions.import_realm') }}"
KEYCLOAK_REALM_IMPORT_DIR_HOST: "{{ docker_compose.directories.volumes }}import/"
KEYCLOAK_REALM_IMPORT_DIR_HOST: "{{ [docker_compose.directories.volumes,'import'] | path_join }}"
KEYCLOAK_REALM_IMPORT_DIR_DOCKER: "/opt/keycloak/data/import/"
KEYCLOAK_REALM_IMPORT_FILE_SRC: "import/realm.json.j2"
KEYCLOAK_REALM_IMPORT_FILE_DST: "{{ KEYCLOAK_REALM_IMPORT_DIR_HOST }}/realm.json"
KEYCLOAK_REALM_IMPORT_FILE_DST: "{{ [KEYCLOAK_REALM_IMPORT_DIR_HOST,'realm.json'] | path_join }}"
## Credentials
KEYCLOAK_ADMIN: "{{ applications | get_app_conf(application_id, 'users.administrator.username') }}"

View File

@@ -20,4 +20,4 @@ galaxy_info:
logo:
class: "fa-solid fa-envelope"
run_after:
- web-app-keycloak
- web-app-matomo

View File

@@ -6,7 +6,7 @@ homeserver:
# Only the /_matrix/client/unstable/fi.mau.as_sync websocket endpoint is used on this address.
#
# Set to null to disable using the websocket. When not using the websocket, make sure hostname and port are set in the appservice section.
websocket_proxy: wss://synapse:8008
websocket_proxy: ws://synapse:8008
# How often should the websocket be pinged? Pinging will be disabled if this is zero.
ping_interval_seconds: 0
# The domain of the homeserver (also known as server_name, used for MXIDs, etc).

View File

@@ -10,11 +10,11 @@ server:
font-src:
- "data:"
connect-src:
- "wss://collabora.{{ PRIMARY_DOMAIN }}"
- "{{ WEBSOCKET_PROTOCOL }}://collabora.{{ PRIMARY_DOMAIN }}"
- "{{ WEB_PROTOCOL }}://collabora.{{ PRIMARY_DOMAIN }}"
frame-src:
- "{{ WEB_PROTOCOL }}://collabora.{{ PRIMARY_DOMAIN }}"
- "wss://collabora.{{ PRIMARY_DOMAIN }}"
- "{{ WEBSOCKET_PROTOCOL }}://collabora.{{ PRIMARY_DOMAIN }}"
domains:
canonical:
- "cloud.{{ PRIMARY_DOMAIN }}"

View File

@@ -1,8 +1,8 @@
{% include 'roles/docker-compose/templates/base.yml.j2' %}
application:
image: "{{ pixelfed_image }}:{{ pixelfed_version }}"
container_name: {{ pixelfed_name }}
image: "{{ PIXELFED_IMAGE }}:{{ PIXELFED_VERSION }}"
container_name: {{ PIXELFED_CONTAINER }}
{% include 'roles/docker-container/templates/base.yml.j2' %}
volumes:
- "data:/var/www/storage"
@@ -12,8 +12,8 @@
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
worker:
container_name: {{ pixelfed_worker_name }}
image: "{{ pixelfed_image }}:{{ pixelfed_version }}"
container_name: {{ PIXELFED_WORKER_CONTAINER }}
image: "{{ PIXELFED_IMAGE }}:{{ PIXELFED_VERSION }}"
{% include 'roles/docker-container/templates/base.yml.j2' %}
volumes:
- "data:/var/www/storage"
@@ -31,6 +31,6 @@
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
data:
name: {{ pixelfed_volume }}
name: {{ PIXELFED_VOLUME }}
{% include 'roles/docker-compose/templates/networks.yml.j2' %}

View File

@@ -2,7 +2,7 @@
APP_KEY={{applications | get_app_conf(application_id, 'credentials.app_key', True)}}
## General Settings
APP_NAME="{{ pixelfed_titel }}"
APP_NAME="{{ PIXELFED_TITEL }}"
APP_ENV={{ ENVIRONMENT | lower }}
APP_DEBUG={{MODE_DEBUG | string | lower }}
APP_URL={{ domains | get_url(application_id, WEB_PROTOCOL) }}
@@ -142,7 +142,7 @@ ENABLE_CONFIG_CACHE=true
PF_OIDC_ENABLED={{ applications | get_app_conf(application_id, 'features.oidc', False) | string | lower }}
PF_OIDC_AUTHORIZE_URL="{{ OIDC.CLIENT.AUTHORIZE_URL }}"
PF_OIDC_TOKEN_URL="{{OIDC.CLIENT.TOKEN_URL}}"
PF_OIDC_TOKEN_URL="{{ OIDC.CLIENT.TOKEN_URL }}"
PF_OIDC_PROFILE_URL="{{ OIDC.CLIENT.USER_INFO_URL }}"
PF_OIDC_LOGOUT_URL="{{OIDC.CLIENT.LOGOUT_URL}}"
PF_OIDC_USERNAME_FIELD="{{ OIDC.ATTRIBUTES.USERNAME }}"

View File

@@ -1,9 +1,12 @@
# General
application_id: "web-app-pixelfed"
proxy_extra_configuration: "client_max_body_size 512M;"
database_type: "mariadb"
pixelfed_version: "{{ applications | get_app_conf(application_id, 'docker.services.pixelfed.version', True) }}"
pixelfed_image: "{{ applications | get_app_conf(application_id, 'docker.services.pixelfed.image', True) }}"
pixelfed_name: "{{ applications | get_app_conf(application_id, 'docker.services.pixelfed.name', True) }}"
pixelfed_worker_name: "{{ applications | get_app_conf(application_id, 'docker.services.worker.name', True) }}"
pixelfed_volume: "{{ applications | get_app_conf(application_id, 'docker.volumes.data', True) }}"
pixelfed_titel: "{{ applications | get_app_conf(application_id, 'titel', True) }}"
# Pixelfed
PIXELFED_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.pixelfed.version') }}"
PIXELFED_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.pixelfed.image') }}"
PIXELFED_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.pixelfed.name') }}"
PIXELFED_WORKER_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.worker.name') }}"
PIXELFED_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
PIXELFED_TITEL: "{{ applications | get_app_conf(application_id, 'titel') }}"

View File

@@ -7,17 +7,17 @@ oidc: {}
flavor: 'taigaio' # Potential flavors: robrotheram, taigaio
features:
matomo: true
css: false
desktop: true
css: true
desktop: true
oidc: false
central_database: true
logout: true
docker:
services:
database:
enabled: true
enabled: true
taiga:
version: "latest"
version: "latest"
server:
csp:
flags:

View File

@@ -1,5 +1,5 @@
credentials:
secret_key:
description: "Django SECRET_KEY used for cryptographic signing in Taiga"
algorithm: "sha256"
validation: "^[a-f0-9]{64}$"
description: "Django SECRET_KEY used for cryptographic signing in Taiga"
algorithm: "sha256"
validation: "^[a-f0-9]{64}$"

View File

@@ -3,17 +3,17 @@
include_role:
name: cmp-db-docker-proxy
- name: "copy templates {{ settings_files }} for taiga-contrib-oidc-auth"
- name: "copy templates {{ TAIGA_SETTING_FILES }} for taiga-contrib-oidc-auth"
template:
src: "taiga/{{item}}.py.j2"
dest: "{{ docker_compose.directories.config }}taiga-{{item}}.py"
when: applications | get_app_conf(application_id, 'features.oidc', True) and applications | get_app_conf(application_id, 'oidc.flavor', True) == 'taigaio'
when: TAIGA_TAIGAIO_ENABLED | bool
notify: docker compose up
loop: "{{ settings_files }}"
loop: "{{ TAIGA_SETTING_FILES }}"
- name: "create {{docker_compose_init}}"
- name: "create {{ TAIGA_DOCKER_COMPOSE_INIT }}"
template:
src: "docker-compose-inits.yml.j2"
dest: "{{docker_compose_init}}"
dest: "{{ TAIGA_DOCKER_COMPOSE_INIT }}"
notify: docker compose up

View File

@@ -2,14 +2,14 @@
taiga-back:
{% include 'roles/docker-container/templates/base.yml.j2' %}
image: "{{taiga_image_backend}}:{{ taiga_version }}"
image: "{{ TAIGA_DOCKER_IMAGE_BACKEND }}:{{ TAIGA_VERSION }}"
volumes:
# These volumens will be used by taiga-back and taiga-async.
- static-data:/taiga-back/static
- media-data:/taiga-back/media
# - ./config.py:/taiga-back/settings/config.py
{% if applications | get_app_conf(application_id, 'features.oidc', False) and applications | get_app_conf(application_id, 'oidc.flavor', True) == 'taigaio' %}
{% if TAIGA_TAIGAIO_ENABLED %}
- {{ docker_compose.directories.config }}taiga-local.py:/taiga-back/settings/local.py:ro
@@ -22,7 +22,7 @@
condition: service_started
taiga-async-rabbitmq:
condition: service_started
{% if applications | get_app_conf(application_id, 'features.oidc', False) and applications | get_app_conf(application_id, 'oidc.flavor', True) == 'taigaio' %}
{% if TAIGA_TAIGAIO_ENABLED %}
command: >
/bin/sh -c "
@@ -34,7 +34,7 @@
taiga-async:
{% include 'roles/docker-container/templates/base.yml.j2' %}
image: "{{taiga_image_backend}}:{{ taiga_version }}"
image: "{{ TAIGA_DOCKER_IMAGE_BACKEND }}:{{ TAIGA_VERSION }}"
entrypoint: ["/taiga-back/docker/async_entrypoint.sh"]
volumes:
# These volumens will be used by taiga-back and taiga-async.
@@ -42,9 +42,9 @@
- media-data:/taiga-back/media
# - ./config.py:/taiga-back/settings/config.py
{% if applications | get_app_conf(application_id, 'features.oidc', False) and applications | get_app_conf(application_id, 'oidc.flavor', True) == 'taigaio' %}
{% if TAIGA_TAIGAIO_ENABLED %}
{% for item in settings_files %}
{% for item in TAIGA_SETTING_FILES %}
- {{ docker_compose.directories.config }}taiga-{{ item }}.py:/taiga-back/settings/{{ item }}.py:ro
{% endfor %}
@@ -57,7 +57,7 @@
condition: service_started
taiga-async-rabbitmq:
condition: service_started
{% if applications | get_app_conf(application_id, 'features.oidc', False) and applications | get_app_conf(application_id, 'oidc.flavor', True) == 'taigaio' %}
{% if TAIGA_TAIGAIO_ENABLED %}
command: >
/bin/sh -c "
@@ -76,12 +76,12 @@
taiga:
taiga-front:
image: "{{taiga_image_frontend}}:{{ taiga_version }}"
image: "{{TAIGA_DOCKER_IMAGE_FRONTEND}}:{{ TAIGA_VERSION }}"
{% include 'roles/docker-container/templates/base.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
taiga:
# volumes:
# - {{ taiga_frontend_conf_path }}:/usr/share/nginx/html/conf.json:ro
# - {{ TAIGA_FRONTEND_CONF_PATH }}:/usr/share/nginx/html/conf.json:ro
taiga-events:
image: taigaio/taiga-events:latest

View File

@@ -1,13 +1,13 @@
# Taiga's URLs - Variables to define where Taiga should be served
TAIGA_SITES_SCHEME = https # serve Taiga using "http" or "https" (secured) connection
TAIGA_SITES_SCHEME = {{ WEB_PROTOCOL }} # serve Taiga using "http" or "https" (secured) connection
TAIGA_SITES_DOMAIN = "{{ domains | get_domain(application_id) }}" # Taiga's base URL
TAIGA_SUBPATH = "" # it'll be appended to the TAIGA_DOMAIN (use either "" or a "/subpath")
WEBSOCKETS_SCHEME = wss # events connection protocol (use either "ws" or "wss")
WEBSOCKETS_SCHEME = {{ WEBSOCKET_PROTOCOL }} # events connection protocol (use either "ws" or "wss")
# Taiga's Secret Key - Variable to provide cryptographic signing
TAIGA_SECRET_KEY = "{{applications | get_app_conf(application_id, 'credentials.secret_key', True)}}"
SECRET_KEY = "{{applications | get_app_conf(application_id, 'credentials.secret_key', True)}}"
TAIGA_SECRET_KEY = "{{ applications | get_app_conf(application_id, 'credentials.secret_key') }}"
SECRET_KEY = "{{ applications | get_app_conf(application_id, 'credentials.secret_key') }}"
# Taiga's Database settings - Variables to create the Taiga database and connect to it
POSTGRES_USER = "{{ database_username }}" # user to connect to PostgreSQL
@@ -16,18 +16,17 @@ POSTGRES_DB = "{{ database_name }}"
POSTGRES_HOST = "{{ database_host }}"
# Taiga's SMTP settings - Variables to send Taiga's emails to the users
EMAIL_BACKEND = "{{email_backend}}" # use an SMTP server or display the emails in the console (either "smtp" or "console")
EMAIL_HOST = "{{ SYSTEM_EMAIL.HOST }}" # SMTP server address
EMAIL_PORT = "{{ SYSTEM_EMAIL.PORT }}" # default SMTP port
EMAIL_HOST_USER = "{{ users['no-reply'].email }}" # user to connect the SMTP server
EMAIL_HOST_PASSWORD = "{{ users['no-reply'].mailu_token }}" # SMTP user's password
EMAIL_DEFAULT_FROM = "{{ users['no-reply'].email }}" # default email address for the automated emails
EMAIL_BACKEND: = "django.core.mail.backends.{{email_backend}}.EmailBackend"
EMAIL_BACKEND = "{{ TAIGA_EMAIL_BACKEND }}" # use an SMTP server or display the emails in the console (either "smtp" or "console")
EMAIL_HOST = "{{ SYSTEM_EMAIL.HOST }}" # SMTP server address
EMAIL_PORT = "{{ SYSTEM_EMAIL.PORT }}" # default SMTP port
EMAIL_HOST_USER = "{{ users['no-reply'].email }}" # user to connect the SMTP server
EMAIL_HOST_PASSWORD = "{{ users['no-reply'].mailu_token }}" # SMTP user's password
EMAIL_DEFAULT_FROM = "{{ users['no-reply'].email }}" # default email address for the automated emails
DEFAULT_FROM_EMAIL = "{{ users['no-reply'].email }}"
# EMAIL_USE_TLS/EMAIL_USE_SSL are mutually exclusive (only set one of those to True)
EMAIL_USE_TLS = "{{ SYSTEM_EMAIL.TLS | capitalize }}" # use TLS (secure) connection with the SMTP server
EMAIL_USE_SSL = "{{ 'False' if SYSTEM_EMAIL.START_TLS else 'True' }}" # use implicit TLS (secure) connection with the SMTP server
EMAIL_USE_TLS = "{{ SYSTEM_EMAIL.TLS | capitalize }}" # use TLS (secure) connection with the SMTP server
EMAIL_USE_SSL = "{{ 'False' if SYSTEM_EMAIL.START_TLS else 'True' }}" # use implicit TLS (secure) connection with the SMTP server
RABBITMQ_USER=taiga
RABBITMQ_PASS=taiga
@@ -47,9 +46,9 @@ MAX_AGE = 360
# Taiga's Telemetry - Variable to enable or disable the anonymous telemetry
ENABLE_TELEMETRY = True
{% if applications | get_app_conf(application_id, 'features.oidc', False) %}
{% if TAIGA_OIDC_ENABLED %}
{% if applications | get_app_conf(application_id, 'oidc.flavor', True) == 'taigaio' %}
{% if TAIGA_TAIGAIO_ENABLED %}
# OIDC via taigaio official contrib
# @See https://github.com/taigaio/taiga-contrib-oidc-auth
@@ -65,14 +64,14 @@ OIDC_OP_JWKS_ENDPOINT="{{ OIDC.CLIENT.CERTS }}"
{% endif %}
{% if applications | get_app_conf(application_id, 'oidc.flavor', True) == 'robrotheram' %}
{% if TAIGA_FLAVOR_ROBROTHERAM %}
# OIDC via robrotheram
# @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.TOKEN_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="{{ OIDC.BUTTON_TEXT }}"

View File

@@ -1,18 +1,24 @@
# General
application_id: "web-app-taiga"
database_type: "postgres"
# 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")
docker_compose_init: "{{ docker_compose.directories.instance }}docker-compose-inits.yml.j2"
taiga_image_backend: >-
{{ 'robrotheram/taiga-back-openid' if applications | get_app_conf(application_id, 'features.oidc', True) and applications | get_app_conf(application_id, 'oidc.flavor', True) == 'robrotheram'
else 'taigaio/taiga-back' }}
taiga_image_frontend: >-
{{ 'robrotheram/taiga-front-openid' if applications | get_app_conf(application_id, 'features.oidc', True) and applications | get_app_conf(application_id, 'oidc.flavor', True) == 'robrotheram'
else 'taigaio/taiga-front' }}
taiga_frontend_conf_path: "{{docker_compose.directories.config}}conf.json"
docker_pull_git_repository: true
settings_files:
docker_pull_git_repository: true
# Taiga
TAIGA_OIDC_ENABLED: "{{ applications | get_app_conf(application_id, 'features.oidc') }}"
TAIGA_FLAVOR_ROBROTHERAM: "{{ applications | get_app_conf(application_id, 'oidc.flavor') == 'robrotheram' }}"
TAIGA_ROBROTHERAM_ENABLED: "{{ TAIGA_OIDC_ENABLED and TAIGA_FLAVOR_ROBROTHERAM }}"
TAIGA_FLAVOR_TAIGAIO: "{{ applications | get_app_conf(application_id, 'oidc.flavor') == 'taigaio' }}"
TAIGA_TAIGAIO_ENABLED: "{{ TAIGA_OIDC_ENABLED and TAIGA_FLAVOR_TAIGAIO }}"
TAIGA_EMAIL_BACKEND: "{{ 'smtp' if SYSTEM_EMAIL.SMTP else 'console' }}" ## use an SMTP server or display the emails in the console (either "smtp" or "console")
TAIGA_DOCKER_COMPOSE_INIT: "{{ [ docker_compose.directories.instance,'docker-compose-inits.yml.j2' ] | path_join }}"
TAIGA_DOCKER_IMAGE_BACKEND: "{{ 'robrotheram/taiga-back-openid' if TAIGA_ROBROTHERAM_ENABLED else 'taigaio/taiga-back' }}"
TAIGA_DOCKER_IMAGE_FRONTEND: "{{ 'robrotheram/taiga-front-openid' if TAIGA_ROBROTHERAM_ENABLED else 'taigaio/taiga-front' }}"
TAIGA_FRONTEND_CONF_PATH: "{{ [ docker_compose.directories.config,'conf.json' ] | path_join }}"
TAIGA_SETTING_FILES:
- urls
- local
taiga_version: "{{ applications | get_app_conf(application_id, 'docker.services.taiga.version', True) }}"
TAIGA_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.taiga.version') }}"

View File

@@ -1,27 +1,27 @@
# The seeds need to be executed as root, because www-data isn't allowed to create files in the wordpress directory
- name: Update DB host in {{ wordpress_config_file }}
- name: Update DB host in {{ WORDPRESS_CONFIG_FILE }}
command: >
docker exec --user root {{ wordpress_container }}
sed -i "s/define(\s*'DB_HOST'\s*,\s*'[^']*'\s*);/define( 'DB_HOST', '{{ database_host }}:{{ database_port }}' );/i" {{ wordpress_docker_conf_path }}
docker exec --user root {{ WORDPRESS_CONTAINER }}
sed -i "s/define(\s*'DB_HOST'\s*,\s*'[^']*'\s*);/define( 'DB_HOST', '{{ database_host }}:{{ database_port }}' );/i" {{ WORDPRESS_DOCKER_CONF_PATH }}
notify: docker compose restart
- name: Update DB name in {{ wordpress_config_file }}
- name: Update DB name in {{ WORDPRESS_CONFIG_FILE }}
command: >
docker exec --user root {{ wordpress_container }}
sed -i "s/define(\s*'DB_NAME'\s*,\s*'[^']*'\s*);/define( 'DB_NAME', '{{ database_name }}' );/i" {{ wordpress_docker_conf_path }}
docker exec --user root {{ WORDPRESS_CONTAINER }}
sed -i "s/define(\s*'DB_NAME'\s*,\s*'[^']*'\s*);/define( 'DB_NAME', '{{ database_name }}' );/i" {{ WORDPRESS_DOCKER_CONF_PATH }}
notify: docker compose restart
- name: Update DB user in {{ wordpress_config_file }}
- name: Update DB user in {{ WORDPRESS_CONFIG_FILE }}
command: >
docker exec --user root {{ wordpress_container }}
sed -i "s/define(\s*'DB_USER'\s*,\s*'[^']*'\s*);/define( 'DB_USER', '{{ database_username }}' );/i" {{ wordpress_docker_conf_path }}
docker exec --user root {{ WORDPRESS_CONTAINER }}
sed -i "s/define(\s*'DB_USER'\s*,\s*'[^']*'\s*);/define( 'DB_USER', '{{ database_username }}' );/i" {{ WORDPRESS_DOCKER_CONF_PATH }}
notify: docker compose restart
- name: Update DB password in {{ wordpress_config_file }}
- name: Update DB password in {{ WORDPRESS_CONFIG_FILE }}
command: >
docker exec --user root {{ wordpress_container }}
sed -i "s/define(\s*'DB_PASSWORD'\s*,\s*'[^']*'\s*);/define( 'DB_PASSWORD', '{{ database_password }}' );/i" {{ wordpress_docker_conf_path }}
docker exec --user root {{ WORDPRESS_CONTAINER }}
sed -i "s/define(\s*'DB_PASSWORD'\s*,\s*'[^']*'\s*);/define( 'DB_PASSWORD', '{{ database_password }}' );/i" {{ WORDPRESS_DOCKER_CONF_PATH }}
notify: docker compose restart
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"

View File

@@ -1,13 +1,13 @@
- name: "Run WordPress core install via WP CLI"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
command: >
docker exec -u {{ wordpress_user }} {{ wordpress_container }}
docker exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER }}
wp core install
--url="{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
--title="{{ applications | get_app_conf(application_id, 'title', True) }}"
--admin_user="{{ applications | get_app_conf(application_id, 'users.administrator.username') }}"
--admin_password="{{ applications | get_app_conf(application_id, 'credentials.administrator_password', True) }}"
--admin_email="{{ applications | get_app_conf(application_id, 'users.administrator.email', True) }}"
--path="{{ wordpress_docker_html_path }}"
--path="{{ WORDPRESS_DOCKER_HTML_PATH }}"
args:
chdir: "{{ docker_compose.directories.instance }}"

View File

@@ -12,7 +12,7 @@
command: >
docker-compose exec -u www-data -T application
wp plugin install {{ plugin_name }} --activate
--path={{ wordpress_docker_html_path }}
--path={{ WORDPRESS_DOCKER_HTML_PATH }}
args:
chdir: "{{ docker_compose.directories.instance }}"
when: not plugin_task_file.stat.exists

View File

@@ -1,19 +1,19 @@
---
# Updates WordPress single-site URLs and normalizes DB references.
# Expects: wp_new_url (passed from main.yml), wordpress_user/container/docker_html_path.
# Expects: wp_new_url (passed from main.yml), WORDPRESS_USER/container/docker_html_path.
- name: Get current 'home' URL
command: >
docker exec -u {{ wordpress_user }} {{ wordpress_container }}
wp option get home --path={{ wordpress_docker_html_path }}
docker exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER }}
wp option get home --path={{ WORDPRESS_DOCKER_HTML_PATH }}
register: wp_home
changed_when: false
failed_when: false
- name: Get current 'siteurl'
command: >
docker exec -u {{ wordpress_user }} {{ wordpress_container }}
wp option get siteurl --path={{ wordpress_docker_html_path }}
docker exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER }}
wp option get siteurl --path={{ WORDPRESS_DOCKER_HTML_PATH }}
register: wp_siteurl
changed_when: false
failed_when: false
@@ -23,8 +23,8 @@
wp_new_url_norm: "{{ wp_new_url | regex_replace('/+$','') }}"
wp_home_norm: "{{ wp_home.stdout | regex_replace('/+$','') }}"
command: >
docker exec -u {{ wordpress_user }} {{ wordpress_container }}
wp option update home "{{ wp_new_url_norm }}" --path={{ wordpress_docker_html_path }}
docker exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER }}
wp option update home "{{ wp_new_url_norm }}" --path={{ WORDPRESS_DOCKER_HTML_PATH }}
when: wp_home_norm != wp_new_url_norm
- name: Update 'siteurl' (if needed)
@@ -32,8 +32,8 @@
wp_new_url_norm: "{{ wp_new_url | regex_replace('/+$','') }}"
wp_siteurl_norm: "{{ wp_siteurl.stdout | regex_replace('/+$','') }}"
command: >
docker exec -u {{ wordpress_user }} {{ wordpress_container }}
wp option update siteurl "{{ wp_new_url_norm }}" --path={{ wordpress_docker_html_path }}
docker exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER }}
wp option update siteurl "{{ wp_new_url_norm }}" --path={{ WORDPRESS_DOCKER_HTML_PATH }}
when: wp_siteurl_norm != wp_new_url_norm
- name: Search-replace old → new URLs in DB (single site)
@@ -41,10 +41,10 @@
wp_old_url_norm: "{{ wp_home.stdout | regex_replace('/+$','') }}"
wp_new_url_norm: "{{ wp_new_url | regex_replace('/+$','') }}"
command: >
docker exec -u {{ wordpress_user }} {{ wordpress_container }}
docker exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER }}
wp search-replace "{{ wp_old_url_norm }}" "{{ wp_new_url_norm }}"
--skip-columns=guid --all-tables-with-prefix --precise
--path={{ wordpress_docker_html_path }}
--path={{ WORDPRESS_DOCKER_HTML_PATH }}
register: wp_sr_domain
changed_when: "{{ ('Success: Made 0 replacements.' not in wp_sr_domain.stdout) | bool }}"
@@ -54,15 +54,15 @@
http_url: "http://{{ domain_only }}"
https_url: "https://{{ domain_only }}"
command: >
docker exec -u {{ wordpress_user }} {{ wordpress_container }}
docker exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER }}
wp search-replace "{{ http_url }}" "{{ https_url }}"
--skip-columns=guid --all-tables-with-prefix --precise
--path={{ wordpress_docker_html_path }}
--path={{ WORDPRESS_DOCKER_HTML_PATH }}
register: wp_sr_scheme
changed_when: "{{ ('Success: Made 0 replacements.' not in wp_sr_scheme.stdout) | bool }}"
- name: Flush caches and rewrite rules
command: >
docker exec -u {{ wordpress_user }} {{ wordpress_container }} bash -lc
"wp cache flush --path={{ wordpress_docker_html_path }} &&
wp rewrite flush --hard --path={{ wordpress_docker_html_path }}"
docker exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER }} bash -lc
"wp cache flush --path={{ WORDPRESS_DOCKER_HTML_PATH }} &&
wp rewrite flush --hard --path={{ WORDPRESS_DOCKER_HTML_PATH }}"

View File

@@ -2,11 +2,11 @@
- name: "Include role srv-domain-provision for {{ application_id }}"
include_role:
name: srv-domain-provision
loop: "{{ wordpress_domains }}"
loop: "{{ WORDPRESS_DOMAINS }}"
loop_control:
loop_var: domain
vars:
proxy_extra_configuration: "client_max_body_size {{ wordpress_max_upload_size }};"
proxy_extra_configuration: "client_max_body_size {{ WORDPRESS_MAX_UPLOAD_SIZE }};"
http_port: "{{ ports.localhost.http[application_id] }}"
- name: "load docker and db for {{ application_id }}"
@@ -21,22 +21,22 @@
dest: "{{ docker_compose.directories.instance }}upload.ini"
notify: docker compose up
- name: "Transfering msmtprc to {{ host_msmtp_conf }}"
- name: "Transfering msmtprc to {{ WORDPRESS_HOST_MSMTP_CONF }}"
template:
src: "{{ playbook_dir }}/roles/sys-svc-msmtp/templates/msmtprc.conf.j2"
dest: "{{ host_msmtp_conf }}"
dest: "{{ WORDPRESS_HOST_MSMTP_CONF }}"
notify: docker compose up
- name: Flush handlers to make {{ wordpress_config_file }} available before patch
- name: Flush handlers to make {{ WORDPRESS_CONFIG_FILE }} available before patch
meta: flush_handlers
- name: Check if {{ wordpress_config_file }} exists in WordPress
command: docker exec -u {{ wordpress_user }} {{ wordpress_container }} test -f {{ wordpress_config_path }}
- name: Check if {{ WORDPRESS_CONFIG_FILE }} exists in WordPress
command: docker exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER }} test -f {{ WORDPRESS_CONFIG_PATH }}
register: wp_config_file_exists
changed_when: false
failed_when: false
- name: Patch WordPress {{ wordpress_config_file }} with updated DB credentials
- name: Patch WordPress {{ WORDPRESS_CONFIG_FILE }} with updated DB credentials
include_tasks: 01_patch_config.yml
when: wp_config_file_exists.rc == 0
@@ -47,7 +47,7 @@
block:
- name: "Iterate through WordPress plugins"
include_tasks: 03_enable_plugin.yml
loop: "{{ wordpress_plugins }}"
loop: "{{ WORDPRESS_PLUGINS }}"
loop_control:
label: "{{ item.key }}"
vars:
@@ -58,8 +58,8 @@
- name: Detect if WordPress is Multisite
command: >
docker exec -u {{ wordpress_user }} {{ wordpress_container }}
wp eval 'echo (int) is_multisite();' --path={{ wordpress_docker_html_path }}
docker exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER }}
wp eval 'echo (int) is_multisite();' --path={{ WORDPRESS_DOCKER_HTML_PATH }}
register: wp_is_multisite
changed_when: false

View File

@@ -7,9 +7,9 @@
# Generate an empty serialized array in the container, then add or update the option
command: >
docker-compose exec -u www-data -T application bash -lc
"serialized_empty_array=$(wp eval 'echo serialize(array());' --path={{ wordpress_docker_html_path }}); \
wp option add openid_connect_generic_settings \"$serialized_empty_array\" --path={{ wordpress_docker_html_path }} \
|| wp option update openid_connect_generic_settings \"$serialized_empty_array\" --path={{ wordpress_docker_html_path }};"
"serialized_empty_array=$(wp eval 'echo serialize(array());' --path={{ WORDPRESS_DOCKER_HTML_PATH }}); \
wp option add openid_connect_generic_settings \"$serialized_empty_array\" --path={{ WORDPRESS_DOCKER_HTML_PATH }} \
|| wp option update openid_connect_generic_settings \"$serialized_empty_array\" --path={{ WORDPRESS_DOCKER_HTML_PATH }};"
args:
chdir: "{{ docker_compose.directories.instance }}"
failed_when: false
@@ -20,6 +20,6 @@
oidc_settings_json_b64: "{{ oidc_vars.oidc_settings | to_json | b64encode }}"
command: >
docker-compose exec -u www-data -T application bash -lc
"wp eval \"update_option('openid_connect_generic_settings', json_decode(base64_decode('{{ oidc_settings_json_b64 }}'), true));\" --path={{ wordpress_docker_html_path }}"
"wp eval \"update_option('openid_connect_generic_settings', json_decode(base64_decode('{{ oidc_settings_json_b64 }}'), true));\" --path={{ WORDPRESS_DOCKER_HTML_PATH }}"
args:
chdir: "{{ docker_compose.directories.instance }}"

View File

@@ -56,7 +56,7 @@
command: >
docker-compose exec -u www-data -T application
wp plugin install wp-discourse --activate
--path={{ wordpress_docker_html_path }}
--path={{ WORDPRESS_DOCKER_HTML_PATH }}
args:
chdir: "{{ docker_compose.directories.instance }}"
@@ -89,6 +89,6 @@
base64_decode('{{ option_json_b64 }}'),
true
)
);\" --path={{ wordpress_docker_html_path }}"
);\" --path={{ WORDPRESS_DOCKER_HTML_PATH }}"
args:
chdir: "{{ docker_compose.directories.instance }}"

View File

@@ -1,4 +1,4 @@
FROM {{ wordpress_image }}:{{ wordpress_version }}
FROM {{ WORDPRESS_IMAGE }}:{{ WORDPRESS_VERSION }}
# Install msmtp and update system
RUN apt-get update && \
@@ -10,6 +10,5 @@ RUN curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli
chmod +x wp-cli.phar && \
mv wp-cli.phar /usr/local/bin/wp
# Copy msmtp configuration and PHP upload settings
COPY config/msmtprc.conf /etc/msmtprc
# Copy PHP upload settings
COPY upload.ini $PHP_INI_DIR/conf.d/

View File

@@ -1,14 +1,15 @@
{% include 'roles/docker-compose/templates/base.yml.j2' %}
application:
{% include 'roles/docker-container/templates/base.yml.j2' %}
image: {{ wordpress_custom_image }}
container_name: {{ wordpress_container }}
image: {{ WORDPRESS_CUSTOM_IMAGE }}
container_name: {{ WORDPRESS_CONTAINER }}
build:
context: .
ports:
- "127.0.0.1:{{ ports.localhost.http[application_id] }}:80"
volumes:
- data:{{ wordpress_docker_html_path }}
- data:{{ WORDPRESS_DOCKER_HTML_PATH }}
- {{ WORDPRESS_HOST_MSMTP_CONF }}:/etc/msmtprc
{% include 'roles/docker-container/templates/healthcheck/msmtp_curl.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
@@ -18,4 +19,4 @@
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
data:
name: "{{ wordpress_volume }}"
name: "{{ WORDPRESS_VOLUME }}"

View File

@@ -1,7 +1,7 @@
file_uploads = On
memory_limit = {{ wordpress_max_upload_size }}
upload_max_filesize = {{ wordpress_max_upload_size }}
post_max_size = {{ wordpress_max_upload_size }}
memory_limit = {{ WORDPRESS_MAX_UPLOAD_SIZE }}
upload_max_filesize = {{ WORDPRESS_MAX_UPLOAD_SIZE }}
post_max_size = {{ WORDPRESS_MAX_UPLOAD_SIZE }}
max_execution_time = 300
; Use msmtp as the Mail Transfer Agent

View File

@@ -1,19 +1,19 @@
# General
application_id: "web-app-wordpress"
database_type: "mariadb"
host_msmtp_conf: "{{docker_compose.directories.config}}msmtprc.conf"
# WordPress Specific
wordpress_max_upload_size: "{{ applications | get_app_conf(application_id, 'max_upload_size') }}"
wordpress_custom_image: "wordpress_custom"
wordpress_docker_html_path: "/var/www/html"
wordpress_docker_conf_path: "{{ wordpress_config_path }}"
wordpress_version: "{{ applications | get_app_conf(application_id, 'docker.services.wordpress.version', True) }}"
wordpress_image: "{{ applications | get_app_conf(application_id, 'docker.services.wordpress.image', True) }}"
wordpress_container: "{{ applications | get_app_conf(application_id, 'docker.services.wordpress.name', True) }}"
wordpress_volume: "{{ applications | get_app_conf(application_id, 'docker.volumes.data', True) }}"
wordpress_domains: "{{ applications | get_app_conf(application_id, 'server.domains.canonical', True) }}"
wordpress_plugins: "{{ applications | get_app_conf(application_id, 'plugins', True) | dict2items }}"
wordpress_user: "www-data"
wordpress_config_file: "wp-config.php"
wordpress_config_path: "{{ wordpress_docker_html_path }}/{{ wordpress_config_file }}"
WORDPRESS_HOST_MSMTP_CONF: "{{ [ docker_compose.directories.config, 'msmtprc.conf'] | path_join }}"
WORDPRESS_MAX_UPLOAD_SIZE: "{{ applications | get_app_conf(application_id, 'max_upload_size') }}"
WORDPRESS_CUSTOM_IMAGE: "wordpress_custom"
WORDPRESS_DOCKER_HTML_PATH: "/var/www/html"
WORDPRESS_DOCKER_CONF_PATH: "{{ WORDPRESS_CONFIG_PATH }}"
WORDPRESS_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.wordpress.version') }}"
WORDPRESS_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.wordpress.image') }}"
WORDPRESS_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.wordpress.name') }}"
WORDPRESS_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
WORDPRESS_DOMAINS: "{{ applications | get_app_conf(application_id, 'server.domains.canonical') }}"
WORDPRESS_PLUGINS: "{{ applications | get_app_conf(application_id, 'plugins') | dict2items }}"
WORDPRESS_USER: "www-data"
WORDPRESS_CONFIG_FILE: "wp-config.php"
WORDPRESS_CONFIG_PATH: "{{ [WORDPRESS_DOCKER_HTML_PATH, WORDPRESS_CONFIG_FILE] | path_join }}"

View File

@@ -1,38 +0,0 @@
# It isn't best practice to use this task
# Better load the repositories into /opt/docker/[servicename]/services, build them there and then use a docker-compose file for customizing
# @todo Refactor\Remove
# @deprecated
- name: "Merge detached_files with applications | get_app_conf('web-app-oauth2-proxy','configuration_file')"
set_fact:
merged_detached_files: "{{ detached_files + [applications | get_app_conf('web-app-oauth2-proxy','configuration_file')] }}"
when: "{{ applications | get_app_conf(application_id,'features.oauth2')"
- name: "backup detached files"
command: >
mv "{{ docker_compose.directories.instance }}{{ item }}" "/tmp/{{ application_id }}-{{ item }}.backup"
args:
removes: "{{ docker_compose.directories.instance }}{{ item }}"
become: true
loop: "{{ merged_detached_files | default(detached_files) }}"
- name: checkout repository
ansible.builtin.shell: git checkout .
become: true
args:
chdir: "{{ docker_compose.directories.instance }}"
ignore_errors: true
- name: "restore detached files"
command: >
mv "/tmp/{{ application_id }}-{{ item }}.backup" "{{ docker_compose.directories.instance }}{{ item }}"
args:
removes: "/tmp/{{ application_id }}-{{ item }}.backup"
become: true
loop: "{{ merged_detached_files | default(detached_files) }}"
- name: "copy {{ detached_files }} templates to server"
template:
src: "{{ item }}.j2"
dest: "{{ docker_compose.directories.instance }}{{ item }}"
loop: "{{ detached_files }}"
notify: docker compose up