diff --git a/.gitea/workflows/pr-cloudflare-docker-deploy.yml b/.gitea/workflows/pr-cloudflare-docker-deploy.yml index d806d597..49ac2ac2 100644 --- a/.gitea/workflows/pr-cloudflare-docker-deploy.yml +++ b/.gitea/workflows/pr-cloudflare-docker-deploy.yml @@ -25,6 +25,13 @@ jobs: uri: 'https://gitea.com/gitea/tea/releases/download/v0.9.2/tea-0.9.2-linux-amd64' name: 'tea' version: '0.9.2' + - name: Gotify Notification + uses: eikendev/gotify-action@master + with: + gotify_api_base: '${{ secrets.RINOA_GOTIFY_URL }}' + gotify_app_token: '${{ secrets.RINOA_RUNNER_GOTIFY_TOKEN }}' + notification_title: 'GITEA: PR Check' + notification_message: 'Checking for existing PR... 🔍' - name: Check if open PR exists id: check-opened-pr-step continue-on-error: true @@ -39,6 +46,13 @@ jobs: pr_index_old=$(tea pr ls --repo ${{ github.repository }} --state all --fields index,title,head --output csv | sed -e 's|"||g' | egrep '^[0-9]' | head -1 | awk -F"," '{print $1}') pr_index_new=$(expr ${pr_index_old} + 1) tea pr c -r ${{ github.repository }} -t "Automated PR for ${{ github.ref_name }} - #${pr_index_new}" -d "Automatically created PR for branch: ${{ github.ref_name }}" -a ${{ github.actor }} -L "Docker Compose, Ansible Configs.j2" + - name: Gotify Notification + uses: eikendev/gotify-action@master + with: + gotify_api_base: '${{ secrets.RINOA_GOTIFY_URL }}' + gotify_app_token: '${{ secrets.RINOA_RUNNER_GOTIFY_TOKEN }}' + notification_title: 'GITEA: PR Check' + notification_message: 'PR Created 🎟️' docker-compose-ansible-lints: name: Docker Compose & Ansible Lints needs: [check-and-create-pr] @@ -65,6 +79,13 @@ jobs: uses: cpanato/vault-installer@main - name: Install hvac run: pip install hvac + - name: Gotify Notification + uses: eikendev/gotify-action@master + with: + gotify_api_base: '${{ secrets.RINOA_GOTIFY_URL }}' + gotify_app_token: '${{ secrets.RINOA_RUNNER_GOTIFY_TOKEN }}' + notification_title: 'GITEA: Ansible Config Dry Run @ Rinoa' + notification_message: 'Starting Ansible dry run...' - name: Ansible Playbook Dry Run uses: dawidd6/action-ansible-playbook@v2 with: @@ -82,7 +103,7 @@ jobs: gotify_api_base: '${{ secrets.RINOA_GOTIFY_URL }}' gotify_app_token: '${{ secrets.RINOA_RUNNER_GOTIFY_TOKEN }}' notification_title: 'GITEA: Ansible Config Dry Run @ Rinoa' - notification_message: 'Ansible dry run completed successfully.' + notification_message: 'Ansible dry run completed successfully; starting Docker Compose' - name: Generate .env file for Docker Compose Dry Run run: | vault kv get -format=json rinoa-docker/env | jq -r '.data.data' | jq -r 'keys[] as $k | "\($k)='\''\(.[$k])'\''"' > .env @@ -149,7 +170,7 @@ jobs: gotify_api_base: '${{ secrets.RINOA_GOTIFY_URL }}' gotify_app_token: '${{ secrets.RINOA_RUNNER_GOTIFY_TOKEN }}' notification_title: 'GITEA: Cloudflare Setup @ Rinoa' - notification_message: 'Starting Cloudflare setup' + notification_message: 'Starting Cloudflare DNS setup...' - name: Compare Subdomains id: compare-subdomains uses: LouisBrunner/diff-action@v2.2.0 @@ -203,6 +224,13 @@ jobs: # modified_services=${egrep '^ [a-z]' changes.yml | sed -e 's|^ ||g' -e 's|:||g' | sed ':a;N;$!ba;s/\n/ /g'} # echo "Modified services: $modified_services" # echo "modified_services=$modified_services" >> $GITHUB_OUTPUT + - name: Gotify Notification + uses: eikendev/gotify-action@master + with: + gotify_api_base: '${{ secrets.RINOA_GOTIFY_URL }}' + gotify_app_token: '${{ secrets.RINOA_RUNNER_GOTIFY_TOKEN }}' + notification_title: 'GITEA: README Update' + notification_message: 'Updating README...' - name: Generate service list run: | yq '.services | to_entries | map({"service": .key, "image": .value.image})' docker-compose.yml > services.yml @@ -222,6 +250,13 @@ jobs: with: message: "chore: Update README" add: "README.md" + - name: Gotify Notification + uses: eikendev/gotify-action@master + with: + gotify_api_base: '${{ secrets.RINOA_GOTIFY_URL }}' + gotify_app_token: '${{ secrets.RINOA_RUNNER_GOTIFY_TOKEN }}' + notification_title: 'GITEA: README Update' + notification_message: 'README updated' pr-merge: name: PR Merge needs: [regenerate-readme-modified-services] @@ -278,6 +313,13 @@ jobs: uses: cpanato/vault-installer@main - name: Install hvac run: pip install hvac + - name: Gotify Notification + uses: eikendev/gotify-action@master + with: + gotify_api_base: '${{ secrets.RINOA_GOTIFY_URL }}' + gotify_app_token: '${{ secrets.RINOA_RUNNER_GOTIFY_TOKEN }}' + notification_title: 'GITEA: Ansible Config Deployment @ Rinoa' + notification_message: 'Starting config deployment with Ansible.' - name: Deploy Docker Configs via Ansible uses: dawidd6/action-ansible-playbook@v2 with: @@ -295,6 +337,13 @@ jobs: gotify_app_token: '${{ secrets.RINOA_RUNNER_GOTIFY_TOKEN }}' notification_title: 'GITEA: Ansible Config Deployment @ Rinoa' notification_message: 'Deployment completed successfully.' + - name: Gotify Notification + uses: eikendev/gotify-action@master + with: + gotify_api_base: '${{ secrets.RINOA_GOTIFY_URL }}' + gotify_app_token: '${{ secrets.RINOA_RUNNER_GOTIFY_TOKEN }}' + notification_title: 'GITEA: Docker Compose Deployment @ Rinoa' + notification_message: 'Starting Docker Compose run...' - name: Generate .env file for deployment run: | vault kv get -format=json rinoa-docker/env | jq -r '.data.data' | jq -r 'keys[] as $k | "\($k)='\''\(.[$k])'\''"' > .env diff --git a/.gitignore b/.gitignore index 0e64181a..21336815 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ **/.cache_ggshield ansible/collections/ansible_collections/ -**/.env \ No newline at end of file +**/.env +**/netbird_openid-configuration.json.j2 \ No newline at end of file diff --git a/README.md b/README.md index 46ab2bef..da1184d9 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,11 @@ | n8n | docker.n8n.io/n8nio/n8n | | navidrome | deluan/navidrome:latest | | netalertx | jokobsk/netalertx:latest | +| netbird-dashboard | netbirdio/dashboard:latest | +| netbird-signal | netbirdio/signal:latest | +| netbird-relay | netbirdio/relay:latest | +| netbird-management | netbirdio/management:latest | +| netbird-coturn | coturn/coturn:latest | | nextcloud | nextcloud/all-in-one:latest | | ollama | ollama/ollama | | ombi | lscr.io/linuxserver/ombi:latest | diff --git a/ansible/app-configs/authelia_configuration.yml.j2 b/ansible/app-configs/authelia_configuration.yml.j2 index 1628d560..1c7126da 100644 --- a/ansible/app-configs/authelia_configuration.yml.j2 +++ b/ansible/app-configs/authelia_configuration.yml.j2 @@ -1,3 +1,7 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +# yaml-language-server: $schema=https://www.authelia.com/schemas/latest/json-schema/configuration.json --- theme: auto default_2fa_method: "totp" @@ -59,11 +63,11 @@ authentication_backend: mail: mail display_name: displayName user: uid=authelia,ou=people,dc=trez,dc=wtf - password: '{{ env AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD }}' + password: '{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['AUTHELIA_AUTH_BIND_LDAP_PASSWORD'] }}' refresh_interval: 5m identity_validation: reset_password: - jwt_secret: '{{ env AUTHELIA_JWT_SECRET }}' + jwt_secret: '{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['AUTHELIA_JWT_SECRET'] }}' password_policy: standard: enabled: true @@ -99,7 +103,7 @@ access_control: - ['user:the.trezured.one'] session: name: authelia_session - secret: '{{ env AUTHELIA_SESSION_SECRET }}' + secret: '{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['AUTHELIA_SESSION_SECRET'] }}' expiration: 1h inactivity: 5m remember_me: 1M @@ -110,12 +114,12 @@ session: host: redis port: 6379 storage: - encryption_key: '{{ env AUTHELIA_STORAGE_ENCRYPTION_KEY }}' + encryption_key: '{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['AUTHELIA_STORAGE_ENCRYPTION_KEY'] }}' postgres: address: 'tcp://authelia-pg:5432' database: authelia username: authelia - password: '{{ env AUTHELIA_STORAGE_POSTGRES_PASSWORD }}' + password: '{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['AUTHELIA_STORAGE_POSTGRES_PASSWORD'] }}' timeout: '5s' regulation: max_retries: 3 @@ -126,12 +130,45 @@ notifier: smtp: address: 'smtp://postal-smtp:25' timeout: '5s' - username: '{{ env AUTHELIA_NOTIFIER_SMTP_USERNAME }}' - password: '{{ env AUTHELIA_NOTIFIER_SMTP_PASSWORD }}' + username: '{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['POSTAL_SMTP_AUTH_USER'] }}' + password: '{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['POSTAL_SMTP_AUTH_PASSWORD'] }}' sender: "Authelia " identifier: 'localhost' subject: "[Authelia] {title}" startup_check_address: 'test@authelia.com' disable_require_tls: true disable_starttls: true - disable_html_emails: false \ No newline at end of file + disable_html_emails: false +identity_providers: + oidc: + hmac_secret: '{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['AUTHELIA_OIDC_HMAC_SECRET'] }}' + jwks: + key_id: 'netbird' + key: | + {{ lookup("community.hashi_vault.vault_kv2_get", "env", engine_mount_point="rinoa-docker", url=vault_addr, token=vault_token_cleaned)["secret"]["AUTHELIA_OIDC_JWKS_KEY"] | replace("\\n", "\n") | indent(8) }} + certificate_chain: | + {{ lookup("community.hashi_vault.vault_kv2_get", "env", engine_mount_point="rinoa-docker", url=vault_addr, token=vault_token_cleaned)["secret"]["AUTHELIA_OIDC_JWKS_CERT_CHAIN"] | replace("\\n", "\n") | indent(8) }} + cors: + allowed_origins_from_client_redirect_uris: true + endpoints: + - 'userinfo' + - 'authorization' + - 'token' + - 'revocation' + - 'introspection' + clients: + - client_id: 'netbird' + client_name: 'NetBird' + client_secret: '{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['AUTHELIA_NETBIRD_CLIENT_SECRET'] }}' + public: false + authorization_policy: 'two_factor' + redirect_uris: + - 'https://vpn.trez.wtf/peers' + - 'https://vpn.trez.wtf/add-peers' + - 'http://localhost' + scopes: + - 'openid' + - 'email' + - 'profile' + userinfo_signed_response_alg: 'none' + token_endpoint_auth_method: 'client_secret_post' \ No newline at end of file diff --git a/ansible/app-configs/multi-scrobbler_config.json.j2 b/ansible/app-configs/multi-scrobbler_config.json.j2 index b55e634a..d4013c6e 100644 --- a/ansible/app-configs/multi-scrobbler_config.json.j2 +++ b/ansible/app-configs/multi-scrobbler_config.json.j2 @@ -2,62 +2,102 @@ {% set secrets_path = 'rinoa-docker/env' %} { - "sourceDefaults": { - "maxPollRetries": 0, // optional, default # of automatic polling restarts on error. can be overridden by property in individual config - "maxRequestRetries": 1, // optional, default # of http request retries a source can make before error is thrown. can be overridden by property in individual config - "retryMultiplier": 1.5 // optional, default retry delay multiplier (retry attempt * multiplier = # of seconds to wait before retrying). can be overridden by property in individual config + "debugMode": false, + "disableWeb": false, + "sourceDefaults": { + "logPayload": false, + "logFilterFailure": "warn", + "logPlayerState": false, + "scrobbleThresholds": { + "duration": 30, + "percent": 20 }, - "clientDefaults": { - "maxRequestRetries": 1, // optional, default # of http request retries a client can make before error is thrown. can be overridden by property in individual config - "retryMultiplier": 1.5 // optional, default retry delay multiplier (retry attempt * multiplier = # of seconds to wait before retrying). can be overridden by property in individual config + "maxPollRetries": 1, + "maxRequestRetries": 1, + "retryMultiplier": 1.5 + }, + "clientDefaults": { + "maxRequestRetries": 1, + "retryMultiplier": 1.5 + }, + "sources": [ + { + "type": "spotify", + "enable": true, + "clients": [], + "name": "Spotify", + "data": { + "clientId": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['YOUR_SPOTIFY_ID'] }}", + "clientSecret": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['YOUR_SPOTIFY_SECRET'] }}", + "redirectUri": "http://localhost:9078/callback" + } }, - "clients": [ - { - "name": "Last.fm Client", - "enable": true, - "configureAs": "client", - "data": { - "apiKey": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['LASTFM_API_KEY'] }}", - "secret": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['LASTFM_API_SECRET'] }}", - "redirectUri": "http://localhost:9078/lastfm/callback" - } - }, - { - "name": "Last.fm Source", - "enable": true, - "configureAs": "source", - "data": { - "apiKey": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['LASTFM_API_KEY'] }}", - "secret": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['LASTFM_API_SECRET'] }}", - "redirectUri": "http://localhost:9078/lastfm/callback" - } - }, - { - "name": "Maloja", - "enable": true, - "data": { - "url": "http://maloja:42010", - "apiKey": "myMalojaKey" - } - }, - { - "name": "ListenBrainz Client", - "enable": true, - "configureAs": "client", - "data": { - "token": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MALOJA_LISTENBRAINZ_TOKEN'] }}", - "username": "Trez.One" - } - }, - { - "name": "ListenBrainz Source", - "enable": true, - "configureAs": "source", - "data": { - "token": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MALOJA_LISTENBRAINZ_TOKEN'] }}", - "username": "Trez.One" - } - } - ] - } + { + "name": "Last.fm", + "enable": true, + "data": { + "apiKey": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['LASTFM_API_KEY'] }}", + "secret": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['LASTFM_API_SECRET'] }}", + "redirectUri": "http://localhost:9078/lastfm/callback" + } + }, + { + "name": "ListenBrainz", + "enable": true, + "data": { + "token": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MALOJA_LISTENBRAINZ_TOKEN'] }}", + "username": "Trez.One" + } + }, + { + "name": "Navidrome", + "enable": true, + "data": { + "url": "http://navidrome:4533", + "user": "admin", + "password": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['NAVIDROME_PASSWORD'] }}" + } + } + ], + "clients": [ + { + "name": "Last.fm Client", + "enable": true, + "data": { + "apiKey": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['LASTFM_API_KEY'] }}", + "secret": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['LASTFM_API_SECRET'] }}", + "redirectUri": "http://localhost:9078/lastfm/callback" + } + }, + { + "name": "ListenBrainz Client", + "enable": true, + "data": { + "token": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MALOJA_LISTENBRAINZ_TOKEN'] }}", + "username": "Trez.One" + } + }, + { + "type": "maloja", + "enable": true, + "name": "Maloja", + "data": { + "url": "http://maloja:42010", + "apiKey": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MALOJA_API_KEY'] }}" + } + } + ], + "webhooks": [ + { + "name": "Gotify", + "type": "gotify", + "url": "http://gotify:8070", + "token": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MULTI_SCROBBLER_GOTIFY_TOKEN'] }}", + "priorities": { + "info": 5, + "warn": 7, + "error": 10 + } + } + ] } \ No newline at end of file diff --git a/ansible/app-configs/netbird_management.json.j2 b/ansible/app-configs/netbird_management.json.j2 index 3004c918..80d2bb29 100644 --- a/ansible/app-configs/netbird_management.json.j2 +++ b/ansible/app-configs/netbird_management.json.j2 @@ -47,60 +47,30 @@ }, "HttpConfig": { "Address": "0.0.0.0:33073", - "AuthIssuer": "https://id.{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MY_TLD'] }}", - "AuthAudience": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['NETBIRD_ZITADEL_CLIENT_ID'] }}", - "AuthKeysLocation": "https://id.{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MY_TLD'] }}/oauth/v2/keys", + "AuthIssuer": "https://auth.{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MY_TLD'] }}", + "AuthAudience": "netbird", + "AuthKeysLocation": "https://auth.{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MY_TLD'] }}/jwks.json", "AuthUserIDClaim": "", "CertFile": "", "CertKey": "", "IdpSignKeyRefreshEnabled": true, - "OIDCConfigEndpoint": "https://id.{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MY_TLD'] }}/.well-known/openid-configuration" - }, - "IdpManagerConfig": { - "ManagerType": "zitadel", - "ClientConfig": { - "Issuer": "https://id.{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MY_TLD'] }}", - "TokenEndpoint": "https://id.{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MY_TLD'] }}/oauth/v2/token", - "ClientID": "netbird", - "ClientSecret": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['NETBIRD_ZITADEL_CLIENT_SECRET'] }}", - "GrantType": "client_credentials" - }, - "ExtraConfig": { - "ManagementEndpoint": "https://id.{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MY_TLD'] }}/management/v1" - }, - "Auth0ClientCredentials": null, - "AzureClientCredentials": null, - "KeycloakClientCredentials": null, - "ZitadelClientCredentials": null - }, - "DeviceAuthorizationFlow": { - "Provider": "hosted", - "ProviderConfig": { - "Audience": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['NETBIRD_ZITADEL_CLIENT_ID'] }}", - "AuthorizationEndpoint": "", - "Domain": "", - "ClientID": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['NETBIRD_ZITADEL_CLIENT_ID'] }}", - "ClientSecret": "", - "TokenEndpoint": "https://id.{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MY_TLD'] }}/oauth/v2/token", - "DeviceAuthEndpoint": "https://id.{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MY_TLD'] }}/oauth/v2/device_authorization", - "Scope": "openid", - "UseIDToken": false, - "RedirectURLs": null - } + "OIDCConfigEndpoint": "https://auth.{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MY_TLD'] }}/.well-known/openid-configuration" }, + "IdpManagerConfig": {}, + "DeviceAuthorizationFlow": {}, "PKCEAuthorizationFlow": { "ProviderConfig": { - "Audience": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['NETBIRD_ZITADEL_CLIENT_ID'] }}", - "ClientID": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['NETBIRD_ZITADEL_CLIENT_ID'] }}", - "ClientSecret": "", + "Audience": "netbird", + "ClientID": "netbird", + "ClientSecret": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['AUTHELIA_NETBIRD_CLIENT_SECRET'] }}", "Domain": "", - "AuthorizationEndpoint": "https://id.{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MY_TLD'] }}/oauth/v2/authorize", - "TokenEndpoint": "https://id.{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MY_TLD'] }}/oauth/v2/token", + "AuthorizationEndpoint": "https://auth.{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MY_TLD'] }}/api/oidc/authorization", + "TokenEndpoint": "https://auth.{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MY_TLD'] }}/api/oidc/token", "Scope": "openid profile email offline_access api", "RedirectURLs": [ "http://localhost:53000" ], - "UseIDToken": false + "UseIDToken": true } } } diff --git a/docker-compose.yml b/docker-compose.yml index d62c07cd..47cace53 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -202,9 +202,10 @@ services: AUTHELIA_SESSION_SECRET: ${AUTHELIA_SESSION_SECRET} AUTHELIA_STORAGE_ENCRYPTION_KEY: ${AUTHELIA_STORAGE_ENCRYPTION_KEY} AUTHELIA_STORAGE_POSTGRES_PASSWORD: ${AUTHELIA_STORAGE_POSTGRES_PASSWORD} - # PGID: ${PGID} - # PUID: ${PUID} + PGID: ${PGID} + PUID: ${PUID} TZ: ${TZ} + X_AUTHELIA_CONFIG_FILTERS: template expose: - 9091 image: authelia/authelia:master @@ -1268,77 +1269,77 @@ services: restart: always volumes: - ${DOCKER_VOLUME_STORAGE}/backups/docker_volume_bkups:/archive - - authelia-pg-db:/data/authelia-pg-db:ro - - bitmagnet-pg-db:/data/bitmagnet-pg-db:ro - - bunkerweb-storage:/data/bunkerweb-storage:ro - - castopod-media:/data/castopod-media:ro - - crowdsec-config:/data/crowdsec-config:ro - - crowdsec-db:/data/crowdsec-db:ro - - dawarich_db_data:/data/dawarich_db_data:ro - - dawarich_shared:/data/dawarich_shared:ro - - dawarich_public:/data/dawarich_public:ro - - dawarich_watched:/data/dawarich_watched:ro - - dbgate-data:/data/dbgate-data:ro - - docker-volume-bkup-data:/data/docker-volume-bkup-data:ro - - fastenhealth-cache:/data/fastenhealth-cache:ro - - fastenhealth-db:/data/fastenhealth-db:ro - - filebeat_etc:/data/filebeat_etc:ro - - filebeat_var:/data/filebeat_var:ro - - gitea-pg-db:/data/gitea-pg-db:ro - - hortusfox_app_backup:/data/hortusfox_app_backup:ro - - hortusfox_app_images:/data/hortusfox_app_images:ro - - hortusfox_app_logs:/data/hortusfox_app_logs:ro - - hortusfox_app_migrate:/data/hortusfox_app_migrate:ro - - hortusfox_app_themes:/data/hortusfox_app_themes:ro - - hortusfox_db_data:/data/hortusfox_db_data:ro - - immich-model-cache:/data/immich-model-cache:ro - - influxdb2-data:/data/influxdb2-data:ro - - influxdb2-config:/data/influxdb2-config:ro - - invidious-postgres:/data/invidious-postgres:ro - - invoice-ninja_cache:/data/invoice-ninja_cache:ro - - invoice-ninja_public:/data/invoice-ninja_public:ro - - invoice-ninja_storage:/data/invoice-ninja_storage:ro - - jitsi-web-admin-theme:/data/jitsi-web-admin-theme:ro - - jitsi-web-admin-upload:/data/jitsi-web-admin-upload:ro - - joplin_data:/data/joplin_data:ro - - librechat-pg-data:/data/librechat-pg-data:ro - - libretranslate_models:/data/libretranslate_models:ro - - lldap_data:/data/lldap_data:ro - - mastodon-pg-db:/data/mastodon-pg-db:ro - - mixpost-storage:/data/mixpost-storage:ro - - mixpost-logs:/data/mixpost-logs:ro - - mongodb_config:/data/mongodb_config:ro - - mongodb_data:/data/mongodb_data:ro - - n8n-data:/data/n8n-data:ro - - netbird-mgmt:/data/netbird-mgmt:ro - - netbird-signal:/data/netbird-signal:ro - - netbird-letsencrypt:/data/netbird-letsencrypt:ro - - nextcloud_aio_mastercontainer:/data/nextcloud_aio_mastercontainer:ro - - ollama:/data/ollama:ro - - open-webui:/data/open-webui:ro - - paperless-ngx-data:/data/paperless-ngx-data:ro - - paperless-ngx-media:/data/paperless-ngx-media:ro - - paperless-ngx-pg:/data/paperless-ngx-pg:ro - - peppermint-pg-data:/data/peppermint-pg-data:ro - - pgbackweb-data:/data/pgbackweb-data:ro - - plausible-db-data:/data/plausible-db-data:ro - - plausible-event-data:/data/plausible-event-data:ro - - plausible-event-logs:/data/plausible-event-logs:ro - - portainer-data:/data/portainer-data:ro - - reactive-resume-pg:/data/reactive-resume-pg:ro - - semaphore_config:/data/semaphore_config:ro - - semaphore_data:/data/semaphore_data:ro - - semaphore_tmp:/data/semaphore_tmp:ro - - sonarqube-data:/data/sonarqube-data:ro - - sonarqube-db:/data/sonarqube-db:ro - - sonarqube-db-data:/data/sonarqube-db-data:ro - - sonarqube-extensions:/data/sonarqube-extensions:ro - - sonarqube-logs:/data/sonarqube-logs:ro - - sonarqube-temp:/data/sonarqube-temp:ro - - tandoor-pg:/data/tandoor-pg:ro - - unmanic-cache:/data/unmanic-cache:ro - - wallos-db:/data/wallos-db:ro - - wallos-logos:/data/wallos-logos:ro + - authelia-pg-db:/backup/authelia-pg-db:ro + - bitmagnet-pg-db:/backup/bitmagnet-pg-db:ro + - bunkerweb-storage:/backup/bunkerweb-storage:ro + - castopod-media:/backup/castopod-media:ro + - crowdsec-config:/backup/crowdsec-config:ro + - crowdsec-db:/backup/crowdsec-db:ro + - dawarich_db_data:/backup/dawarich_db_data:ro + - dawarich_shared:/backup/dawarich_shared:ro + - dawarich_public:/backup/dawarich_public:ro + - dawarich_watched:/backup/dawarich_watched:ro + - dbgate-data:/backup/dbgate-data:ro + - docker-volume-bkup-data:/backup/docker-volume-bkup-data:ro + - fastenhealth-cache:/backup/fastenhealth-cache:ro + - fastenhealth-db:/backup/fastenhealth-db:ro + - filebeat_etc:/backup/filebeat_etc:ro + - filebeat_var:/backup/filebeat_var:ro + - gitea-pg-db:/backup/gitea-pg-db:ro + - hortusfox_app_backup:/backup/hortusfox_app_backup:ro + - hortusfox_app_images:/backup/hortusfox_app_images:ro + - hortusfox_app_logs:/backup/hortusfox_app_logs:ro + - hortusfox_app_migrate:/backup/hortusfox_app_migrate:ro + - hortusfox_app_themes:/backup/hortusfox_app_themes:ro + - hortusfox_db_data:/backup/hortusfox_db_data:ro + - immich-model-cache:/backup/immich-model-cache:ro + - influxdb2-data:/backup/influxdb2-data:ro + - influxdb2-config:/backup/influxdb2-config:ro + - invidious-postgres:/backup/invidious-postgres:ro + - invoice-ninja_cache:/backup/invoice-ninja_cache:ro + - invoice-ninja_public:/backup/invoice-ninja_public:ro + - invoice-ninja_storage:/backup/invoice-ninja_storage:ro + - jitsi-web-admin-theme:/backup/jitsi-web-admin-theme:ro + - jitsi-web-admin-upload:/backup/jitsi-web-admin-upload:ro + - joplin_data:/backup/joplin_data:ro + - librechat-pg-data:/backup/librechat-pg-data:ro + - libretranslate_models:/backup/libretranslate_models:ro + - lldap_data:/backup/lldap_data:ro + - mastodon-pg-db:/backup/mastodon-pg-db:ro + - mixpost-storage:/backup/mixpost-storage:ro + - mixpost-logs:/backup/mixpost-logs:ro + - mongodb_config:/backup/mongodb_config:ro + - mongodb_data:/backup/mongodb_data:ro + - n8n-data:/backup/n8n-data:ro + - netbird-mgmt:/backup/netbird-mgmt:ro + - netbird-signal:/backup/netbird-signal:ro + - netbird-letsencrypt:/backup/netbird-letsencrypt:ro + - nextcloud_aio_mastercontainer:/backup/nextcloud_aio_mastercontainer:ro + - ollama:/backup/ollama:ro + - open-webui:/backup/open-webui:ro + - paperless-ngx-data:/backup/paperless-ngx-data:ro + - paperless-ngx-media:/backup/paperless-ngx-media:ro + - paperless-ngx-pg:/backup/paperless-ngx-pg:ro + - peppermint-pg-data:/backup/peppermint-pg-data:ro + - pgbackweb-data:/backup/pgbackweb-data:ro + - plausible-db-data:/backup/plausible-db-data:ro + - plausible-event-data:/backup/plausible-event-data:ro + - plausible-event-logs:/backup/plausible-event-logs:ro + - portainer-data:/backup/portainer-data:ro + - reactive-resume-pg:/backup/reactive-resume-pg:ro + - semaphore_config:/backup/semaphore_config:ro + - semaphore_data:/backup/semaphore_data:ro + - semaphore_tmp:/backup/semaphore_tmp:ro + - sonarqube-data:/backup/sonarqube-data:ro + - sonarqube-db:/backup/sonarqube-db:ro + - sonarqube-db-data:/backup/sonarqube-db-data:ro + - sonarqube-extensions:/backup/sonarqube-extensions:ro + - sonarqube-logs:/backup/sonarqube-logs:ro + - sonarqube-temp:/backup/sonarqube-temp:ro + - tandoor-pg:/backup/tandoor-pg:ro + - unmanic-cache:/backup/unmanic-cache:ro + - wallos-db:/backup/wallos-db:ro + - wallos-logos:/backup/wallos-logos:ro docuseal: container_name: docuseal image: docuseal/docuseal:latest @@ -1790,8 +1791,12 @@ services: condition: service_started required: true immich-pg-db: - condition: service_started + condition: service_healthy required: true + immich-machine-learning: + condition: service_healthy + required: true + restart: true environment: DB_DATABASE_NAME: immich DB_HOSTNAME: immich-pg-db @@ -1835,10 +1840,6 @@ services: - /etc/localtime:/etc/localtime:ro immich-machine-learning: container_name: immich-machine-learning - depends_on: - immich-server: - condition: service_started - required: true healthcheck: disable: false image: ghcr.io/immich-app/immich-machine-learning:release @@ -3337,8 +3338,8 @@ services: homepage.widget.type: navidrome homepage.widget.url: http://navidrome:4533 homepage.widget.user: admin - homepage.widget.token: e8a9e97b29aa963fa4729c633289d232 - homepage.widget.salt: v5Z93Z + homepage.widget.token: ${NAVIDROME_HOMEPAGE_TOKEN} + homepage.widget.salt: ${NAVIDROME_HOMEPAGE_SALT} swag: enable swag_port: 4533 swag_proto: http @@ -3383,123 +3384,121 @@ services: target: /app/api # (API: OPTION 2) use when debugging issues # - ${DOCKER_VOLUME_CONFIG}/netalertx/api:/app/api - # netbird-dashboard: - # container_name: netbird-dashboard - # environment: - # # Endpoints - # NETBIRD_MGMT_API_ENDPOINT: https://netbird.${MY_TLD}:33073 - # NETBIRD_MGMT_GRPC_API_ENDPOINT: https://netbird.${MY_TLD}:33073 - # # OIDC - # AUTH_AUDIENCE: ${NETBIRD_ZITADEL_CLIENT_ID} - # AUTH_CLIENT_ID: ${NETBIRD_ZITADEL_CLIENT_ID} - # AUTH_CLIENT_SECRET: ${NETBIRD_ZITADEL_CLIENT_SECRET} - # AUTH_AUTHORITY: https://id.${MY_TLD} - # USE_AUTH0: false - # AUTH_SUPPORTED_SCOPES: openid profile email offline_access api - # AUTH_REDIRECT_URI: /auth - # AUTH_SILENT_REDIRECT_URI: /silent-auth - # NETBIRD_TOKEN_SOURCE: accessToken - # # SSL - # NGINX_SSL_PORT: 443 - # # Letsencrypt - # LETSENCRYPT_DOMAIN: - # LETSENCRYPT_EMAIL: - # image: netbirdio/dashboard:latest - # labels: - # homepage.group: Privacy/Security - # homepage.name: Netbird - # homepage.href: https://netbird.${MY_TLD} - # homepage.icon: netbird.svg - # homepage.description: Peer-to-peer private network and centralized access control system - # swag: enable - # swag_proto: http - # swag_port: 80 - # swag_auth: authelia - # swag_url: netbird.${MY_TLD} - # swag_server_custom_directive: | - # location /signalexchange.SignalExchange/ { - # grpc_pass grpc://netbird-signal:80; - # #grpc_ssl_verify off; - # grpc_read_timeout 1d; - # grpc_send_timeout 1d; - # grpc_socket_keepalive on; - # } - # # Proxy Management http endpoint - # location /api { - # proxy_pass http://netbird-management:443; - # } - # # Proxy Management grpc endpoint - # location /management.ManagementService/ { - # grpc_pass grpc://netbird-management:443; - # #grpc_ssl_verify off; - # grpc_read_timeout 1d; - # grpc_send_timeout 1d; - # grpc_socket_keepalive on; - # } - # swag.uptime-kuma.enabled: true - # swag.uptime-kuma.monitor.url: https://netbird.${MY_TLD} - # ports: - # - 32908:80 - # - 36610:443 - # restart: unless-stopped - # volumes: - # - netbird-letsencrypt:/etc/letsencrypt/ - # netbird-signal: - # container_name: netbird-signal - # image: netbirdio/signal:latest - # ports: - # - 10001:80 - # restart: unless-stopped - # volumes: - # - netbird-signal:/var/lib/netbird - # netbird-relay: - # container_name: netbird-relay - # image: netbirdio/relay:latest - # restart: unless-stopped - # environment: - # NB_LOG_LEVEL: info - # NB_LISTEN_ADDRESS: :33080 - # NB_EXPOSED_ADDRESS: netbird.${MY_TLD}:33080 - # # todo: change to a secure secret - # NB_AUTH_SECRET: ${NETBIRD_RELAY_AUTH_SECRET} - # ports: - # - 33080:33080 - # netbird-management: - # command: [ - # "--port", "443", - # "--log-file", "console", - # "--log-level", "info", - # "--disable-anonymous-metrics=false", - # "--single-account-mode-domain=netbird.${MY_TLD}", - # "--dns-domain=netbird.selfhosted" - # ] - # container_name: netbird-management - # depends_on: - # netbird-dashboard: - # condition: service_started - # environment: - # NETBIRD_STORE_ENGINE_POSTGRES_DSN: - # NETBIRD_STORE_ENGINE_MYSQL_DSN: - # image: netbirdio/management:latest - # restart: unless-stopped - # volumes: - # - netbird-mgmt:/var/lib/netbird - # - netbird-letsencrypt:/etc/letsencrypt:ro - # - ${DOCKER_VOLUME_CONFIG}/netbird/management.json:/etc/netbird/management.json - # ports: - # - 23833:443 #API port - # netbird-coturn: - # command: - # - -c /etc/turnserver.conf - # container_name: netbird-coturn - # image: coturn/coturn:latest - # restart: unless-stopped - # #domainname: netbird.${MY_TLD} # only needed when TLS is enabled - # volumes: - # - ${DOCKER_VOLUME_CONFIG}/netbird/turnserver.conf:/etc/turnserver.conf:ro - # - ${DOCKER_VOLUME_CONFIG}/netbird/privkey.pem:/etc/coturn/private/privkey.pem:ro - # - ${DOCKER_VOLUME_CONFIG}/netbird/cert.pem:/etc/coturn/certs/cert.pem:ro - # network_mode: host + netbird-dashboard: + container_name: netbird-dashboard + environment: + # Endpoints + NETBIRD_MGMT_API_ENDPOINT: https://vpn.${MY_TLD} + NETBIRD_MGMT_GRPC_API_ENDPOINT: https://vpn.${MY_TLD} + # OIDC + AUTH_AUDIENCE: none + AUTH_CLIENT_ID: netbird + AUTH_CLIENT_SECRET: ${AUTHELIA_NETBIRD_CLIENT_SECRET} + AUTH_AUTHORITY: https://auth.${MY_TLD} + USE_AUTH0: false + AUTH_SUPPORTED_SCOPES: openid profile email offline_access api + AUTH_REDIRECT_URI: /peers + AUTH_SILENT_REDIRECT_URI: /add-peers + NETBIRD_TOKEN_SOURCE: idToken + # SSL + NGINX_SSL_PORT: 443 + # Letsencrypt + LETSENCRYPT_DOMAIN: + LETSENCRYPT_EMAIL: + image: netbirdio/dashboard:latest + labels: + homepage.group: Privacy/Security + homepage.name: Netbird + homepage.href: https://vpn.${MY_TLD} + homepage.icon: netbird.svg + homepage.description: Peer-to-peer private network and centralized access control system + swag: enable + swag_proto: http + swag_port: 80 + swag_auth: authelia + swag_url: vpn.${MY_TLD} + swag_server_custom_directive: | + location /signalexchange.SignalExchange/ { + grpc_pass grpc://netbird-signal; + #grpc_ssl_verify off; + grpc_read_timeout 1d; + grpc_send_timeout 1d; + grpc_socket_keepalive on; + } + # Proxy Management http endpoint + location /api { + proxy_pass http://netbird-management; + } + # Proxy Management grpc endpoint + location /management.ManagementService/ { + grpc_pass grpc://netbird-management; + #grpc_ssl_verify off; + grpc_read_timeout 1d; + grpc_send_timeout 1d; + grpc_socket_keepalive on; + } + swag.uptime-kuma.enabled: true + swag.uptime-kuma.monitor.url: https://vpn.${MY_TLD} + ports: + - 32908:80 + - 36610:443 + restart: unless-stopped + volumes: + - netbird-letsencrypt:/etc/letsencrypt/ + netbird-signal: + container_name: netbird-signal + image: netbirdio/signal:latest + ports: + - 10001:80 + restart: unless-stopped + volumes: + - netbird-signal:/var/lib/netbird + netbird-relay: + image: netbirdio/relay:latest + restart: unless-stopped + environment: + NB_LOG_LEVEL: info + NB_LISTEN_ADDRESS: :33080 + NB_EXPOSED_ADDRESS: vpn.${MY_TLD}:33080 + # todo: change to a secure secret + NB_AUTH_SECRET: ${NETBIRD_RELAY_AUTH_SECRET} + ports: + - 33080:33080 + netbird-management: + command: [ + "--port", "443", + "--log-file", "console", + "--log-level", "info", + "--disable-anonymous-metrics=false", + "--single-account-mode-domain=vpn.${MY_TLD}", + "--dns-domain=vpn.trez.wtf" + ] + container_name: netbird-management + depends_on: + netbird-dashboard: + condition: service_started + environment: + NETBIRD_STORE_ENGINE_POSTGRES_DSN: + NETBIRD_STORE_ENGINE_MYSQL_DSN: + image: netbirdio/management:latest + restart: unless-stopped + volumes: + - netbird-mgmt:/var/lib/netbird + - netbird-letsencrypt:/etc/letsencrypt:ro + - ${DOCKER_VOLUME_CONFIG}/netbird/management.json:/etc/netbird/management.json + ports: + - 33073:443 #API port + netbird-coturn: + command: + - -c /etc/turnserver.conf + container_name: netbird-coturn + image: coturn/coturn:latest + restart: unless-stopped + #domainname: vpn.${MY_TLD} # only needed when TLS is enabled + volumes: + - ${DOCKER_VOLUME_CONFIG}/netbird/turnserver.conf:/etc/turnserver.conf:ro + # - ${DOCKER_VOLUME_CONFIG}/netbird/privkey.pem:/etc/coturn/private/privkey.pem:ro + # - ${DOCKER_VOLUME_CONFIG}/netbird/cert.pem:/etc/coturn/certs/cert.pem:ro nextcloud: container_name: nextcloud-aio-mastercontainer environment: @@ -4899,7 +4898,6 @@ services: swag: condition: service_started required: true - restart: true environment: PGID: ${PGID} PUID: ${PUID}