From a2a58f6343bf3faac8e6e0d9231ca24c731b83bb Mon Sep 17 00:00:00 2001 From: Tuan-Dat Tran Date: Fri, 25 Apr 2025 23:36:44 +0200 Subject: [PATCH] feat(keycloak|docker): improved templating Signed-off-by: Tuan-Dat Tran --- group_vars/docker/docker.yml | 57 +++++----- group_vars/docker/keycloak.yml | 12 +- group_vars/docker/secrets.yml | 105 +++++++++--------- roles/docker_host/templates/compose.yaml.j2 | 66 +++++------ .../templates/keycloak/realm.json.j2 | 48 ++++---- 5 files changed, 157 insertions(+), 131 deletions(-) diff --git a/group_vars/docker/docker.yml b/group_vars/docker/docker.yml index 1fe0fed..61df020 100644 --- a/group_vars/docker/docker.yml +++ b/group_vars/docker/docker.yml @@ -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 }}" diff --git a/group_vars/docker/keycloak.yml b/group_vars/docker/keycloak.yml index 4909ae8..d1c0205 100644 --- a/group_vars/docker/keycloak.yml +++ b/group_vars/docker/keycloak.yml @@ -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: [] diff --git a/group_vars/docker/secrets.yml b/group_vars/docker/secrets.yml index 1d1db0d..e423c00 100644 --- a/group_vars/docker/secrets.yml +++ b/group_vars/docker/secrets.yml @@ -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 diff --git a/roles/docker_host/templates/compose.yaml.j2 b/roles/docker_host/templates/compose.yaml.j2 index e177237..9648015 100644 --- a/roles/docker_host/templates/compose.yaml.j2 +++ b/roles/docker_host/templates/compose.yaml.j2 @@ -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: {} diff --git a/roles/docker_host/templates/keycloak/realm.json.j2 b/roles/docker_host/templates/keycloak/realm.json.j2 index e77073d..579c9b0 100644 --- a/roles/docker_host/templates/keycloak/realm.json.j2 +++ b/roles/docker_host/templates/keycloak/realm.json.j2 @@ -5,7 +5,8 @@ "displayNameHtml": "
{{keycloak.display_name}}
", "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 %} - {% endfor %} +{% 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 %} - {% endfor %} +{% for account in user.client_roles.account %} + "{{ account }}"{%- if not loop.last %},{% endif %}{{''}} +{% endfor %} ] } - }, - {% endfor %} + },{% if not loop.last %}{% endif %} +{% endfor %} +{% endif %} { "username": "{{ keycloak.admin.username }}", "enabled": true, @@ -41,37 +43,37 @@ } ], "realmRoles": [ - {%- for realm_role in keycloak.admin.realm_roles %} - "{{ realm_role }}"{% if not loop.last %},{% endif %} - {% endfor %} +{% 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 %} - {% endfor %} +{% 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 %} - {% endfor %} +{% for account in keycloak.admin.client_roles.account %} + "{{ account }}"{%- if not loop.last %},{% endif %}{{''}} +{% endfor %} ] } } ], "roles": { "realm": [ - {%- for role in keycloak.roles.realm %} +{% for role in keycloak.roles.realm %} { "name": "{{ role.name }}", "description": "{{ role.name }}" }{% if not loop.last %},{% endif %} - {% endfor %} +{% endfor %} ] }, "defaultRoles": [ - {%- for role in keycloak.roles.default_roles %} - "{{ role }}"{% if not loop.last %},{% endif %} - {% endfor %} +{% for role in keycloak.roles.default_roles %} + "{{ role }}"{% if not loop.last %},{% endif %}{{''}} +{% endfor %} ] }