feat(keycloak|docker): improved templating

Signed-off-by: Tuan-Dat Tran <tuan-dat.tran@tudattr.dev>
This commit is contained in:
Tuan-Dat Tran
2025-04-25 23:36:44 +02:00
parent 42196a32dc
commit a2a58f6343
5 changed files with 157 additions and 131 deletions

View File

@@ -12,7 +12,6 @@ services:
- docker-host00
container_name: syncthing
image: syncthing/syncthing:1.29
restart: unless-stopped
volumes:
- name: "Data"
internal: /var/syncthing/
@@ -39,7 +38,6 @@ services:
- docker-host00
container_name: kuma
image: louislam/uptime-kuma:1.23.16
restart: unless-stopped
volumes:
- name: "Data"
internal: /app/data
@@ -57,7 +55,6 @@ services:
- docker-host00
container_name: plex
image: lscr.io/linuxserver/plex:1.41.5
restart: unless-stopped
volumes:
- name: "Configuration"
internal: /config
@@ -110,7 +107,6 @@ services:
- docker-host01
container_name: jellyfin
image: jellyfin/jellyfin:10.10
restart: "unless-stopped"
volumes:
- name: "Configuration"
internal: /config
@@ -141,7 +137,6 @@ services:
- docker-host01
container_name: homeassistant
image: "ghcr.io/home-assistant/home-assistant:stable"
restart: unless-stopped
privileged: true
volumes:
- name: "Configuration"
@@ -168,7 +163,6 @@ services:
- docker-host00
container_name: ddns-updater
image: qmcgaw/ddns-updater:2
restart: unless-stopped
volumes:
- name: "Configuration"
internal: /updater/data/"
@@ -182,7 +176,6 @@ services:
- docker-host00
container_name: sonarr
image: linuxserver/sonarr:4.0.14
restart: unless-stopped
volumes:
- name: "Configuration"
internal: /config
@@ -206,7 +199,6 @@ services:
- docker-host00
container_name: radarr
image: linuxserver/radarr:5.21.1
restart: unless-stopped
volumes:
- name: "Configuration"
internal: /config
@@ -230,7 +222,6 @@ services:
- docker-host00
container_name: lidarr
image: linuxserver/lidarr:2.10.3
restart: unless-stopped
volumes:
- name: "Configuration"
internal: /config
@@ -254,7 +245,6 @@ services:
- docker-host00
container_name: prowlarr
image: linuxserver/prowlarr:1.32.2
restart: unless-stopped
volumes:
- name: "Configuration"
internal: /config
@@ -272,10 +262,9 @@ services:
- docker-host00
container_name: paperless
image: ghcr.io/paperless-ngx/paperless-ngx:2.14
restart: unless-stopped
depends_on:
- paperless-postgres
- paperless-broker
- paperless-redis
volumes:
- name: "Configuration"
internal: /usr/src/paperless/data
@@ -290,7 +279,7 @@ services:
internal: /usr/src/paperless/consume
external: "{{ docker.directories.local }}/paperless/data/consume"
environment:
- "PAPERLESS_REDIS=redis://paperless-broker:6379"
- "PAPERLESS_REDIS=redis://paperless-redis:6379"
- "PAPERLESS_DBHOST=paperless-postgres"
- "PAPERLESS_DBUSER=paperless"
- "PAPERLESS_DBPASS={{ vault.docker.paperless.dbpass }}"
@@ -303,12 +292,18 @@ services:
- name: "http"
internal: 8000
external: "{{ services_external_http.paperless }}"
sub_service:
- name: postgres
version: 15
username: paperless
password: "{{ vault.docker.paperless.dbpass }}"
- name: redis
version: 7
- name: pdf
vm:
- docker-host00
container_name: stirling
image: frooodle/s-pdf:0.45.0
restart: unless-stopped
ports:
- name: "http"
internal: 8080
@@ -318,7 +313,6 @@ services:
- docker-host01
container_name: gitea
image: gitea/gitea:1.23-rootless
restart: unless-stopped
volumes:
- name: "Configuration"
internal: /etc/gitea
@@ -347,7 +341,6 @@ services:
- docker-host00
container_name: changedetection
image: dgtlmoon/changedetection.io:0.49
restart: unless-stopped
volumes:
- name: "Data"
internal: /datastore
@@ -361,7 +354,6 @@ services:
- docker-host00
container_name: gluetun
image: qmcgaw/gluetun:v3.40
restart: unless-stopped
cap_add:
- NET_ADMIN
devices:
@@ -394,7 +386,6 @@ services:
- docker-host00
container_name: torrentleech
image: qbittorrentofficial/qbittorrent-nox
restart: unless-stopped
depends_on:
- gluetun
network_mode: "container:gluetun"
@@ -420,7 +411,6 @@ services:
- docker-host00
container_name: qbit
image: qbittorrentofficial/qbittorrent-nox:5.0.4-1
restart: unless-stopped
depends_on:
- gluetun
network_mode: "container:gluetun"
@@ -447,7 +437,6 @@ services:
- docker-host01
container_name: cadvisor
image: gcr.io/cadvisor/cadvisor:v0.52.1
restart: unless-stopped
ports:
- name: ""
internal: 8080
@@ -470,7 +459,6 @@ services:
- docker-host01
container_name: karakeep
image: ghcr.io/karakeep-app/karakeep:0.23.2
restart: unless-stopped
ports:
- name: "http"
internal: 3000
@@ -488,12 +476,21 @@ services:
- OPENAI_API_KEY={{ vault.docker.karakeep.openai_key }}
- DATA_DIR=/data
- DISABLE_SIGNUPS=true
sub_service:
- name: meilisearch
version: v1.11.1
nextauth_secret: "{{ vault.docker.karakeep.nextauth_secret }}"
meili_master_key: "{{ vault.docker.karakeep.meili_master_key }}"
openai_key: "{{ vault.docker.karakeep.openai_key }}"
- name: chrome
version: 123
- name: keycloak
vm:
- docker-host01
container_name: keycloak
image: quay.io/keycloak/keycloak:26.2
restart: unless-stopped
depends_on:
- keycloak-postgres
ports:
- name: "http"
internal: 8080
@@ -502,14 +499,17 @@ services:
- name: "config"
internal: /opt/keycloak/data/import/homelab-realm.json
external: "{{ docker.directories.local }}/keycloak/homelab-realm.json"
- name: "config"
internal: /opt/keycloak/data/import/master-realm.json
external: "{{ docker.directories.local }}/keycloak/master-realm.json"
command:
- "start"
- "--import-realm"
environment:
- KC_DB=postgres
- KC_DB_URL=jdbc:postgresql://postgres:5432/keycloak
- KC_DB_USERNAME=keycloak
- KC_DB_PASSWORD=password
- KC_DB_URL=jdbc:postgresql://keycloak-postgres:5432/keycloak
- KC_DB_USERNAME={{ keycloak_config.database.username }}
- KC_DB_PASSWORD={{ keycloak_config.database.password }}
- KC_HOSTNAME=keycloak.{{ internal_domain }}
- KC_HTTP_ENABLED=true
- KC_HTTP_RELATIVE_PATH=/
@@ -518,4 +518,9 @@ services:
- KC_HOSTNAME_URL=https://keycloak.{{ internal_domain }}
- KC_HOSTNAME_ADMIN_URL=https://keycloak.{{ internal_domain }}
- KC_BOOTSTRAP_ADMIN_USERNAME=serviceadmin-{{ keycloak_admin_hash }}
- KC_BOOTSTRAP_ADMIN_PASSWORD={{ vault.docker.keycloak.admin.password }
- KC_BOOTSTRAP_ADMIN_PASSWORD={{ vault.docker.keycloak.admin.password }}
sub_service:
- name: postgres
version: 17
username: "{{ keycloak_config.database.username }}"
password: "{{ keycloak_config.database.password }}"

View File

@@ -1,7 +1,13 @@
keycloak_admin_hash: "{{ vault.docker.keycloak.admin.hash }}"
keycloak_realms: "{{ keycloak_config.realms }}"
keycloak_config:
reals:
database:
db_name: keycloak
username: keycloak
password: "{{ vault.docker.keycloak.database.password }}"
realms:
- realm: homelab
display_name: "Homelab Realm"
users:
@@ -42,6 +48,7 @@ keycloak_config:
realm_roles:
- offline_access
- uma_authorization
- create-realm
- admin
client_roles:
realm_management:
@@ -49,3 +56,6 @@ keycloak_config:
account:
- view-profile
- manage-account
roles:
realm: []
default_roles: []

View File

@@ -1,51 +1,56 @@
$ANSIBLE_VAULT;1.1;AES256
66363634613334353739343565353932393932633064623536666362323639643230343866313864
6331373639363262343664396131626632653232666439630a663333323564343763303266626362
30356631633633623535616136326438353166633637353339353461333439333364313437653364
6565653535616330330a386639643730366535346233303463303030306437303931623839356538
36666562353861373435366131373535613733323338393030396335646138653361653538386263
63373763643031343831643339653964653337316264356536376261643664373465323231643534
64646565643734613035326463653331613366356163326561383765653264336265313439346130
39623661643264633838386362313866386536326461336232333564343634363437653863346664
63376662643731663834303830393561353031653334386161663938636665383362313236626530
34663231343039376639306264383539663263306166343335363663303664326631633534333263
63613565656263623066376239313330313464303635613366613537333063616666393532363635
65363237613262303161326530336464313262653665633630396562616534653464666638666138
35396139363033353530353266376230366165653261323837303966623032356236303631363234
63366338333266616263376636373836313333373936313562626237306631646434383738396537
63333262306637326330623236323335326530383231626534616666616530373463656534336330
37383239376237663730323137623638353062666566373464343935613239343038386335323064
62653436343563643065373238326339663032636634326365393131373439343736633332366566
64366635633939326262336238653531653738353263663539383361303466393661616231326532
66666537653230396661616361653163663231653463336639343236333462656138386163346537
62613866623862383236366161623939386337396133393563623133656461633036633731353234
37643733343333613063656531356432363666383638343439396332316164633532383934663666
32373039636232343930613762386339613963613933316130313565323364343863363139306262
31636532306234613534366364386666366538663231386166666538633737373134396637306664
62376537356137626366376636373564373039633135376462343865393831303733356165393938
34633534356466313530333762333631336563346338613737633930386461346132613338346438
64663362646364626362396264333563623263306133343438383166663339333133623639613435
66373831353862323432666132626265656536653163343437373465303139326536326534373832
63626137643031356335353137333962633535323331613038646265313037616431353761383465
37623134656163613835353866313562623366336439386138646337363764333662346139323565
34386463313730333761646465633936626436343166613636353938343039636239663031366335
65336661343635346665393766623730316665323865643663623361666265373439376336396431
34333035633337353663623966303738393261663433373039666539333861663538663431333664
34363036313332616435383638353165663333343638356661326538333734313136636630623832
37303663633433623638616364313239623736323832336161303735663030386138643636386633
34396234363238623635633135373439643839333266643331633365326161353836643735636463
63613538313839336337616561353836346339623761636630303037383766393362366636323533
64333139623532346463346532316132323664366132646636636639636361653734343733386465
39643437666464663930303934343239383539346638643332396166383737336461646333326335
62626230396662366563356664366662396331613235356665376162626637613336333764313261
32393663306163613235336262663562646636656366393538656561333139323339313233373833
33376633303964356261656265653435663339333031323133656331663231626339633533396638
33316339356339383031306535373434636464376337303938636261363833363830613464323263
31353764353933656332353633393338386637373334623766396430646261666236333162633136
64623034653163303166346235373335396533343461663763643664363561383331386335393631
65333534636139356538306434356364656339313938383566343633626663376533373564636430
35356539343233313234343232323465323433313839633764326433303732356665666630616534
34343736663263303336656135393534366462323936383161646533623064376638346330396339
64653066343062396135666335643533353439663535333037373661346166623030613235396433
37653335666533373365633233393338376166343637393432383666313139643564383638333666
3461306330623163336465303963643836653238306330363034
32623863646365383136636631383936353032333935623162386465643139663835303063666138
3336626338376466386265663737383062653236383430310a633138323038626134636362616166
37383831323239366338333038326665643932643237656265316361323466376636373662343761
6234366130373535330a343432663638393566613963303530653937613139366330653933376137
65356265306139326361336632323332663135373735626539376565313466323236323862623531
65623932633936666338653164646661373937376133333937336434613264393637363065353462
31376333336433643432626531373731656238336431376630653832363437646665353333313764
63656565326636383537373736303933636264633939323262656363346639376439383632386530
64373230623135316634323565623736386263613630383038643636323965326464333533333136
30346132616237356662626462363266376261333434663634353330613137626538376433333235
63346434386538663335333262386536663330653835343335323636363233333135626434356131
61346465643231646338346435396662323834373634613834393231326531666637636566316434
66663737643037336332313338663739653939333866383835663835386165373664623433623237
35353734616431666561656231336463336234656362623265356361626161383136653064616664
35623638653935643465646538653931643935313638366133343233616565623433376435323739
31376236626131623765303761396666346330633734373137366366336265663361613337366236
35356239373361666337663661333834623039323639373131363638393435303161636336316639
35376231366162626536396130666631323337313034363066303737613764336232383235613764
66356530333733363030396633626438326134356535653538363561643837303462653732376462
64663034653135386364643434653162343338343437323062396565643466643264653165393064
32333561303035626463363461303866316465323966636166376432616532353438656633346363
62656464303165646463336636386630333561373537386330663531616466643164623865393233
66356337633238316235636632626234313938386338363164613231336434396566666666616538
32396235383930306362343466656535393036303931663063626465373831636134346237346530
64396464323538333433636461303231306538373861393932636336313061383032323662633432
39376265353734333339313266353964383830373665373234633236613830636432326636353933
65656238393438633862366363366665643364313534623833656634393035336634663837656661
33643338393330376464356232633638303732626336383936626662313430303338373438653865
62613765626332396636636433623364386135316265643163326534646138663930306363353737
33353537396135386637313132393365616638323330313966323461383666326664303231353734
34336663333865346538386663316638306239343832616231323730393363353933393365653830
31393933313963396236653234383564376264616332373230663961313638343933336261646435
35386437336130376139646563383137666466356361386366323735346130613866313330306631
62383566363832333633653564313936363564346166663931653831616634633135353565306464
64613863343766613764623461633335643137363065643864313337653665346230363331626434
30306235343661393336656434666637623930333038393865653865643836613235366562386232
39653336633034646233353633323135336639653062356233643131346666376664356262343938
32396335356532323231646330383734666435666164643731323634326134393732316131353836
65633631326133663633376361373631653739613633313161313935323066643530356337613835
64316431653437653163626234386164303465353731616530623863323937343565666339323639
31343562373433303535626465333936373433323834363965323732336535333565616231316235
39663431356633326466393862383133313030656431333839396333326461323130366533306139
31316338323333356334623332663166323035373864313739363335356162633937613164373637
62643538323066363734353136323537613263306138613761643865383062343934313666316530
65666166303263643163633666323861633765626438343739613164386333316335323963326334
31663433653534383866666639353036616565363230626136626330303061623936363531333139
65376333616331316637633461623836663965633462383830633165376631356631396564323330
66346561613133353438653365333361643166393535393466373330316136376263643163666139
64656233326333656438613235303937653363323761636666373633623938656134366262323931
35323133373163393964323962346433366434623636383133323535363632363465663862306439
33633564643030306638343430313831376333613363643839303330343338393964623038343165
39346233303864393537316531396333356363373565626530633237653337393434653034633263
32386431613462363430623761333961393834353664626238653063336536653531626266613463
30623438313430663165303064336532613637613566623864643730633232353538336131666566
366331336161363266613532653336343131

View File

@@ -1,10 +1,11 @@
services:
{% for service in services %}
{% if inventory_hostname in service.vm %}
{{ service.name }}:
container_name: {{ service.container_name }}
image: {{ service.image }}
restart: {{ service.restart }}
restart: unless-stopped
{% if service.network_mode is not defined %}
hostname: {{ service.name }}
networks:
@@ -62,34 +63,37 @@ services:
- {{ command }}
{% endfor %}
{% endif %}
{% if service.name == 'paperless' %}
{{ service.name }}-broker:
container_name: {{ service.name }}-broker
image: docker.io/library/redis:7
restart: unless-stopped
networks:
- net
volumes:
- /opt/local/paperless/redis/data:/data
{% if service.sub_service is defined and service.sub_service is iterable %}
{% for sub in service.sub_service %}
{% if sub.name is defined and sub.name == "postgres" %}
{{ service.name }}-postgres:
container_name: {{ service.name }}-postgres
image: docker.io/library/postgres:15
image: docker.io/library/postgres:{{ sub.version }}
restart: unless-stopped
hostname: {{ service.name }}-postgres
networks:
- net
volumes:
- /opt/local/paperless/db/data:/var/lib/postgresql/data
- /opt/local/{{ service.name }}/postgres/data:/var/lib/postgresql/data
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: {{ vault.docker.paperless.dbpass }}
POSTGRES_DB: {{ service.name }}
POSTGRES_USER: {{ sub.username }}
POSTGRES_PASSWORD: {{ sub.password }}
{% endif %}
{% if service.name == 'karakeep' %}
{% if sub.name is defined and sub.name == "redis" %}
{{ service.name }}-redis:
container_name: {{ service.name }}-redis
image: docker.io/library/redis:{{ sub.version }}
restart: unless-stopped
hostname: {{ service.name }}-redis
networks:
- net
volumes:
- /opt/local/{{ service.name }}/redis/data:/data
{% endif %}
{% if sub.name is defined and sub.name == "chrome" %}
{{ service.name }}-chrome:
image: gcr.io/zenika-hub/alpine-chrome:123
image: gcr.io/zenika-hub/alpine-chrome:{{ sub.version }}
container_name: {{ service.name }}-chrome
restart: unless-stopped
networks:
@@ -101,22 +105,25 @@ services:
- --remote-debugging-address=0.0.0.0
- --remote-debugging-port=9222
- --hide-scrollbars
{% endif %}
{% if sub.name is defined and sub.name == "meilisearch" %}
{{ service.name }}-meilisearch:
image: getmeili/meilisearch:v1.11.1
container_name: {{ service.name }}-meilisearch
image: getmeili/meilisearch:{{ sub.version }}
restart: unless-stopped
hostname: {{ service.name }}-meilisearch
networks:
- net
volumes:
- /opt/local/{{ service.name }}/mailisearch/data:/meili_data
environment:
- MEILI_NO_ANALYTICS=true
- NEXTAUTH_SECRET={{ vault.docker.karakeep.nextauth_secret }}
- MEILI_MASTER_KEY={{ vault.docker.karakeep.meili_master_key }}
- OPENAI_API_KEY="{{ vault.docker.karakeep.openai_key }}"
volumes:
- /opt/local/karakeep/meili/data:/meili_data
- NEXTAUTH_SECRET={{ sub.nextauth_secret }}
- MEILI_MASTER_KEY={{ sub.meili_master_key }}
- OPENAI_API_KEY="{{ sub.openai_key }}"
{% endif %}
{% endfor %}
{% endif %}
{% endif %}
{% endfor %}
networks:
@@ -126,6 +133,3 @@ networks:
driver: default
config:
- subnet: 172.16.69.0/24
volumes:
prometheus_data: {}

View File

@@ -5,7 +5,8 @@
"displayNameHtml": "<div class=\"kc-logo-text\">{{keycloak.display_name}}</div>",
"bruteForceProtected": true,
"users": [
{%- for user in keycloak.users %}
{% if keycloak.users is defined and keycloak.users is iterable %}
{% for user in keycloak.users %}
{
"username": "{{ user.username }}",
"enabled": true,
@@ -17,19 +18,20 @@
}
],
"realmRoles": [
{%- for realm_role in user.realm_roles %}
"{{ realm_role }}"{%- if not loop.last %},{%- endif %}
{% for realm_role in user.realm_roles %}
"{{ realm_role }}"{%- if not loop.last %},{% endif %}{{''}}
{% endfor %}
],
"clientRoles": {
"account": [
{%- for account in user.client_roles.account %}
"{{ account }}"{%- if not loop.last %},{%- endif %}
{% for account in user.client_roles.account %}
"{{ account }}"{%- if not loop.last %},{% endif %}{{''}}
{% endfor %}
]
}
},
},{% if not loop.last %}{% endif %}
{% endfor %}
{% endif %}
{
"username": "{{ keycloak.admin.username }}",
"enabled": true,
@@ -41,19 +43,19 @@
}
],
"realmRoles": [
{%- for realm_role in keycloak.admin.realm_roles %}
"{{ realm_role }}"{% if not loop.last %},{% endif %}
{% for realm_role in keycloak.admin.realm_roles %}
"{{ realm_role }}"{% if not loop.last %},{% endif %}{{''}}
{% endfor %}
],
"clientRoles": {
"realm-management": [
{%- for realm_management in keycloak.admin.client_roles.realm_management %}
"{{ realm_management }}"{%- if not loop.last %},{%- endif %}
{% for realm_management in keycloak.admin.client_roles.realm_management %}
"{{ realm_management }}"{%- if not loop.last %},{% endif %}{{''}}
{% endfor %}
],
"account": [
{%- for account in keycloak.admin.client_roles.account %}
"{{ account }}"{%- if not loop.last %},{%- endif %}
{% for account in keycloak.admin.client_roles.account %}
"{{ account }}"{%- if not loop.last %},{% endif %}{{''}}
{% endfor %}
]
}
@@ -61,7 +63,7 @@
],
"roles": {
"realm": [
{%- for role in keycloak.roles.realm %}
{% for role in keycloak.roles.realm %}
{
"name": "{{ role.name }}",
"description": "{{ role.name }}"
@@ -70,8 +72,8 @@
]
},
"defaultRoles": [
{%- for role in keycloak.roles.default_roles %}
"{{ role }}"{% if not loop.last %},{% endif %}
{% for role in keycloak.roles.default_roles %}
"{{ role }}"{% if not loop.last %},{% endif %}{{''}}
{% endfor %}
]
}