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
This commit is contained in:
2025-08-27 14:58:44 +02:00
parent 5446a1497e
commit 5287bb4d74
10 changed files with 142 additions and 94 deletions

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' }}"