From cbdc8f35a5da116318c7f47f99c2b92a4a68475b Mon Sep 17 00:00:00 2001 From: "Trez.One" Date: Wed, 11 Jun 2025 20:17:16 -0400 Subject: [PATCH] Reorganizing configs. --- .../adguardhome/AdGuardHome.yaml.j2 | 199 ++ ansible/app-configs/apprise/apprise.yml.j2 | 6 + .../app-configs/authelia/configuration.yml.j2 | 172 ++ ansible/app-configs/cloudflared/config.yml.j2 | 16 + ansible/app-configs/crowdsec/acquis.yaml.j2 | 15 + ansible/app-configs/crowdsec/config.yaml.j2 | 49 + .../crowdsec/local-api-credentials.yaml.j2 | 6 + .../crowdsec/online-api-credentials.yaml.j2 | 6 + ansible/app-configs/crowdsec/profiles.yaml.j2 | 17 + .../ghost/ghost_config.production.json.j2 | 42 + .../gitea/act-runner/config.yaml.j2 | 101 + ansible/app-configs/gitea/app.ini.j2 | 125 + .../gitea/gitea-sonarqube-bot/config.yaml.j2 | 81 + .../grafana/alloy/alloy_config.alloy | 404 +++ .../grafana/alloy/alloy_endpoints.json.j2 | 34 + .../app-configs/grafana/beyla/beyla.yml.j2 | 7 + .../app-configs/grafana/mimir/mimir.yaml.j2 | 77 + .../grafana/pyroscope/config.yaml.j2 | 12 + .../app-configs/grafana/tempo/config.yml.j2 | 787 ++++++ .../app-configs/grafana/tempo/tempo.yaml.j2 | 54 + .../app-configs/homepage/bookmarks.yaml.j2 | 22 + ansible/app-configs/homepage/docker.yaml.j2 | 15 + .../app-configs/homepage/kubernetes.yaml.j2 | 6 + ansible/app-configs/homepage/services.yaml.j2 | 33 + ansible/app-configs/homepage/settings.yaml.j2 | 56 + ansible/app-configs/homepage/widgets.yaml.j2 | 33 + ansible/app-configs/invidious/config.yml.j2 | 952 +++++++ .../invoice-ninja/invoice-ninja.env.j2 | 52 + .../app-configs/librechat/librechat.env.j2 | 550 ++++ .../app-configs/librechat/librechat.yaml.j2 | 33 + ansible/app-configs/lidarr/config.xml.j2 | 21 + ansible/app-configs/lidify/config.json.j2 | 25 + ansible/app-configs/loggifly/config.yaml.j2 | 33 + ansible/app-configs/mirotalk/src/config.js.j2 | 159 ++ .../multi-scrobbler/config.json.j2 | 111 + .../app-configs/netbird/management.json.j2 | 76 + .../netbird/openid-configuration.json.j2 | 122 + .../app-configs/netbird/turnserver.conf.j2 | 725 ++++++ .../plausible/clickhouse-config.xml.j2 | 11 + ansible/app-configs/postal/postal.yml.j2 | 62 + ansible/app-configs/prowlarr/config.xml.j2 | 21 + ansible/app-configs/radarec/config.json.j2 | 20 + ansible/app-configs/radarr/config.xml.j2 | 21 + ansible/app-configs/readarr/config.xml.j2 | 21 + ansible/app-configs/romm/config.yml.j2 | 48 + ansible/app-configs/sabnzbdvpn/sabnzbd.ini.j2 | 482 ++++ .../scrutiny/config/config.yaml.j2 | 7 + ansible/app-configs/searxng/settings.yml.j2 | 2243 +++++++++++++++++ ansible/app-configs/searxng/uwsgi.ini.j2 | 49 + .../signoz/clickhouse/cluster.ha.xml.j2 | 75 + .../signoz/clickhouse/cluster.xml.j2 | 75 + .../signoz/clickhouse/config.xml.j2 | 1142 +++++++++ .../signoz/clickhouse/custom-function.xml.j2 | 21 + .../signoz/clickhouse/storage.xml.j2 | 41 + .../signoz/clickhouse/users.xml.j2 | 123 + .../signoz/otel/otel-collector-config.yaml.j2 | 103 + .../otel/otel-collector-opamp-config.yaml.j2 | 1 + ansible/app-configs/signoz/prometheus.yml.j2 | 25 + ansible/app-configs/sonarr/config.xml.j2 | 22 + ansible/app-configs/sonashow/config.json.j2 | 21 + ansible/app-configs/soularr/config.ini.j2 | 76 + ansible/app-configs/soulseek/slskd.yml.j2 | 212 ++ ansible/app-configs/sourcebot/config.json.j2 | 19 + ansible/app-configs/traccar/traccar.xml.j2 | 29 + ansible/app-configs/unmanic/settings.json.j2 | 29 + ansible/app-configs/vector/vector.yaml.j2 | 31 + ansible/app-configs/wazuh/certs.yml.j2 | 19 + .../app-configs/wazuh/wazuh.indexer.yml.j2 | 33 + ansible/app-configs/wazuh/wazuh.yml.j2 | 10 + ansible/app-configs/youtubedl/config.yml.j2 | 19 + ansible/app-configs/zitadel/config.yaml.j2 | 43 + .../app-configs/zitadel/init-steps.yaml.j2 | 13 + ansible/app-configs/zitadel/secrets.yaml.j2 | 13 + 73 files changed, 10414 insertions(+) create mode 100644 ansible/app-configs/adguardhome/AdGuardHome.yaml.j2 create mode 100644 ansible/app-configs/apprise/apprise.yml.j2 create mode 100644 ansible/app-configs/authelia/configuration.yml.j2 create mode 100644 ansible/app-configs/cloudflared/config.yml.j2 create mode 100644 ansible/app-configs/crowdsec/acquis.yaml.j2 create mode 100644 ansible/app-configs/crowdsec/config.yaml.j2 create mode 100644 ansible/app-configs/crowdsec/local-api-credentials.yaml.j2 create mode 100644 ansible/app-configs/crowdsec/online-api-credentials.yaml.j2 create mode 100644 ansible/app-configs/crowdsec/profiles.yaml.j2 create mode 100644 ansible/app-configs/ghost/ghost_config.production.json.j2 create mode 100644 ansible/app-configs/gitea/act-runner/config.yaml.j2 create mode 100644 ansible/app-configs/gitea/app.ini.j2 create mode 100644 ansible/app-configs/gitea/gitea-sonarqube-bot/config.yaml.j2 create mode 100644 ansible/app-configs/grafana/alloy/alloy_config.alloy create mode 100644 ansible/app-configs/grafana/alloy/alloy_endpoints.json.j2 create mode 100644 ansible/app-configs/grafana/beyla/beyla.yml.j2 create mode 100644 ansible/app-configs/grafana/mimir/mimir.yaml.j2 create mode 100644 ansible/app-configs/grafana/pyroscope/config.yaml.j2 create mode 100644 ansible/app-configs/grafana/tempo/config.yml.j2 create mode 100644 ansible/app-configs/grafana/tempo/tempo.yaml.j2 create mode 100644 ansible/app-configs/homepage/bookmarks.yaml.j2 create mode 100644 ansible/app-configs/homepage/docker.yaml.j2 create mode 100644 ansible/app-configs/homepage/kubernetes.yaml.j2 create mode 100644 ansible/app-configs/homepage/services.yaml.j2 create mode 100644 ansible/app-configs/homepage/settings.yaml.j2 create mode 100644 ansible/app-configs/homepage/widgets.yaml.j2 create mode 100644 ansible/app-configs/invidious/config.yml.j2 create mode 100644 ansible/app-configs/invoice-ninja/invoice-ninja.env.j2 create mode 100644 ansible/app-configs/librechat/librechat.env.j2 create mode 100644 ansible/app-configs/librechat/librechat.yaml.j2 create mode 100644 ansible/app-configs/lidarr/config.xml.j2 create mode 100644 ansible/app-configs/lidify/config.json.j2 create mode 100644 ansible/app-configs/loggifly/config.yaml.j2 create mode 100644 ansible/app-configs/mirotalk/src/config.js.j2 create mode 100644 ansible/app-configs/multi-scrobbler/config.json.j2 create mode 100644 ansible/app-configs/netbird/management.json.j2 create mode 100644 ansible/app-configs/netbird/openid-configuration.json.j2 create mode 100644 ansible/app-configs/netbird/turnserver.conf.j2 create mode 100644 ansible/app-configs/plausible/clickhouse-config.xml.j2 create mode 100644 ansible/app-configs/postal/postal.yml.j2 create mode 100644 ansible/app-configs/prowlarr/config.xml.j2 create mode 100644 ansible/app-configs/radarec/config.json.j2 create mode 100644 ansible/app-configs/radarr/config.xml.j2 create mode 100644 ansible/app-configs/readarr/config.xml.j2 create mode 100644 ansible/app-configs/romm/config.yml.j2 create mode 100644 ansible/app-configs/sabnzbdvpn/sabnzbd.ini.j2 create mode 100644 ansible/app-configs/scrutiny/config/config.yaml.j2 create mode 100644 ansible/app-configs/searxng/settings.yml.j2 create mode 100644 ansible/app-configs/searxng/uwsgi.ini.j2 create mode 100644 ansible/app-configs/signoz/clickhouse/cluster.ha.xml.j2 create mode 100644 ansible/app-configs/signoz/clickhouse/cluster.xml.j2 create mode 100644 ansible/app-configs/signoz/clickhouse/config.xml.j2 create mode 100644 ansible/app-configs/signoz/clickhouse/custom-function.xml.j2 create mode 100644 ansible/app-configs/signoz/clickhouse/storage.xml.j2 create mode 100644 ansible/app-configs/signoz/clickhouse/users.xml.j2 create mode 100644 ansible/app-configs/signoz/otel/otel-collector-config.yaml.j2 create mode 100644 ansible/app-configs/signoz/otel/otel-collector-opamp-config.yaml.j2 create mode 100644 ansible/app-configs/signoz/prometheus.yml.j2 create mode 100644 ansible/app-configs/sonarr/config.xml.j2 create mode 100644 ansible/app-configs/sonashow/config.json.j2 create mode 100644 ansible/app-configs/soularr/config.ini.j2 create mode 100644 ansible/app-configs/soulseek/slskd.yml.j2 create mode 100644 ansible/app-configs/sourcebot/config.json.j2 create mode 100644 ansible/app-configs/traccar/traccar.xml.j2 create mode 100644 ansible/app-configs/unmanic/settings.json.j2 create mode 100644 ansible/app-configs/vector/vector.yaml.j2 create mode 100644 ansible/app-configs/wazuh/certs.yml.j2 create mode 100644 ansible/app-configs/wazuh/wazuh.indexer.yml.j2 create mode 100644 ansible/app-configs/wazuh/wazuh.yml.j2 create mode 100644 ansible/app-configs/youtubedl/config.yml.j2 create mode 100644 ansible/app-configs/zitadel/config.yaml.j2 create mode 100644 ansible/app-configs/zitadel/init-steps.yaml.j2 create mode 100644 ansible/app-configs/zitadel/secrets.yaml.j2 diff --git a/ansible/app-configs/adguardhome/AdGuardHome.yaml.j2 b/ansible/app-configs/adguardhome/AdGuardHome.yaml.j2 new file mode 100644 index 00000000..8265074b --- /dev/null +++ b/ansible/app-configs/adguardhome/AdGuardHome.yaml.j2 @@ -0,0 +1,199 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +http: + pprof: + port: 6060 + enabled: false + address: 0.0.0.0:8008 + session_ttl: 720h +users: + - name: admin + password: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['ADGUARD_BCRYPT'] }} +auth_attempts: 5 +block_auth_min: 15 +http_proxy: "" +language: "" +theme: auto +dns: + bind_hosts: + - 0.0.0.0 + port: 53 + anonymize_client_ip: false + ratelimit: 20 + ratelimit_subnet_len_ipv4: 24 + ratelimit_subnet_len_ipv6: 56 + ratelimit_whitelist: [] + refuse_any: true + upstream_dns: + - 94.140.14.14 + - 94.140.15.15 + - https://dns.adguard-dns.com/dns-query + - tls://dns.adguard-dns.com + - quic://dns.adguard-dns.com + - 1.1.1.1 + - 1.0.0.1 + - 1.1.1.2 + - 1.0.0.2 + - 185.228.168.9 + - 185.228.169.9 + - 76.76.2.3 + - tls://getdnsapi.net + - 185.49.141.37 + - tls://dot.seby.io + upstream_dns_file: "" + bootstrap_dns: + - 9.9.9.10 + - 149.112.112.10 + - 2620:fe::10 + - 2620:fe::fe:10 + fallback_dns: [] + upstream_mode: load_balance + fastest_timeout: 1s + allowed_clients: [] + disallowed_clients: [] + blocked_hosts: + - version.bind + - id.server + - hostname.bind + trusted_proxies: + - 127.0.0.0/8 + - ::1/128 + cache_size: 4194304 + cache_ttl_min: 0 + cache_ttl_max: 0 + cache_optimistic: false + bogus_nxdomain: [] + aaaa_disabled: false + enable_dnssec: false + edns_client_subnet: + custom_ip: "" + enabled: false + use_custom: false + max_goroutines: 300 + handle_ddr: true + ipset: [] + ipset_file: "" + bootstrap_prefer_ipv6: false + upstream_timeout: 10s + private_networks: [] + use_private_ptr_resolvers: false + local_ptr_upstreams: [] + use_dns64: false + dns64_prefixes: [] + serve_http3: false + use_http3_upstreams: false + serve_plain_dns: true + hostsfile_enabled: true + pending_requests: + enabled: true +tls: + enabled: true + server_name: "" + force_https: false + port_https: 446 + port_dns_over_tls: 853 + port_dns_over_quic: 853 + port_dnscrypt: 0 + dnscrypt_config_file: "" + allow_unencrypted_doh: false + certificate_chain: "" + private_key: "" + certificate_path: /opt/adguardhome/certs/live/trez.wtf/priv-fullchain-bundle.pem + private_key_path: /opt/adguardhome/certs/live/trez.wtf/priv-fullchain-bundle.pem + strict_sni_check: false +querylog: + dir_path: "" + ignored: [] + interval: 2160h + size_memory: 1000 + enabled: true + file_enabled: true +statistics: + dir_path: "" + ignored: [] + interval: 24h + enabled: true +filters: + - enabled: true + url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt + name: AdGuard DNS filter + id: 1 + - enabled: false + url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_2.txt + name: AdAway Default Blocklist + id: 2 +whitelist_filters: [] +user_rules: [] +dhcp: + enabled: false + interface_name: "" + local_domain_name: lan + dhcpv4: + gateway_ip: 192.168.1.1 + subnet_mask: 255.255.255.0 + range_start: 192.168.1.2 + range_end: 192.168.1.240 + lease_duration: 86400 + icmp_timeout_msec: 1000 + options: [] + dhcpv6: + range_start: "" + lease_duration: 86400 + ra_slaac_only: false + ra_allow_slaac: false +filtering: + blocking_ipv4: "" + blocking_ipv6: "" + blocked_services: + schedule: + time_zone: America/New_York + ids: [] + protection_disabled_until: null + safe_search: + enabled: false + bing: true + duckduckgo: true + ecosia: true + google: true + pixabay: true + yandex: true + youtube: true + blocking_mode: default + parental_block_host: family-block.dns.adguard.com + safebrowsing_block_host: standard-block.dns.adguard.com + rewrites: [] + safe_fs_patterns: + - /opt/adguardhome/work/userfilters/* + safebrowsing_cache_size: 1048576 + safesearch_cache_size: 1048576 + parental_cache_size: 1048576 + cache_time: 30 + filters_update_interval: 24 + blocked_response_ttl: 10 + filtering_enabled: true + parental_enabled: false + safebrowsing_enabled: false + protection_enabled: true +clients: + runtime_sources: + whois: true + arp: true + rdns: true + dhcp: true + hosts: true + persistent: [] +log: + enabled: true + file: "" + max_backups: 0 + max_size: 100 + max_age: 3 + compress: false + local_time: false + verbose: false +os: + group: "" + user: "" + rlimit_nofile: 0 +schema_version: 29 diff --git a/ansible/app-configs/apprise/apprise.yml.j2 b/ansible/app-configs/apprise/apprise.yml.j2 new file mode 100644 index 00000000..5b0bfa5c --- /dev/null +++ b/ansible/app-configs/apprise/apprise.yml.j2 @@ -0,0 +1,6 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +urls: + - gotify://gotify/{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['APPRISE_GOTIFY_TOKEN'] }} + - mailto://{{ 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'] }}:{{ 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'] }}@trez.wtf25?smtp=postal-smtp&from=noreply@trez.wtf \ No newline at end of file diff --git a/ansible/app-configs/authelia/configuration.yml.j2 b/ansible/app-configs/authelia/configuration.yml.j2 new file mode 100644 index 00000000..48764283 --- /dev/null +++ b/ansible/app-configs/authelia/configuration.yml.j2 @@ -0,0 +1,172 @@ +{% 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" +server: + address: '0.0.0.0:9091' + endpoints: + enable_pprof: false + enable_expvars: false + disable_healthcheck: false + tls: + key: "" + certificate: "" + client_certificates: [] + headers: + csp_template: "" +log: + level: debug +telemetry: + metrics: + enabled: true + address: tcp://0.0.0.0:9959 +totp: + disable: false + issuer: authelia.com + algorithm: sha256 + digits: 6 + period: 30 + skew: 1 + secret_size: 32 +webauthn: + disable: false + timeout: 60s + display_name: Authelia + attestation_conveyance_preference: indirect + selection_criteria: + user_verification: preferred +ntp: + address: "time.cloudflare.com:123" + version: 4 + max_desync: 3s + disable_startup_check: false + disable_failure: false +authentication_backend: + password_reset: + disable: false + custom_url: "" + ldap: + implementation: custom + address: ldap://lldap:3890 + timeout: 5s + start_tls: false + base_dn: dc=trez,dc=wtf + additional_users_dn: ou=people + users_filter: "(&({username_attribute}={input})(objectClass=person))" + additional_groups_dn: ou=groups + groups_filter: "(member={dn})" + attributes: + username: uid + group_name: cn + mail: mail + display_name: displayName + user: uid=authelia,ou=people,dc=trez,dc=wtf + 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: '{{ 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 + min_length: 8 + max_length: 0 + require_uppercase: true + require_lowercase: true + require_number: true + require_special: false + zxcvbn: + enabled: false + min_score: 3 +access_control: + default_policy: deny + networks: + - name: 'internal' + networks: + - '172.17.0.0/16' + - '172.18.0.0/16' + - '192.168.1.0/24' + rules: + - domain_regex: + - '^trez.wtf$' + - ^www.trez.wtf$'' + policy: bypass + - domain: '*.trez.wtf' + policy: bypass + networks: + - 'internal' + - domain: '*.trez.wtf' + policy: one_factor + subject: + - ['user:the.trezured.one'] +session: + name: authelia_session + 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 + cookies: + - domain: 'trez.wtf' + authelia_url: 'https://auth.trez.wtf' + redis: + host: redis + port: 6379 +storage: + 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: '{{ 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 + find_time: 2m + ban_time: 5m +notifier: + disable_startup_check: true + smtp: + address: 'smtp://postal-smtp:25' + timeout: '5s' + 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 +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: | + {{ 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(10) }} + 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/cloudflared/config.yml.j2 b/ansible/app-configs/cloudflared/config.yml.j2 new file mode 100644 index 00000000..a02e5104 --- /dev/null +++ b/ansible/app-configs/cloudflared/config.yml.j2 @@ -0,0 +1,16 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +tunnel: 52bdee6e-8ccb-47be-ba9e-f8010b905e41 +credentials-file: /etc/cloudflared/52bdee6e-8ccb-47be-ba9e-f8010b905e41.json +warp-routing: + enabled: true + +ingress: + - hostname: git-ssh.trez.wtf + service: ssh://gitea:22 + - hostname: gist-ssh.trez.wtf + service: ssh://gitea-opengist:2222 + - hostname: ssh.trez.wtf + service: ssh://192.168.1.254:22 + - service: http_status:404 # Default for unmatched requests diff --git a/ansible/app-configs/crowdsec/acquis.yaml.j2 b/ansible/app-configs/crowdsec/acquis.yaml.j2 new file mode 100644 index 00000000..2830970b --- /dev/null +++ b/ansible/app-configs/crowdsec/acquis.yaml.j2 @@ -0,0 +1,15 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + + +source: journalctl +journalctl_filter: + - "--directory=/var/log/host/" +labels: + type: syslog +--- +filenames: + - /var/log/swag/* +labels: + type: nginx +--- diff --git a/ansible/app-configs/crowdsec/config.yaml.j2 b/ansible/app-configs/crowdsec/config.yaml.j2 new file mode 100644 index 00000000..9f58cb6b --- /dev/null +++ b/ansible/app-configs/crowdsec/config.yaml.j2 @@ -0,0 +1,49 @@ +common: + daemonize: false + log_media: stdout + log_level: info + log_dir: /var/log/ +config_paths: + config_dir: /etc/crowdsec/ + data_dir: /var/lib/crowdsec/data/ + simulation_path: /etc/crowdsec/simulation.yaml + hub_dir: /etc/crowdsec/hub/ + index_path: /etc/crowdsec/hub/.index.json + notification_dir: /etc/crowdsec/notifications/ + plugin_dir: /usr/local/lib/crowdsec/plugins/ +crowdsec_service: + acquisition_path: /etc/crowdsec/acquis.yaml + acquisition_dir: /etc/crowdsec/acquis.d + parser_routines: 1 +plugin_config: + user: nobody + group: nobody +cscli: + output: human +db_config: + log_level: info + type: sqlite + db_path: /var/lib/crowdsec/data/crowdsec.db + flush: + max_items: 5000 + max_age: 7d + use_wal: false +api: + client: + insecure_skip_verify: false + credentials_path: /etc/crowdsec/local_api_credentials.yaml + server: + log_level: info + listen_uri: 0.0.0.0:8080 + profiles_path: /etc/crowdsec/profiles.yaml + trusted_ips: # IP ranges, or IPs which can have admin API access + - 127.0.0.1 + - ::1 + online_client: # Central API credentials (to push signals and receive bad IPs) + credentials_path: /etc/crowdsec/online_api_credentials.yaml + enable: true +prometheus: + enabled: true + level: full + listen_addr: 0.0.0.0 + listen_port: 6060 \ No newline at end of file diff --git a/ansible/app-configs/crowdsec/local-api-credentials.yaml.j2 b/ansible/app-configs/crowdsec/local-api-credentials.yaml.j2 new file mode 100644 index 00000000..5335296f --- /dev/null +++ b/ansible/app-configs/crowdsec/local-api-credentials.yaml.j2 @@ -0,0 +1,6 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +url: http://0.0.0.0:8080 +login: localhost +password: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['CROWDSEC_LOCAL_API_KEY'] }} \ No newline at end of file diff --git a/ansible/app-configs/crowdsec/online-api-credentials.yaml.j2 b/ansible/app-configs/crowdsec/online-api-credentials.yaml.j2 new file mode 100644 index 00000000..3f7aeafb --- /dev/null +++ b/ansible/app-configs/crowdsec/online-api-credentials.yaml.j2 @@ -0,0 +1,6 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +url: https://api.crowdsec.net/ +login: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['CROWDSEC_ONLINE_PASSWORD'] }} +password: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['CROWDSEC_ONLINE_PASSWORD'] }} \ No newline at end of file diff --git a/ansible/app-configs/crowdsec/profiles.yaml.j2 b/ansible/app-configs/crowdsec/profiles.yaml.j2 new file mode 100644 index 00000000..0dfb52c6 --- /dev/null +++ b/ansible/app-configs/crowdsec/profiles.yaml.j2 @@ -0,0 +1,17 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +name: default_ip_remediation +#debug: true +filters: + - Alert.Remediation == true && Alert.GetScope() == "Ip" +decisions: + - type: ban + duration: 4h +#duration_expr: Sprintf('%dh', (GetDecisionsCount(Alert.GetValue()) + 1) * 4) +# notifications: +# - slack_default # Set the webhook in /etc/crowdsec/notifications/slack.yaml before enabling this. +# - splunk_default # Set the splunk url and token in /etc/crowdsec/notifications/splunk.yaml before enabling this. +# - http_default # Set the required http parameters in /etc/crowdsec/notifications/http.yaml before enabling this. +# - email_default # Set the required email parameters in /etc/crowdsec/notifications/email.yaml before enabling this. +on_success: break \ No newline at end of file diff --git a/ansible/app-configs/ghost/ghost_config.production.json.j2 b/ansible/app-configs/ghost/ghost_config.production.json.j2 new file mode 100644 index 00000000..40e0dd14 --- /dev/null +++ b/ansible/app-configs/ghost/ghost_config.production.json.j2 @@ -0,0 +1,42 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +{ + "url": "blog.trez.wtf", + "database": { + "client": "mysql", + "connection": { + "host" : "mariadb", + "port" : 3306, + "user" : "ghost", + "password" : "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['GHOST_DB_PASSWORD'] }}", + "database" : "ghost_db" + } + }, + "mail": { + "from": "'Ghost @ Rinoa' ", + "transport": "SMTP", + "options": { + "host": "postal-smtp", + "port": 25, + "secure": false, + "auth": { + "user": "{{ 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'] }}", + "pass": "{{ 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'] }}" + } + } + }, + "paths": { + "contentPath": "content/" + }, + "privacy": { + "useGravatar": true + }, + "logging": { + "level": "info", + "rotation": { + "enabled": true + }, + "transports": ["file"] + } +} \ No newline at end of file diff --git a/ansible/app-configs/gitea/act-runner/config.yaml.j2 b/ansible/app-configs/gitea/act-runner/config.yaml.j2 new file mode 100644 index 00000000..f7882a24 --- /dev/null +++ b/ansible/app-configs/gitea/act-runner/config.yaml.j2 @@ -0,0 +1,101 @@ +# Example configuration file, it's safe to copy this as the default config file without any modification. + +# You don't have to copy this file to your instance, +# just run `./act_runner generate-config > config.yaml` to generate a config file. + +log: + # The level of logging, can be trace, debug, info, warn, error, fatal + level: info + +runner: + # Where to store the registration result. + file: .runner + # Execute how many tasks concurrently at the same time. + capacity: 3 + # Extra environment variables to run jobs. +# envs: +# A_TEST_ENV_NAME_1: a_test_env_value_1 +# A_TEST_ENV_NAME_2: a_test_env_value_2 + # Extra environment variables to run jobs from a file. + # It will be ignored if it's empty or the file doesn't exist. +# env_file: .env + # The timeout for a job to be finished. + # Please note that the Gitea instance also has a timeout (3h by default) for the job. + # So the job could be stopped by the Gitea instance if it's timeout is shorter than this. + timeout: 3h + # The timeout for the runner to wait for running jobs to finish when shutting down. + # Any running jobs that haven't finished after this timeout will be cancelled. + shutdown_timeout: 0s + # Whether skip verifying the TLS certificate of the Gitea instance. + insecure: false + # The timeout for fetching the job from the Gitea instance. + fetch_timeout: 5s + # The interval for fetching the job from the Gitea instance. + fetch_interval: 2s + # The labels of a runner are used to determine which jobs the runner can run, and how to run them. + # Like: "macos-arm64:host" or "ubuntu-latest:docker://gitea/runner-images:ubuntu-latest" + # Find more images provided by Gitea at https://gitea.com/gitea/runner-images . + # If it's empty when registering, it will ask for inputting labels. + # If it's empty when execute `daemon`, will use labels in `.runner` file. + labels: + - "ubuntu-latest:docker://gitea/runner-images:ubuntu-latest" + - "ubuntu-22.04:docker://gitea/runner-images:ubuntu-22.04" + - "ubuntu-20.04:docker://gitea/runner-images:ubuntu-20.04" + +cache: + # Enable cache server to use actions/cache. + enabled: true + # The directory to store the cache data. + # If it's empty, the cache data will be stored in $HOME/.cache/actcache. + dir: "" + # The host of the cache server. + # It's not for the address to listen, but the address to connect from job containers. + # So 0.0.0.0 is a bad choice, leave it empty to detect automatically. + host: "192.168.1.254" + # The port of the cache server. + # 0 means to use a random available port. + port: 63604 + # The external cache server URL. Valid only when enable is true. + # If it's specified, act_runner will use this URL as the ACTIONS_CACHE_URL rather than start a server by itself. + # The URL should generally end with "/". + external_server: "" + +container: + # Specifies the network to which the container will connect. + # Could be host, bridge or the name of a custom network. + # If it's empty, act_runner will create a network automatically. + network: "compose_default" + # Whether to use privileged mode or not when launching task containers (privileged mode is required for Docker-in-Docker). + privileged: false + # And other options to be used when the container is started (eg, --add-host=my.gitea.url:host-gateway). + options: + # The parent directory of a job's working directory. + # NOTE: There is no need to add the first '/' of the path as act_runner will add it automatically. + # If the path starts with '/', the '/' will be trimmed. + # For example, if the parent directory is /path/to/my/dir, workdir_parent should be path/to/my/dir + # If it's empty, /workspace will be used. + workdir_parent: + # Volumes (including bind mounts) can be mounted to containers. Glob syntax is supported, see https://github.com/gobwas/glob + # You can specify multiple volumes. If the sequence is empty, no volumes can be mounted. + # For example, if you only allow containers to mount the `data` volume and all the json files in `/src`, you should change the config to: + # valid_volumes: + # - data + # - /src/*.json + # If you want to allow any volume, please use the following configuration: + # valid_volumes: + # - '**' + valid_volumes: [] + # overrides the docker client host with the specified one. + # If it's empty, act_runner will find an available docker host automatically. + # If it's "-", act_runner will find an available docker host automatically, but the docker host won't be mounted to the job containers and service containers. + # If it's not empty or "-", the specified docker host will be used. An error will be returned if it doesn't work. + docker_host: "" + # Pull docker image(s) even if already present + force_pull: false + # Rebuild docker image(s) even if already present + force_rebuild: false + +host: + # The parent directory of a job's working directory. + # If it's empty, $HOME/.cache/act/ will be used. + workdir_parent: diff --git a/ansible/app-configs/gitea/app.ini.j2 b/ansible/app-configs/gitea/app.ini.j2 new file mode 100644 index 00000000..bc4e810b --- /dev/null +++ b/ansible/app-configs/gitea/app.ini.j2 @@ -0,0 +1,125 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +APP_NAME = Gitea: Git with a cup of tea +RUN_MODE = prod +RUN_USER = git +WORK_PATH = /data/gitea + +[repository] +ROOT = /data/git/repositories +DEFAULT_PRIVATE = last +EMABLE_PUSH_CREATE_USER = true + +[repository.local] +LOCAL_COPY_PATH = /data/gitea/tmp/local-repo + +[repository.upload] +TEMP_PATH = /data/gitea/uploads + +[server] +APP_DATA_PATH = /data/gitea +DOMAIN = git.trez.wtf +SSH_DOMAIN = git-ssh.trez.wtf +HTTP_PORT = 3000 +ROOT_URL = https://git.trez.wtf/ +DISABLE_SSH = false +SSH_PORT = 22 +SSH_LISTEN_PORT = 22 +LFS_START_SERVER = true +LFS_JWT_SECRET = {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['GITEA_LFS_JWT_SECRET'] }} +OFFLINE_MODE = true + +[database] +PATH = /data/gitea/gitea.db +DB_TYPE = postgres +HOST = gitea-db:5432 +NAME = gitea +USER = gitea +PASSWD = {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['GITEA_PG_DB_PASSWORD'] }} +LOG_SQL = false +SCHEMA = +SSL_MODE = disable + +[indexer] +ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve +REPO_INDEXER_ENABLED = true +REPO_INDEXER_PATH = indexers/repos.bleve +MAX_FILE_SIZE = 1048576 +REPO_INDEXER_INCLUDE = +REPO_INDEXER_EXCLUDE = resources/bin/** + +[session] +PROVIDER_CONFIG = /data/gitea/sessions +PROVIDER = file + +[picture] +AVATAR_UPLOAD_PATH = /data/gitea/avatars +REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars + +[attachment] +PATH = /data/gitea/attachments + +[log] +MODE = console +LEVEL = info +ROOT_PATH = root + +[security] +INSTALL_LOCK = true +SECRET_KEY = +REVERSE_PROXY_LIMIT = 1 +REVERSE_PROXY_TRUSTED_PROXIES = * +INTERNAL_TOKEN = {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['GITEA_INTERNAL_TOKEN'] }} +PASSWORD_HASH_ALGO = pbkdf2 + +[service] +DISABLE_REGISTRATION = false +REQUIRE_SIGNIN_VIEW = false +REGISTER_EMAIL_CONFIRM = true +ENABLE_NOTIFY_MAIL = true +ALLOW_ONLY_EXTERNAL_REGISTRATION = false +ENABLE_CAPTCHA = true +DEFAULT_KEEP_EMAIL_PRIVATE = true +DEFAULT_ALLOW_CREATE_ORGANIZATION = false +DEFAULT_ENABLE_TIMETRACKING = false +NO_REPLY_ADDRESS = noreply@trez.wtf + +[lfs] +PATH = /data/git/lfs + +[mailer] +PASSWD = {{ 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'] }} +PROTOCOL = smtp +ENABLED = true +FROM = '"Gitea" ' +SMTP_PORT = 25 +USER = rinoa/postal-smtp +SMTP_ADDR = postal-smtp +IS_TLS_ENABLED = faLse + +[openid] +ENABLE_OPENID_SIGNIN = true +ENABLE_OPENID_SIGNUP = true + +[cron.update_checker] +ENABLED = false + +[repository.pull-request] +DEFAULT_MERGE_STYLE = merge + +[repository.signing] +DEFAULT_TRUST_MODEL = committer + +[oauth2] +JWT_SECRET = {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['GITEA_OAUTH2_JWT_SECRET'] }} + +[ui] +THEMES = + +[actions] +ENABLED = true + +[webhook] +ALLOWED_HOST_LIST = private,104.21.1.234,172.67.152.146 +SKIP_TLS_VERIFY = true diff --git a/ansible/app-configs/gitea/gitea-sonarqube-bot/config.yaml.j2 b/ansible/app-configs/gitea/gitea-sonarqube-bot/config.yaml.j2 new file mode 100644 index 00000000..90b9fb69 --- /dev/null +++ b/ansible/app-configs/gitea/gitea-sonarqube-bot/config.yaml.j2 @@ -0,0 +1,81 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +# Gitea related configuration. Necessary for adding/updating comments on repository pull requests +gitea: + # Endpoint of your Gitea instance. Must be expandable by '/api/v1' to form the API base path as shown in Swagger UI. + url: https://git.trez.wtf + + # Created access token for the user that shall be used as bot account. + # User needs "Read project" permissions with access to "Pull Requests" + token: + value: "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['GITEA_SONARQUBE_BOT_GITEA_TOKEN'] }}" + # # or path to file containing the plain text secret + # file: /path/to/gitea/token + + # If the sent webhook has a signature header, the bot validates the request payload. If the value does not match, the + # request will be ignored. + # The bot looks for `X-Gitea-Signature` header containing the sha256 hmac hash of the plain text secret. If the header + # exists and no webhookSecret is defined here, the bot will ignore the request, because it cannot be validated. + webhook: + secret: "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['GITEA_SONARQUBE_BOT_GITEA_WEBHOOK_SECRET'] }}" + # # or path to file containing the plain text secret + # secretFile: /path/to/gitea/webhook/secret + + # Pull Request status check settings. + statusCheck: + # Configure the label/name of the PR status check. + name: "gitea-sonarqube-bot" + +# SonarQube related configuration. Necessary for requesting data from the API and processing the webhook. +sonarqube: + # Endpoint of your SonarQube instance. Must be expandable by '/api' to form the API base path. + url: https://sqube.trez.wtf + + # Created access token for the user that shall be used as bot account. + # User needs "Browse on project" permissions + token: + value: "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['GITEA_SONARQUBE_BOT_SQUBE_TOKEN'] }}" + # # or path to file containing the plain text secret + # file: /path/to/sonarqube/token + + # If the sent webhook has a signature header, the bot validates the request payload. If the value does not match, the + # request will be ignored. + # The bot looks for `X-Sonar-Webhook-HMAC-SHA256` header containing the sha256 hmac hash of the plain text secret. + # If the header exists and no webhookSecret is defined here, the bot will ignore the request, because it cannot be + # validated. + webhook: + secret: "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['GITEA_SONARQUBE_BOT_SQUBE_WEBHOOK_SECRET'] }}" + # # or path to file containing the plain text secret + # secretFile: /path/to/sonarqube/webhook/secret + + # Some useful metrics depend on the edition in use. There are various ones like code_smells, vulnerabilities, bugs, etc. + # By default, the bot will extract "bugs,vulnerabilities,code_smells" + # Setting this option you can extend that default list by your own metrics. + # additionalMetrics: [] + # - "new_security_hotspots" + +# List of project mappings to take care of. Webhooks for other projects will be ignored. +# At least one must be configured. Otherwise, all webhooks (no matter which source) because the bot cannot map on its own. +projects: + - sonarqube: + key: rinoa-docker + # A repository specification contains the owner name and the repository name itself. The owner can be the name of a + # real account or an organization in which the repository is located. + gitea: + owner: Trez.One + name: rinoa-docker + +# Define pull request names from SonarScanner analysis. Default pattern matches the Jenkins Gitea plugin schema. +namingPattern: + # Regular expression that MUST HAVE exactly ONE GROUP that matches the integer part of the PR. + # That integer part is identical to the pull request ID in Gitea. + regex: "^.*$" + + # Valid Go format string. It MUST have one integer placeholder which will be replaced by the pull request ID. + # See: https://pkg.go.dev/fmt#hdr-Printing + template: "%s" + + # Example for integer-only names + # # regex: "^(\\d+)$" + # # template: "%d" diff --git a/ansible/app-configs/grafana/alloy/alloy_config.alloy b/ansible/app-configs/grafana/alloy/alloy_config.alloy new file mode 100644 index 00000000..a6441e39 --- /dev/null +++ b/ansible/app-configs/grafana/alloy/alloy_config.alloy @@ -0,0 +1,404 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Agent globals +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +local.file "endpoints" { + // The endpoints file is used to define the endpoints, credentials and options + // for the Agent export to. + filename = "/etc/alloy/endpoints.json" +} + +discovery.docker "rinoadocker" { + host = env("DOCKER_HOST") +} + +tracing { + write_to = [otelcol.exporter.otlp.tempo.input] +} +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Metrics +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +prometheus.remote_write "mimir" { + endpoint { + url = json_path(local.file.endpoints.content, ".metrics.url")[0] + basic_auth { + username = json_path(local.file.endpoints.content, ".metrics.basicAuth.username")[0] + password = json_path(local.file.endpoints.content, ".metrics.basicAuth.password")[0] + } + } +} + +prometheus.scrape "prometheus" { + targets = [{ + __address__ = "localhost:12345", + }] + forward_to = [prometheus.remote_write.mimir.receiver] + job_name = "prometheus" +} + +prometheus.exporter.unix "rinoa" { + procfs_path = "/host/proc" + sysfs_path = "/host/sys" + rootfs_path = "/rootfs" +} + +prometheus.scrape "rinoa" { + targets = prometheus.exporter.unix.rinoa.targets + forward_to = [prometheus.remote_write.mimir.receiver] + job_name = "rinoa_host" +} + +prometheus.exporter.cadvisor "docker" { + docker_host = env("DOCKER_HOST") + storage_duration = "5m" +} + +prometheus.scrape "docker" { + targets = prometheus.exporter.cadvisor.docker.targets + forward_to = [prometheus.remote_write.mimir.receiver] + job_name = "docker_stats" +} +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Logging +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +loki.write "loki" { + endpoint { + url = json_path(local.file.endpoints.content, ".logs.url")[0] + basic_auth { + username = json_path(local.file.endpoints.content, ".logs.basicAuth.username")[0] + password = json_path(local.file.endpoints.content, ".logs.basicAuth.password")[0] + } + } + external_labels = {} +} + +loki.source.journal "hostjournal" { + forward_to = [loki.write.loki.receiver] + max_age = "24h" + path = "/rootfs/var/log/journal/" + labels = { + job = "host-journal", + } +} + +local.file_match "system" { + path_targets = [{ + __address__ = "localhost", + __path__ = "/rootfs/var/log/*log", + job = "varlogs", + }] +} + +loki.source.file "system" { + targets = local.file_match.system.targets + forward_to = [loki.write.loki.receiver] +} + +loki.source.docker "containers" { + host = env("DOCKER_HOST") + targets = discovery.docker.rinoadocker.targets + forward_to = [loki.write.loki.receiver] + labels = { + job = "containerlogs", + } +} + +loki.process "containers" { + forward_to = [loki.write.loki.receiver] + // stage.docker {} + stage.json { + expressions = { + attrs = "", + output = "log", + stream = "stream", + } + } + + stage.json { + expressions = { + tag = "", + } + source = "attrs" + } + + stage.regex { + expression = "(?P(?:[^|]*[^|])).(?P(?:[^|]*[^|])).(?P(?:[^|]*[^|])).(?P(?:[^|]*[^|]))" + source = "tag" + } + + stage.timestamp { + source = "time" + format = "RFC3339Nano" + } + + stage.labels { + values = { + container_id = null, + container_name = null, + image_id = null, + image_name = null, + stream = null, + tag = null, + } + } + + stage.output { + source = "output" + } +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Traces +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +beyla.ebpf "rinoadocker" { + open_port = "80-65535" + routes { + unmatched = "heauristic" + } + output { + traces = [ + otelcol.connector.servicegraph.tracemetrics.input, + otelcol.connector.spanmetrics.tracemetrics.input, + otelcol.processor.batch.default.input, + otelcol.connector.spanlogs.autologging.input, + ] + } +} + +prometheus.scrape "beyla" { + targets = beyla.ebpf.rinoadocker.targets + forward_to = [prometheus.remote_write.mimir.receiver] +} + +otelcol.auth.headers "tempo" { + header { + key = "Authorization" + value = join(["Basic ", json_path(local.file.endpoints.content, ".traces.basicAuthToken")[0]], "") + } +} + +otelcol.processor.batch "default" { + // Wait until we've received 16K of data. + send_batch_size = 16384 + send_batch_max_size = 16384 + // Or until 2 seconds have elapsed. + timeout = "2s" + // When the Agent has enough batched data, send it to the OpenTelemetry exporter named 'tempo'. + output { + traces = [otelcol.exporter.otlp.tempo.input] + } +} + +otelcol.exporter.otlp "tempo" { + // Define the client for exporting. + client { + // Authentication block. + auth = otelcol.auth.headers.tempo.handler + + // Send to the locally running Tempo instance, on port 4317 (OTLP gRPC). + endpoint = json_path(local.file.endpoints.content, ".traces.url")[0] + + // Configure TLS settings for communicating with the endpoint. + tls { + // The connection is insecure. + insecure = json_path(local.file.endpoints.content, ".traces.tls.insecure")[0] + // Do not verify TLS certificates when connecting. + insecure_skip_verify = json_path(local.file.endpoints.content, ".traces.tls.insecureSkipVerify")[0] + } + } +} + +otelcol.connector.spanlogs "autologging" { + // We only want to output a line for each root span (ie. every single trace), and not for every + // process or span (outputting a line for every span would be extremely verbose). + spans = false + roots = true + processes = false + // We want to ensure that the following three span attributes are included in the log line, if + // present. + span_attributes = [ "http.method", "http.target", "http.status_code" ] + + // Overrides the default key in the log line to be `traceId`, which is then used by Grafana to + // identify the trace ID for correlation with the Tempo datasource. + overrides { + trace_id_key = "traceId" + } + // Send to the OpenTelemetry Loki exporter. + output { + logs = [otelcol.exporter.loki.autologging.input] + } +} + +// Simply forwards the incoming OpenTelemetry log format out as a Loki log. +// We need this stage to ensure we can then process the logline as a Loki object. +otelcol.exporter.loki "autologging" { + forward_to = [loki.process.autologging.receiver] +} + +// The Loki processor allows us to accept a correctly formatted Loki log and mutate it into +// a set of fields for output. +loki.process "autologging" { + // The JSON stage simply extracts the `body` (the actual logline) from the Loki log, ignoring + // all other fields. + stage.json { + expressions = { "body" = "" } + } + // The output stage takes the body (the main logline) and uses this as the source for the output + // logline. In this case, it essentially turns it into logfmt. + stage.output { + source = "body" + } + + // Finally send the processed logline onto the Loki exporter. + forward_to = [loki.write.autologging.receiver] +} + +// The Loki writer receives a processed Loki log and then writes it to a Loki instance. +loki.write "autologging" { + // Add the `agent` value to the `job` label, so we can identify it as having been generated + // by Grafana Agent when querying. + external_labels = { + job = "agent", + } + + // Output the Loki log to the local Loki instance. + endpoint { + url = json_path(local.file.endpoints.content, ".logs.url")[0] + + // The basic auth credentials for the Loki instance. + basic_auth { + username = json_path(local.file.endpoints.content, ".logs.basicAuth.username")[0] + password = json_path(local.file.endpoints.content, ".logs.basicAuth.password")[0] + } + } +} + +// The Tail Sampling processor will use a set of policies to determine which received traces to keep +// and send to Tempo. +otelcol.processor.tail_sampling "errors" { + // Total wait time from the start of a trace before making a sampling decision. Note that smaller time + // periods can potentially cause a decision to be made before the end of a trace has occurred. + decision_wait = "30s" + + // The following policies follow a logical OR pattern, meaning that if any of the policies match, + // the trace will be kept. For logical AND, you can use the `and` policy. Every span of a trace is + // examined by each policy in turn. A match will cause a short-circuit. + + // This policy defines that traces that contain errors should be kept. + policy { + // The name of the policy can be used for logging purposes. + name = "sample-erroring-traces" + // The type must match the type of policy to be used, in this case examing the status code + // of every span in the trace. + type = "status_code" + // This block determines the error codes that should match in order to keep the trace, + // in this case the OpenTelemetry 'ERROR' code. + status_code { + status_codes = [ "ERROR" ] + } + } + + // This policy defines that only traces that are longer than 200ms in total should be kept. + policy { + // The name of the policy can be used for logging purposes. + name = "sample-long-traces" + // The type must match the policy to be used, in this case the total latency of the trace. + type = "latency" + // This block determines the total length of the trace in milliseconds. + latency { + threshold_ms = 200 + } + } + + // The output block forwards the kept traces onto the batch processor, which will marshall them + // for exporting to Tempo. + output { + traces = [otelcol.processor.batch.default.input] + } +} + +// The Spanmetrics Connector will generate RED metrics based on the incoming trace span data. +otelcol.connector.spanmetrics "tracemetrics" { + // The namespace explicit adds a prefix to all the generated span metrics names. + // In this case, we'll ensure they match as closely as possible those generated by Tempo. + namespace = "traces.spanmetrics" + + // Each extra dimension (metrics label) to be added to the generated metrics from matching span attributes. These + // need to be defined with a name and optionally a default value (in the following cases, we do not want a default + // value if the span attribute is not present). + dimension { + name = "http.method" + } + dimension { + name = "http.target" + } + dimension { + name = "http.status_code" + } + dimension { + name = "service.version" + } + + // A histogram block must be present, either explicitly defining bucket values or via an exponential block. + // We do the latter here. + histogram { + explicit { + } + } + + // The exemplar block is added to ensure we generate exemplars for traces on relevant metric values. + exemplars { + enabled = true + } + + // Generated metrics data is in OTLP format. We send this data to the OpenTelemetry Prometheus exporter to ensure + // it gets transformed into Prometheus format data. + output { + metrics = [otelcol.exporter.prometheus.tracemetrics.input] + } +} + +// The Servicegraph Connector will generate service graph metrics (edges and nodes) based on incoming trace spans. +otelcol.connector.servicegraph "tracemetrics" { + // Extra dimensions (metrics labels) to be added to the generated metrics from matching span attributes. + // For this component, this is defined as an array. There are no default values and the labels will not be generated + // for missing span attributes. + dimensions = [ + "http.method", + "http.target", + "http.status_code", + "service.version", + ] + + // Generated metrics data is in OTLP format. We send this data to the OpenTelemetry Prometheus exporter to ensure + // it gets transformed into Prometheus format data. + output { + metrics = [otelcol.exporter.prometheus.tracemetrics.input] + } +} + +otelcol.exporter.prometheus "tracemetrics" { + // Forward to our local Prometheus remote writer which will send the metrics to Mimir. + forward_to = [prometheus.remote_write.mimir.receiver] +} +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Profiling +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + +pyroscope.write "pyroscope" { + endpoint { + url = json_path(local.file.endpoints.content, ".profiles.url")[0] + basic_auth { + username = json_path(local.file.endpoints.content, ".profiles.basicAuth.username")[0] + password = json_path(local.file.endpoints.content, ".profiles.basicAuth.password")[0] + } + } + external_labels = {} +} + +pyroscope.ebpf "rinoadocker" { + forward_to = [pyroscope.write.pyroscope.receiver] + targets = discovery.docker.rinoadocker.targets +} \ No newline at end of file diff --git a/ansible/app-configs/grafana/alloy/alloy_endpoints.json.j2 b/ansible/app-configs/grafana/alloy/alloy_endpoints.json.j2 new file mode 100644 index 00000000..d50b71a4 --- /dev/null +++ b/ansible/app-configs/grafana/alloy/alloy_endpoints.json.j2 @@ -0,0 +1,34 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +{ + "metrics": { + "url": "http://grafana-mimir:9009/api/v1/push", + "basicAuth": { + "username": "", + "password": "" + } + }, + "logs": { + "url": "http://grafana-loki:3100/loki/api/v1/push", + "basicAuth": { + "username": "", + "password": "" + } + }, + "traces": { + "url": "http://grafana-tempo:4317", + "basicAuthToken": "", + "tls": { + "insecure": true, + "insecureSkipVerify": true + } + }, + "profiles": { + "url": "http://grafana-pyroscope:4040", + "basicAuth": { + "username": "", + "password": "" + } + } +} \ No newline at end of file diff --git a/ansible/app-configs/grafana/beyla/beyla.yml.j2 b/ansible/app-configs/grafana/beyla/beyla.yml.j2 new file mode 100644 index 00000000..5fa9bfa4 --- /dev/null +++ b/ansible/app-configs/grafana/beyla/beyla.yml.j2 @@ -0,0 +1,7 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +routes: + patterns: + - /* + unmatched: heuristic diff --git a/ansible/app-configs/grafana/mimir/mimir.yaml.j2 b/ansible/app-configs/grafana/mimir/mimir.yaml.j2 new file mode 100644 index 00000000..80825a17 --- /dev/null +++ b/ansible/app-configs/grafana/mimir/mimir.yaml.j2 @@ -0,0 +1,77 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +multitenancy_enabled: false +no_auth_tenant: rinoa_mimir +# target: query-frontend +# api: +# prometheus_http_prefix: '/prometheus' +server: + http_listen_port: 9009 +# frontend: +# split_queries_by_interval: 24h +# align_queries_with_step: true + # cache_results: true + # results_cache: + # backend: "memcached" + # memcached: + # addresses: "memcached-mimir:11211" +# downstream_url: http://grafana-agent:12345 + +common: + storage: + backend: s3 + s3: + endpoint: minio:9000 + access_key_id: "Q8KAihuXtGgmretKNh7C" + secret_access_key: "hOlRODtnvFlNlL26Bj3GizZG6Ys3rlpG8p6Vo3NX" + bucket_name: "mimir" + insecure: true + +blocks_storage: + storage_prefix: rinoa + tsdb: + dir: /tmp/mimir/tsdb + +memberlist: + tls_enabled: false + +compactor: + # Directory to temporarily store blocks underdoing compaction. + data_dir: /tmp/mimir/compactor + # The sharding ring type used to share the hashed ring for the compactor. + sharding_ring: + # Use memberlist backend store (the default). + kvstore: + store: memberlist + +# The distributor receives incoming metrics data for the system. +distributor: + # The ring to share hash ring data across instances. + ring: + # The address advertised in the ring. Localhost. + instance_addr: 127.0.0.1 + # Use memberlist backend store (the default). + kvstore: + store: memberlist + +# The ingester receives data from the distributor and processes it into indices and blocks. +ingester: + # The ring to share hash ring data across instances. + ring: + # The address advertised in the ring. Localhost. + instance_addr: 127.0.0.1 + # Use memberlist backend store (the default). + kvstore: + store: memberlist + # Only run one instance of the ingesters. + # Note: It is highly recommended to run more than one ingester in production, the default is an RF of 3. + replication_factor: 1 + +# The store gateway block configures gateway storage. +store_gateway: + # Configuration for the hash ring. + sharding_ring: + # Only run a single instance. In production setups, the replication factor must + # be set on the querier and ruler as well. + replication_factor: 1 diff --git a/ansible/app-configs/grafana/pyroscope/config.yaml.j2 b/ansible/app-configs/grafana/pyroscope/config.yaml.j2 new file mode 100644 index 00000000..fe8066be --- /dev/null +++ b/ansible/app-configs/grafana/pyroscope/config.yaml.j2 @@ -0,0 +1,12 @@ +storage: + backend: s3 + s3: + bucket_name: pyroscope + endpoint: minio:9000 + region: us-east-fh-pln + access_key_id: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MINIO_PYROSCOPE_STORAGE_ACCESS_KEY'] }} + secret_access_key: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MINIO_PYROSCOPE_STORAGE_SECRET_KEY'] }} + insecure: true + +analytics: + reporting_enabled: false \ No newline at end of file diff --git a/ansible/app-configs/grafana/tempo/config.yml.j2 b/ansible/app-configs/grafana/tempo/config.yml.j2 new file mode 100644 index 00000000..690b60bd --- /dev/null +++ b/ansible/app-configs/grafana/tempo/config.yml.j2 @@ -0,0 +1,787 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +target: all +http_api_prefix: "" +autocomplete_filtering_enabled: true +server: + http_listen_network: tcp + http_listen_address: "" + http_listen_port: 80 + http_listen_conn_limit: 0 + grpc_listen_network: tcp + grpc_listen_address: "" + grpc_listen_port: 9095 + grpc_listen_conn_limit: 0 + tls_cipher_suites: "" + tls_min_version: "" + http_tls_config: + cert: "" + key: null + client_ca: "" + cert_file: "" + key_file: "" + client_auth_type: "" + client_ca_file: "" + grpc_tls_config: + cert: "" + key: null + client_ca: "" + cert_file: "" + key_file: "" + client_auth_type: "" + client_ca_file: "" + register_instrumentation: true + report_grpc_codes_in_instrumentation_label_enabled: false + graceful_shutdown_timeout: 30s + http_server_read_timeout: 30s + http_server_read_header_timeout: 0s + http_server_write_timeout: 30s + http_server_idle_timeout: 2m0s + http_log_closed_connections_without_response_enabled: false + grpc_server_max_recv_msg_size: 16777216 + grpc_server_max_send_msg_size: 16777216 + grpc_server_max_concurrent_streams: 100 + grpc_server_max_connection_idle: 2562047h47m16.854775807s + grpc_server_max_connection_age: 2562047h47m16.854775807s + grpc_server_max_connection_age_grace: 2562047h47m16.854775807s + grpc_server_keepalive_time: 2h0m0s + grpc_server_keepalive_timeout: 20s + grpc_server_min_time_between_pings: 10s + grpc_server_ping_without_stream_allowed: true + grpc_server_num_workers: 0 + log_format: logfmt + log_level: info + log_source_ips_enabled: false + log_source_ips_header: "" + log_source_ips_regex: "" + log_request_headers: false + log_request_at_info_level_enabled: false + log_request_exclude_headers_list: "" + http_path_prefix: "" +internal_server: + http_listen_network: tcp + http_listen_address: "" + http_listen_port: 3101 + http_listen_conn_limit: 0 + grpc_listen_network: "" + grpc_listen_address: "" + grpc_listen_port: 0 + grpc_listen_conn_limit: 0 + tls_cipher_suites: "" + tls_min_version: "" + http_tls_config: + cert: "" + key: null + client_ca: "" + cert_file: "" + key_file: "" + client_auth_type: "" + client_ca_file: "" + grpc_tls_config: + cert: "" + key: null + client_ca: "" + cert_file: "" + key_file: "" + client_auth_type: "" + client_ca_file: "" + register_instrumentation: false + report_grpc_codes_in_instrumentation_label_enabled: false + graceful_shutdown_timeout: 30s + http_server_read_timeout: 30s + http_server_read_header_timeout: 0s + http_server_write_timeout: 30s + http_server_idle_timeout: 2m0s + http_log_closed_connections_without_response_enabled: false + grpc_server_max_recv_msg_size: 0 + grpc_server_max_send_msg_size: 0 + grpc_server_max_concurrent_streams: 0 + grpc_server_max_connection_idle: 0s + grpc_server_max_connection_age: 0s + grpc_server_max_connection_age_grace: 0s + grpc_server_keepalive_time: 0s + grpc_server_keepalive_timeout: 0s + grpc_server_min_time_between_pings: 0s + grpc_server_ping_without_stream_allowed: false + grpc_server_num_workers: 0 + log_format: logfmt + log_level: info + log_source_ips_enabled: false + log_source_ips_header: "" + log_source_ips_regex: "" + log_request_headers: false + log_request_at_info_level_enabled: false + log_request_exclude_headers_list: "" + http_path_prefix: "" + enable: false +distributor: + ring: + kvstore: + store: memberlist + prefix: collectors/ + consul: + host: localhost:8500 + acl_token: "" + http_client_timeout: 20s + consistent_reads: false + watch_rate_limit: 1 + watch_burst_size: 1 + cas_retry_delay: 1s + etcd: + endpoints: [] + dial_timeout: 10s + max_retries: 10 + tls_enabled: false + tls_cert_path: "" + tls_key_path: "" + tls_ca_path: "" + tls_server_name: "" + tls_insecure_skip_verify: false + tls_cipher_suites: "" + tls_min_version: "" + username: "" + password: "" + multi: + primary: "" + secondary: "" + mirror_enabled: false + mirror_timeout: 2s + heartbeat_period: 5s + heartbeat_timeout: 5m0s + instance_id: local-instance + instance_interface_names: + - eth0 + - en0 + instance_port: 0 + instance_addr: "" + receivers: {} + override_ring_key: distributor + forwarders: [] + extend_writes: true + retry_after_on_resource_exhausted: 0s +ingester_client: + pool_config: + checkinterval: 15s + healthcheckenabled: true + healthchecktimeout: 1s + maxconcurrenthealthchecks: 0 + remote_timeout: 5s + grpc_client_config: + max_recv_msg_size: 104857600 + max_send_msg_size: 104857600 + grpc_compression: snappy + rate_limit: 0 + rate_limit_burst: 0 + backoff_on_ratelimits: false + backoff_config: + min_period: 100ms + max_period: 10s + max_retries: 10 + initial_stream_window_size: 63KiB1023B + initial_connection_window_size: 63KiB1023B + tls_enabled: false + tls_cert_path: "" + tls_key_path: "" + tls_ca_path: "" + tls_server_name: "" + tls_insecure_skip_verify: false + tls_cipher_suites: "" + tls_min_version: "" + connect_timeout: 5s + connect_backoff_base_delay: 1s + connect_backoff_max_delay: 5s +metrics_generator_client: + pool_config: + checkinterval: 15s + healthcheckenabled: true + healthchecktimeout: 1s + maxconcurrenthealthchecks: 0 + remote_timeout: 5s + grpc_client_config: + max_recv_msg_size: 104857600 + max_send_msg_size: 104857600 + grpc_compression: snappy + rate_limit: 0 + rate_limit_burst: 0 + backoff_on_ratelimits: false + backoff_config: + min_period: 100ms + max_period: 10s + max_retries: 10 + initial_stream_window_size: 63KiB1023B + initial_connection_window_size: 63KiB1023B + tls_enabled: false + tls_cert_path: "" + tls_key_path: "" + tls_ca_path: "" + tls_server_name: "" + tls_insecure_skip_verify: false + tls_cipher_suites: "" + tls_min_version: "" + connect_timeout: 5s + connect_backoff_base_delay: 1s + connect_backoff_max_delay: 5s +querier: + search: + query_timeout: 30s + prefer_self: 10 + external_hedge_requests_at: 8s + external_hedge_requests_up_to: 2 + external_backend: "" + google_cloud_run: null + external_endpoints: [] + trace_by_id: + query_timeout: 10s + max_concurrent_queries: 20 + frontend_worker: + frontend_address: 127.0.0.1:9095 + dns_lookup_duration: 10s + parallelism: 2 + match_max_concurrent: true + id: "" + grpc_client_config: + max_recv_msg_size: 104857600 + max_send_msg_size: 16777216 + grpc_compression: gzip + rate_limit: 0 + rate_limit_burst: 0 + backoff_on_ratelimits: false + backoff_config: + min_period: 100ms + max_period: 1s + max_retries: 5 + initial_stream_window_size: 0B + initial_connection_window_size: 0B + tls_enabled: false + tls_cert_path: "" + tls_key_path: "" + tls_ca_path: "" + tls_server_name: "" + tls_insecure_skip_verify: false + tls_cipher_suites: "" + tls_min_version: "" + connect_timeout: 0s + connect_backoff_base_delay: 0s + connect_backoff_max_delay: 0s + query_relevant_ingesters: false +query_frontend: + max_outstanding_per_tenant: 2000 + querier_forget_delay: 0s + max_batch_size: 5 + max_retries: 2 + search: + concurrent_jobs: 1000 + target_bytes_per_job: 104857600 + default_result_limit: 20 + max_result_limit: 0 + max_duration: 168h0m0s + query_backend_after: 15m0s + query_ingesters_until: 30m0s + trace_by_id: + query_shards: 50 + hedge_requests_at: 2s + hedge_requests_up_to: 2 + metrics: + concurrent_jobs: 1000 + target_bytes_per_job: 104857600 + max_duration: 0s + query_backend_after: 1h0m0s + interval: 5m0s + multi_tenant_queries_enabled: true +compactor: + ring: + kvstore: + store: "" + prefix: collectors/ + consul: + host: localhost:8500 + acl_token: "" + http_client_timeout: 20s + consistent_reads: false + watch_rate_limit: 1 + watch_burst_size: 1 + cas_retry_delay: 1s + etcd: + endpoints: [] + dial_timeout: 10s + max_retries: 10 + tls_enabled: false + tls_cert_path: "" + tls_key_path: "" + tls_ca_path: "" + tls_server_name: "" + tls_insecure_skip_verify: false + tls_cipher_suites: "" + tls_min_version: "" + username: "" + password: "" + multi: + primary: "" + secondary: "" + mirror_enabled: false + mirror_timeout: 2s + heartbeat_period: 5s + heartbeat_timeout: 1m0s + wait_stability_min_duration: 1m0s + wait_stability_max_duration: 5m0s + instance_id: local-instance + instance_interface_names: + - eth0 + - en0 + instance_port: 0 + instance_addr: "" + enable_inet6: false + wait_active_instance_timeout: 10m0s + compaction: + v2_in_buffer_bytes: 5242880 + v2_out_buffer_bytes: 20971520 + v2_prefetch_traces_count: 1000 + compaction_window: 1h0m0s + max_compaction_objects: 6000000 + max_block_bytes: 107374182400 + block_retention: 336h0m0s + compacted_block_retention: 1h0m0s + retention_concurrency: 10 + max_time_per_tenant: 5m0s + compaction_cycle: 30s + override_ring_key: compactor +ingester: + lifecycler: + ring: + kvstore: + store: inmemory + prefix: collectors/ + consul: + host: localhost:8500 + acl_token: "" + http_client_timeout: 20s + consistent_reads: false + watch_rate_limit: 1 + watch_burst_size: 1 + cas_retry_delay: 1s + etcd: + endpoints: [] + dial_timeout: 10s + max_retries: 10 + tls_enabled: false + tls_cert_path: "" + tls_key_path: "" + tls_ca_path: "" + tls_server_name: "" + tls_insecure_skip_verify: false + tls_cipher_suites: "" + tls_min_version: "" + username: "" + password: "" + multi: + primary: "" + secondary: "" + mirror_enabled: false + mirror_timeout: 2s + heartbeat_timeout: 5m0s + replication_factor: 1 + zone_awareness_enabled: false + excluded_zones: "" + num_tokens: 128 + heartbeat_period: 5s + heartbeat_timeout: 1m0s + observe_period: 0s + join_after: 0s + min_ready_duration: 15s + interface_names: + - en0 + - bridge100 + enable_inet6: false + final_sleep: 0s + tokens_file_path: "" + availability_zone: "" + unregister_on_shutdown: true + readiness_check_ring_health: true + address: 127.0.0.1 + port: 0 + id: local-instance + concurrent_flushes: 4 + flush_check_period: 10s + flush_op_timeout: 5m0s + trace_idle_period: 10s + max_block_duration: 30m0s + max_block_bytes: 524288000 + complete_block_timeout: 15m0s + override_ring_key: ring + flush_all_on_shutdown: false +metrics_generator: + ring: + kvstore: + store: inmemory + prefix: collectors/ + consul: + host: localhost:8500 + acl_token: "" + http_client_timeout: 20s + consistent_reads: false + watch_rate_limit: 1 + watch_burst_size: 1 + cas_retry_delay: 1s + etcd: + endpoints: [] + dial_timeout: 10s + max_retries: 10 + tls_enabled: false + tls_cert_path: "" + tls_key_path: "" + tls_ca_path: "" + tls_server_name: "" + tls_insecure_skip_verify: false + tls_cipher_suites: "" + tls_min_version: "" + username: "" + password: "" + multi: + primary: "" + secondary: "" + mirror_enabled: false + mirror_timeout: 2s + heartbeat_period: 5s + heartbeat_timeout: 1m0s + instance_id: local-instance + instance_interface_names: + - eth0 + - en0 + instance_addr: 127.0.0.1 + instance_port: 0 + enable_inet6: false + processor: + service_graphs: + wait: 10s + max_items: 10000 + workers: 10 + histogram_buckets: + - 0.1 + - 0.2 + - 0.4 + - 0.8 + - 1.6 + - 3.2 + - 6.4 + - 12.8 + dimensions: [] + enable_client_server_prefix: false + peer_attributes: + - peer.service + - db.name + - db.system + span_multiplier_key: "" + span_metrics: + histogram_buckets: + - 0.002 + - 0.004 + - 0.008 + - 0.016 + - 0.032 + - 0.064 + - 0.128 + - 0.256 + - 0.512 + - 1.024 + - 2.048 + - 4.096 + - 8.192 + - 16.384 + intrinsic_dimensions: + service: true + span_name: true + span_kind: true + status_code: true + dimensions: [] + dimension_mappings: [] + enable_target_info: false + span_multiplier_key: "" + subprocessors: + 0: true + 1: true + 2: true + filter_policies: [] + target_info_excluded_dimensions: [] + local_blocks: + block: + bloom_filter_false_positive: 0.01 + bloom_filter_shard_size_bytes: 102400 + version: vParquet3 + search_encoding: snappy + search_page_size_bytes: 1048576 + v2_index_downsample_bytes: 1048576 + v2_index_page_size_bytes: 256000 + v2_encoding: zstd + parquet_row_group_size_bytes: 100000000 + parquet_dedicated_columns: [] + search: + chunk_size_bytes: 1000000 + prefetch_trace_count: 1000 + read_buffer_count: 32 + read_buffer_size_bytes: 1048576 + cache_control: + footer: false + column_index: false + offset_index: false + flush_check_period: 10s + trace_idle_period: 10s + max_block_duration: 1m0s + max_block_bytes: 500000000 + complete_block_timeout: 1h0m0s + max_live_traces: 0 + concurrent_blocks: 10 + filter_server_spans: true + registry: + collection_interval: 15s + stale_duration: 15m0s + max_label_name_length: 1024 + max_label_value_length: 2048 + storage: + path: "" + wal: + wal_segment_size: 134217728 + wal_compression: none + stripe_size: 16384 + truncate_frequency: 2h0m0s + min_wal_time: 300000 + max_wal_time: 14400000 + no_lockfile: false + remote_write_flush_deadline: 1m0s + remote_write_add_org_id_header: true + traces_storage: + path: "" + completedfilepath: "" + blocksfilepath: "" + v2_encoding: none + search_encoding: none + ingestion_time_range_slack: 0s + version: vParquet3 + metrics_ingestion_time_range_slack: 30s + query_timeout: 30s + override_ring_key: metrics-generator +storage: + trace: + pool: + max_workers: 400 + queue_depth: 20000 + wal: + path: /tmp/tempo/wal + completedfilepath: /tmp/tempo/wal/completed + blocksfilepath: /tmp/tempo/wal/blocks + v2_encoding: snappy + search_encoding: none + ingestion_time_range_slack: 2m0s + version: vParquet3 + block: + bloom_filter_false_positive: 0.01 + bloom_filter_shard_size_bytes: 102400 + version: vParquet3 + search_encoding: snappy + search_page_size_bytes: 1048576 + v2_index_downsample_bytes: 1048576 + v2_index_page_size_bytes: 256000 + v2_encoding: zstd + parquet_row_group_size_bytes: 100000000 + parquet_dedicated_columns: [] + search: + chunk_size_bytes: 1000000 + prefetch_trace_count: 1000 + read_buffer_count: 32 + read_buffer_size_bytes: 1048576 + cache_control: + footer: false + column_index: false + offset_index: false + blocklist_poll: 5m0s + blocklist_poll_concurrency: 50 + blocklist_poll_fallback: true + blocklist_poll_tenant_index_builders: 2 + blocklist_poll_stale_tenant_index: 0s + blocklist_poll_jitter_ms: 0 + blocklist_poll_tolerate_consecutive_errors: 1 + backend: local + local: + path: /tmp/tempo/traces + gcs: + bucket_name: "" + prefix: "" + chunk_buffer_size: 10485760 + endpoint: "" + hedge_requests_at: 0s + hedge_requests_up_to: 2 + insecure: false + object_cache_control: "" + object_metadata: {} + list_blocks_concurrency: 3 + s3: + tls_cert_path: "" + tls_key_path: "" + tls_ca_path: "" + tls_server_name: "" + tls_insecure_skip_verify: false + tls_cipher_suites: "" + tls_min_version: VersionTLS12 + bucket: "" + prefix: "" + endpoint: "" + region: "" + access_key: "" + secret_key: "" + session_token: "" + insecure: false + part_size: 0 + hedge_requests_at: 0s + hedge_requests_up_to: 2 + signature_v2: false + forcepathstyle: false + bucket_lookup_type: 0 + tags: {} + storage_class: "" + metadata: {} + native_aws_auth_enabled: false + list_blocks_concurrency: 3 + azure: + storage_account_name: "" + storage_account_key: "" + use_managed_identity: false + use_federated_token: false + user_assigned_id: "" + container_name: "" + prefix: "" + endpoint_suffix: blob.core.windows.net + max_buffers: 4 + buffer_size: 3145728 + hedge_requests_at: 0s + hedge_requests_up_to: 2 + use_v2_sdk: false + cache: "" + background_cache: + writeback_goroutines: 10 + writeback_buffer: 10000 + memcached: null + redis: null + cache_min_compaction_level: 0 + cache_max_block_age: 0s +overrides: + defaults: + ingestion: + rate_strategy: local + rate_limit_bytes: 15000000 + burst_size_bytes: 20000000 + max_traces_per_user: 10000 + read: + max_bytes_per_tag_values_query: 5000000 + global: + max_bytes_per_trace: 5000000 + per_tenant_override_config: "" + per_tenant_override_period: 10s + user_configurable_overrides: + enabled: false + poll_interval: 1m0s + client: + backend: "" + confirm_versioning: true + local: + path: "" + gcs: + bucket_name: "" + prefix: "" + chunk_buffer_size: 10485760 + endpoint: "" + hedge_requests_at: 0s + hedge_requests_up_to: 2 + insecure: false + object_cache_control: "" + object_metadata: {} + list_blocks_concurrency: 3 + s3: + tls_cert_path: "" + tls_key_path: "" + tls_ca_path: "" + tls_server_name: "" + tls_insecure_skip_verify: false + tls_cipher_suites: "" + tls_min_version: VersionTLS12 + bucket: "" + prefix: "" + endpoint: "" + region: "" + access_key: "" + secret_key: "" + session_token: "" + insecure: false + part_size: 0 + hedge_requests_at: 0s + hedge_requests_up_to: 2 + signature_v2: false + forcepathstyle: false + bucket_lookup_type: 0 + tags: {} + storage_class: "" + metadata: {} + native_aws_auth_enabled: false + list_blocks_concurrency: 3 + azure: + storage_account_name: "" + storage_account_key: "" + use_managed_identity: false + use_federated_token: false + user_assigned_id: "" + container_name: "" + prefix: "" + endpoint_suffix: blob.core.windows.net + max_buffers: 4 + buffer_size: 3145728 + hedge_requests_at: 0s + hedge_requests_up_to: 2 + use_v2_sdk: false + api: + check_for_conflicting_runtime_overrides: false +memberlist: + node_name: "" + randomize_node_name: true + stream_timeout: 2s + retransmit_factor: 2 + pull_push_interval: 30s + gossip_interval: 1s + gossip_nodes: 2 + gossip_to_dead_nodes_time: 30s + dead_node_reclaim_time: 0s + compression_enabled: false + advertise_addr: "" + advertise_port: 7946 + cluster_label: "" + cluster_label_verification_disabled: false + join_members: [] + min_join_backoff: 1s + max_join_backoff: 1m0s + max_join_retries: 10 + abort_if_cluster_join_fails: false + rejoin_interval: 0s + left_ingesters_timeout: 5m0s + leave_timeout: 20s + message_history_buffer_bytes: 0 + bind_addr: [] + bind_port: 7946 + packet_dial_timeout: 2s + packet_write_timeout: 5s + tls_enabled: false + tls_cert_path: "" + tls_key_path: "" + tls_ca_path: "" + tls_server_name: "" + tls_insecure_skip_verify: false + tls_cipher_suites: "" + tls_min_version: "" +usage_report: + reporting_enabled: true + backoff: + min_period: 100ms + max_period: 10s + max_retries: 0 +cache: + background: + writeback_goroutines: 10 + writeback_buffer: 10000 + caches: [] \ No newline at end of file diff --git a/ansible/app-configs/grafana/tempo/tempo.yaml.j2 b/ansible/app-configs/grafana/tempo/tempo.yaml.j2 new file mode 100644 index 00000000..fbfd0050 --- /dev/null +++ b/ansible/app-configs/grafana/tempo/tempo.yaml.j2 @@ -0,0 +1,54 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + + +server: + http_listen_port: 3200 + +distributor: + receivers: # this configuration will listen on all ports and protocols that tempo is capable of. + jaeger: # the receives all come from the OpenTelemetry collector. more configuration information can + protocols: # be found there: https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver + thrift_http: # + grpc: # for a production deployment you should only enable the receivers you need! + thrift_binary: + thrift_compact: + zipkin: + otlp: + protocols: + http: + grpc: + opencensus: + +ingester: + max_block_duration: 5m # cut the headblock when this much time passes. this is being set for demo purposes and should probably be left alone normally + +compactor: + compaction: + block_retention: 1h # overall Tempo trace retention. set for demo purposes + +# metrics_generator: +# registry: +# external_labels: +# source: tempo +# cluster: docker-compose +# storage: +# path: /tmp/tempo/generator/wal +# remote_write: +# - url: http://grafana-alloy:12345/api/v1/write +# send_exemplars: true + +storage: + trace: + backend: s3 # backend configuration to use + wal: + path: /tmp/tempo/wal # where to store the the wal locally + s3: + bucket: tempo # how to store data in s3 + endpoint: minio:9000 + access_key: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MINIO_TEMPO_STORAGE_ACCESS_KEY'] }} + secret_key: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['MINIO_TEMPO_STORAGE_SECRET_KEY'] }} + insecure: true + +usage_report: + reporting_enabled: false \ No newline at end of file diff --git a/ansible/app-configs/homepage/bookmarks.yaml.j2 b/ansible/app-configs/homepage/bookmarks.yaml.j2 new file mode 100644 index 00000000..3213604c --- /dev/null +++ b/ansible/app-configs/homepage/bookmarks.yaml.j2 @@ -0,0 +1,22 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + + +--- +# For configuration options and examples, please see: +# https://gethomepage.dev/en/configs/bookmarks + +#- Developer: +# - Github: +# - abbr: GH +# href: https://github.com/ +# +#- Social: +# - Reddit: +# - abbr: RE +# href: https://reddit.com/ +# +#- Entertainment: +# - YouTube: +# - abbr: YT +# href: https://youtube.com/ diff --git a/ansible/app-configs/homepage/docker.yaml.j2 b/ansible/app-configs/homepage/docker.yaml.j2 new file mode 100644 index 00000000..58f2932a --- /dev/null +++ b/ansible/app-configs/homepage/docker.yaml.j2 @@ -0,0 +1,15 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + + +--- +# For configuration options and examples, please see: +# https://gethomepage.dev/en/configs/docker/ + +# my-docker: +# host: 127.0.0.1 +# port: 2375 + + my-docker: + host: dockerproxy + port: 2375 diff --git a/ansible/app-configs/homepage/kubernetes.yaml.j2 b/ansible/app-configs/homepage/kubernetes.yaml.j2 new file mode 100644 index 00000000..edc81b18 --- /dev/null +++ b/ansible/app-configs/homepage/kubernetes.yaml.j2 @@ -0,0 +1,6 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + + +--- +# sample kubernetes config diff --git a/ansible/app-configs/homepage/services.yaml.j2 b/ansible/app-configs/homepage/services.yaml.j2 new file mode 100644 index 00000000..7a610bbc --- /dev/null +++ b/ansible/app-configs/homepage/services.yaml.j2 @@ -0,0 +1,33 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +--- +# For configuration options and examples, please see: +# https://gethomepage.dev/en/configs/services + +#- My First Group: +# - My First Service: +# href: http://localhost/ +# description: Homepage is awesome +# +#- My Second Group: +# - My Second Service: +# href: http://localhost/ +# description: Homepage is the best +# +#- My Third Group: +# - My Third Service: +# href: http://localhost/ +# description: Homepage is 😎 + +- Automation: + - Home Assistant (Rikku): + href: https://ha.trez.wtf + description: Smart Home + icon: home-assistant.png + weight: 0 + widget: + type: homeassistant + url: http://192.168.1.252:8123 + key: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['HOMEPAGE_HOME_ASSISTANT_API_KEY'] }} + diff --git a/ansible/app-configs/homepage/settings.yaml.j2 b/ansible/app-configs/homepage/settings.yaml.j2 new file mode 100644 index 00000000..68393536 --- /dev/null +++ b/ansible/app-configs/homepage/settings.yaml.j2 @@ -0,0 +1,56 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +--- +# For configuration options and examples, please see: +# https://gethomepage.dev/en/configs/settings + +providers: + openweathermap: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['HOMEPAGE_OPENWEATHERMAP_API_KEY'] }} + # weatherapi: weatherapiapikey +title: Rinoa Dashboard (trez.WTF) +headerStyle: underlined +color: slate +showStats: false +statusStyle: "dot" +favicon: /icons/favicon.ico +useEqualHeights: true +hideErrors: false +searchDescriptions: true +showSearchSuggestions: true +provider: duckduckgo + +layout: + System Administration: + style: row + columns: 4 + Infrastructure/App Performance Monitoring: + style: row + columns: 3 + Code/DevOps: + style: row + columns: 3 + Social: + style: row + columns: 4 + Lifestyle: + style: row + columns: 3 + Automation: + style: row + columns: 5 + Privacy/Security: + style: row + columns: 5 + Personal/Professional Services: + style: row + columns: 5 + Servarr Stack: + style: row + columns: 3 + Downloaders: + style: row + columns: 2 + Media Library: + style: row + columns: 3 diff --git a/ansible/app-configs/homepage/widgets.yaml.j2 b/ansible/app-configs/homepage/widgets.yaml.j2 new file mode 100644 index 00000000..0e4f004c --- /dev/null +++ b/ansible/app-configs/homepage/widgets.yaml.j2 @@ -0,0 +1,33 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +--- +# For configuration options and examples, please see: +# https://gethomepage.dev/en/configs/widgets + +- resources: + label: System + cpu: true + memory: true + cputemp: true + uptime: true + +- resources: + label: Storage + expanded: true + disk: + - / + - /rinoa-storage + +- search: + provider: custom + url: https://search.trez.wtf/search?q= + target: _blank + +- openweathermap: + label: New York + latitude: 40.72 + longitude: -73.85 + units: imperial + provider: openweathermap + cache: 10 \ No newline at end of file diff --git a/ansible/app-configs/invidious/config.yml.j2 b/ansible/app-configs/invidious/config.yml.j2 new file mode 100644 index 00000000..7aff109b --- /dev/null +++ b/ansible/app-configs/invidious/config.yml.j2 @@ -0,0 +1,952 @@ +{% set vault_addr = 'https://vault.trez.wtf' %} +{% set secrets_path = 'rinoa-docker/env' %} + +######################################### +# +# Database and other external servers +# +######################################### + +## +## Database configuration with separate parameters. +## This setting is MANDATORY, unless 'database_url' is used. +## +db: + user: kemal + host: invidious-db + port: 5432 + dbname: invidious + password: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['INVID_PG_DB_PASSWORD'] }} + +## +## Database configuration using a single URI. This is an +## alternative to the 'db' parameter above. If both forms +## are used, then only database_url is used. +## This setting is MANDATORY, unless 'db' is used. +## +## Note: The 'database_url' setting allows the use of UNIX +## sockets. To do so, remove the IP address (or FQDN) and port +## and append the 'host' parameter. E.g: +## postgres://kemal:kemal@/invidious?host=/var/run/postgresql +## +## Accepted values: a postgres:// URI +## Default: postgres://kemal:kemal@localhost:5432/invidious +## +#database_url: postgres://kemal:kemal@localhost:5432/invidious + +## +## Enable automatic table integrity check. This will create +## the required tables and columns if anything is missing. +## +## Accepted values: true, false +## Default: false +## +check_tables: true + + +## +## Path to an external signature resolver, used to emulate +## the Youtube client's Javascript. If no such server is +## available, some videos will not be playable. +## +## When this setting is commented out, no external +## resolver will be used. +## +## Accepted values: a path to a UNIX socket or ":" +## Default: +## +signature_server: invidious-sig-helper:12999 + + +######################################### +# +# Server config +# +######################################### + +# ----------------------------- +# Network (inbound) +# ----------------------------- + +## +## Port to listen on for incoming connections. +## +## Note: Ports lower than 1024 requires either root privileges +## (not recommended) or the "CAP_NET_BIND_SERVICE" capability +## (See https://stackoverflow.com/a/414258 and `man capabilities`) +## +## Accepted values: 1-65535 +## Default: 3000 +## +#port: 3000 + +## +## When the invidious instance is behind a proxy, and the proxy +## listens on a different port than the instance does, this lets +## invidious know about it. This is used to craft absolute URLs +## to the instance (e.g in the API). +## +## Note: This setting is MANDATORY if invidious is behind a +## reverse proxy. +## +## Accepted values: 1-65535 +## Default: +## +#external_port: + +## +## Interface address to listen on for incoming connections. +## +## Accepted values: a valid IPv4 or IPv6 address. +## default: 0.0.0.0 (listen on all interfaces) +## +#host_binding: 0.0.0.0 + +## +## Domain name under which this instance is hosted. This is +## used to craft absolute URLs to the instance (e.g in the API). +## The domain MUST be defined if your instance is accessed from +## a domain name (like 'example.com'). +## +## Accepted values: a fully qualified domain name (FQDN) +## Default: +## +# domain: + +## +## Tell Invidious that it is behind a proxy that provides only +## HTTPS, so all links must use the https:// scheme. This +## setting MUST be set to true if invidious is behind a +## reverse proxy serving HTTPs. +## +## Accepted values: true, false +## Default: false +## +https_only: false + +## +## Enable/Disable 'Strict-Transport-Security'. Make sure that +## the domain specified under 'domain' is served securely. +## +## Accepted values: true, false +## Default: true +## +#hsts: true + + +# ----------------------------- +# Network (outbound) +# ----------------------------- + +## +## Disable proxying server-wide. Can be disable as a whole, or +## only for a single function. +## +## Accepted values: true, false, dash, livestreams, downloads, local +## Default: false +## +#disable_proxy: false + +## +## Size of the HTTP pool used to connect to youtube. Each +## domain ('youtube.com', 'ytimg.com', ...) has its own pool. +## +## Accepted values: a positive integer +## Default: 100 +## +#pool_size: 100 + + +## +## Additional cookies to be sent when requesting the youtube API. +## +## Accepted values: a string in the format "name1=value1; name2=value2..." +## Default: +## +#cookies: + +## +## Force connection to youtube over a specific IP family. +## +## Note: This may sometimes resolve issues involving rate-limiting. +## See https://github.com/ytdl-org/youtube-dl/issues/21729. +## +## Accepted values: ipv4, ipv6 +## Default: +## +#force_resolve: + +## +## Configuration for using a HTTP proxy +## +## If unset, then no HTTP proxy will be used. +## +#http_proxy: +# user: +# password: +# host: +# port: + + +## +## Use Innertube's transcripts API instead of timedtext for closed captions +## +## Useful for larger instances as InnerTube is **not ratelimited**. See https://github.com/iv-org/invidious/issues/2567 +## +## Subtitle experience may differ slightly on Invidious. +## +## Accepted values: true, false +## Default: false +## +# use_innertube_for_captions: false + +## +## Send Google session informations. This is useful when Invidious is blocked +## by the message "This helps protect our community." +## See https://github.com/iv-org/invidious/issues/4734. +## +## Warning: These strings gives much more identifiable information to Google! +## +## Accepted values: String +## Default: +## +po_token: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['INVID_PO_TOKEN'] }} +visitor_data: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['INVID_VISITOR_DATA'] }} + +# ----------------------------- +# Logging +# ----------------------------- + +## +## Path to log file. Can be absolute or relative to the invidious +## binary. This is overridden if "-o OUTPUT" or "--output=OUTPUT" +## are passed on the command line. +## +## Accepted values: a filesystem path or 'STDOUT' +## Default: STDOUT +## +#output: STDOUT + +## +## Logging Verbosity. This is overridden if "-l LEVEL" or +## "--log-level=LEVEL" are passed on the command line. +## +## Accepted values: All, Trace, Debug, Info, Warn, Error, Fatal, Off +## Default: Info +## +#log_level: Info + +## +## Enables colors in logs. Useful for debugging purposes +## This is overridden if "-k" or "--colorize" +## are passed on the command line. +## Colors are also disabled if the environment variable +## NO_COLOR is present and has any value +## +## Accepted values: true, false +## Default: true +## +#colorize_logs: false + +# ----------------------------- +# Features +# ----------------------------- + +## +## Enable/Disable the "Popular" tab on the main page. +## +## Accepted values: true, false +## Default: true +## +#popular_enabled: true + +## +## Enable/Disable statstics (available at /api/v1/stats). +## The following data is available: +## - Software name ("invidious") and version+branch (same data as +## displayed in the footer, e.g: "2021.05.13-75e5b49" / "master") +## - The value of the 'registration_enabled' config (true/false) +## - Number of currently registered users +## - Number of registered users who connected in the last month +## - Number of registered users who connected in the last 6 months +## - Timestamp of the last server restart +## - Timestamp of the last "Channel Refresh" job execution +## +## Warning: This setting MUST be set to true if you plan to run +## a public instance. It is used by api.invidious.io to refresh +## your instance's status. +## +## Accepted values: true, false +## Default: false +## +#statistics_enabled: false + + +# ----------------------------- +# Users and accounts +# ----------------------------- + +## +## Allow/Forbid Invidious (local) account creation. Invidious +## accounts allow users to subscribe to channels and to create +## playlists without a Google account. +## +## Accepted values: true, false +## Default: true +## +#registration_enabled: true + +## +## Allow/Forbid users to log-in. +## +## Accepted values: true, false +## Default: true +## +#login_enabled: true + +## +## Enable/Disable the captcha challenge on the login page. +## +## Note: this is a basic captcha challenge that doesn't +## depend on any third parties. +## +## Accepted values: true, false +## Default: true +## +#captcha_enabled: true + +## +## List of usernames that will be granted administrator rights. +## A user with administrator rights will be able to change the +## server configuration options listed below in /preferences, +## in addition to the usual user preferences. +## +## Server-wide settings: +## - popular_enabled +## - captcha_enabled +## - login_enabled +## - registration_enabled +## - statistics_enabled +## Default user preferences: +## - default_home +## - feed_menu +## +## Accepted values: an array of strings +## Default: [""] +## +#admins: [""] + +## +## Enable/Disable the user notifications for all users +## +## Note: On large instances, it is recommended to set this option to 'false' +## in order to reduce the amount of data written to the database, and hence +## improve the overall performance of the instance. +## +## Accepted values: true, false +## Default: true +## +#enable_user_notifications: true + +# ----------------------------- +# Background jobs +# ----------------------------- + +## +## Number of threads to use when crawling channel videos (during +## subscriptions update). +## +## Notes: This setting is overridden if either "-c THREADS" or +## "--channel-threads=THREADS" is passed on the command line. +## +## Accepted values: a positive integer +## Default: 1 +## +channel_threads: 1 + +## +## Time interval between two executions of the job that crawls +## channel videos (subscriptions update). +## +## Accepted values: a valid time interval (like 1h30m or 90m) +## Default: 30m +## +#channel_refresh_interval: 30m + +## +## Forcefully dump and re-download the entire list of uploaded +## videos when crawling channel (during subscriptions update). +## +## Accepted values: true, false +## Default: false +## +full_refresh: false + +## +## Number of threads to use when updating RSS feeds. +## +## Notes: This setting is overridden if either "-f THREADS" or +## "--feed-threads=THREADS" is passed on the command line. +## +## Accepted values: a positive integer +## Default: 1 +## +feed_threads: 1 + + +jobs: + + ## Options for the database cleaning job + clear_expired_items: + + ## Enable/Disable job + ## + ## Accepted values: true, false + ## Default: true + ## + enable: true + + ## Options for the channels updater job + refresh_channels: + + ## Enable/Disable job + ## + ## Accepted values: true, false + ## Default: true + ## + enable: true + + ## Options for the RSS feeds updater job + refresh_feeds: + + ## Enable/Disable job + ## + ## Accepted values: true, false + ## Default: true + ## + enable: true + + +# ----------------------------- +# Miscellaneous +# ----------------------------- + +## +## custom banner displayed at the top of every page. This can +## used for instance announcements, e.g. +## +## Accepted values: any string. HTML is accepted. +## Default: +## +#banner: + +## +## Subscribe to channels using PubSubHub (Google PubSubHubbub service). +## PubSubHub allows Invidious to be instantly notified when a new video +## is published on any subscribed channels. When PubSubHub is not used, +## Invidious will check for new videos every minute. +## +## Note: This setting is recommended for public instances. +## +## Note 2: +## - Requires a public instance (it uses /feed/webhook/v1) +## - Requires 'domain' and 'hmac_key' to be set. +## - Setting this parameter to any number greater than zero will +## enable channel subscriptions via PubSubHub, but will limit the +## amount of concurrent subscriptions. +## +## Accepted values: true, false, a positive integer +## Default: false +## +#use_pubsub_feeds: false + +## +## HMAC signing key used for CSRF tokens, cookies and pubsub +## subscriptions verification. +## +## Note: This parameter is mandatory and should be a random string. +## Such random string can be generated on linux with the following +## command: `pwgen 20 1` +## +## Accepted values: a string +## Default: +## +hmac_key: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token_cleaned)['secret']['INVID_HMAC_KEY'] }} + +## +## List of video IDs where the "download" widget must be +## disabled, in order to comply with DMCA requests. +## +## Accepted values: an array of string +## Default: +## +#dmca_content: + +## +## Cache video annotations in the database. +## +## Warning: empty annotations or annotations that only contain +## cards won't be cached. +## +## Accepted values: true, false +## Default: false +## +#cache_annotations: false + +## +## Source code URL. If your instance is running a modified source +## code, you MUST publish it somewhere and set this option. +## +## Accepted values: a string +## Default: +## +#modified_source_code_url: "" + +## +## Maximum custom playlist length limit. +## +## Accepted values: Integer +## Default: 500 +## +#playlist_length_limit: 500 + +######################################### +# +# Default user preferences +# +######################################### + +## +## NOTE: All the settings below define the default user +## preferences. They will apply to ALL users connecting +## without a preferences cookie (so either on the first +## connection to the instance or after clearing the +## browser's cookies). +## + +default_user_preferences: + + # ----------------------------- + # Internationalization + # ----------------------------- + + ## + ## Default user interface language (locale). + ## + ## Note: When hosting a public instance, overriding the + ## default (english) is not recommended, as it may + ## people using other languages. + ## + ## Accepted values: + ## ar (Arabic) + ## da (Danish) + ## de (German) + ## en-US (english, US) + ## el (Greek) + ## eo (Esperanto) + ## es (Spanish) + ## fa (Persian) + ## fi (Finnish) + ## fr (French) + ## he (Hebrew) + ## hr (Hungarian) + ## id (Indonesian) + ## is (Icelandic) + ## it (Italian) + ## ja (Japanese) + ## nb-NO (Norwegian, Bokmål) + ## nl (Dutch) + ## pl (Polish) + ## pt-BR (Portuguese, Brazil) + ## pt-PT (Portuguese, Portugal) + ## ro (Romanian) + ## ru (Russian) + ## sv (Swedish) + ## tr (Turkish) + ## uk (Ukrainian) + ## zh-CN (Chinese, China) (a.k.a "Simplified Chinese") + ## zh-TW (Chinese, Taiwan) (a.k.a "Traditional Chinese") + ## + ## Default: en-US + ## + #locale: en-US + + ## + ## Default geographical location for content. + ## + ## Accepted values: + ## AE, AR, AT, AU, AZ, BA, BD, BE, BG, BH, BO, BR, BY, CA, CH, CL, CO, CR, + ## CY, CZ, DE, DK, DO, DZ, EC, EE, EG, ES, FI, FR, GB, GE, GH, GR, GT, HK, + ## HN, HR, HU, ID, IE, IL, IN, IQ, IS, IT, JM, JO, JP, KE, KR, KW, KZ, LB, + ## LI, LK, LT, LU, LV, LY, MA, ME, MK, MT, MX, MY, NG, NI, NL, NO, NP, NZ, + ## OM, PA, PE, PG, PH, PK, PL, PR, PT, PY, QA, RO, RS, RU, SA, SE, SG, SI, + ## SK, SN, SV, TH, TN, TR, TW, TZ, UA, UG, US, UY, VE, VN, YE, ZA, ZW + ## + ## Default: US + ## + #region: US + + ## + ## Top 3 preferred languages for video captions. + ## + ## Note: overriding the default (no preferred + ## caption language) is not recommended, in order + ## to not penalize people using other languages. + ## + ## Accepted values: a three-entries array. + ## Each entry can be one of: + ## "English", "English (auto-generated)", + ## "Afrikaans", "Albanian", "Amharic", "Arabic", + ## "Armenian", "Azerbaijani", "Bangla", "Basque", + ## "Belarusian", "Bosnian", "Bulgarian", "Burmese", + ## "Catalan", "Cebuano", "Chinese (Simplified)", + ## "Chinese (Traditional)", "Corsican", "Croatian", + ## "Czech", "Danish", "Dutch", "Esperanto", "Estonian", + ## "Filipino", "Finnish", "French", "Galician", "Georgian", + ## "German", "Greek", "Gujarati", "Haitian Creole", "Hausa", + ## "Hawaiian", "Hebrew", "Hindi", "Hmong", "Hungarian", + ## "Icelandic", "Igbo", "Indonesian", "Irish", "Italian", + ## "Japanese", "Javanese", "Kannada", "Kazakh", "Khmer", + ## "Korean", "Kurdish", "Kyrgyz", "Lao", "Latin", "Latvian", + ## "Lithuanian", "Luxembourgish", "Macedonian", + ## "Malagasy", "Malay", "Malayalam", "Maltese", "Maori", + ## "Marathi", "Mongolian", "Nepali", "Norwegian Bokmål", + ## "Nyanja", "Pashto", "Persian", "Polish", "Portuguese", + ## "Punjabi", "Romanian", "Russian", "Samoan", + ## "Scottish Gaelic", "Serbian", "Shona", "Sindhi", + ## "Sinhala", "Slovak", "Slovenian", "Somali", + ## "Southern Sotho", "Spanish", "Spanish (Latin America)", + ## "Sundanese", "Swahili", "Swedish", "Tajik", "Tamil", + ## "Telugu", "Thai", "Turkish", "Ukrainian", "Urdu", + ## "Uzbek", "Vietnamese", "Welsh", "Western Frisian", + ## "Xhosa", "Yiddish", "Yoruba", "Zulu" + ## + ## Default: ["", "", ""] + ## + #captions: ["", "", ""] + + + # ----------------------------- + # Interface + # ----------------------------- + + ## + ## Enable/Disable dark mode. + ## + ## Accepted values: "dark", "light", "auto" + ## Default: "auto" + ## + #dark_mode: "auto" + + ## + ## Enable/Disable thin mode (no video thumbnails). + ## + ## Accepted values: true, false + ## Default: false + ## + #thin_mode: false + + ## + ## List of feeds available on the home page. + ## + ## Note: "Subscriptions" and "Playlists" are only visible + ## when the user is logged in. + ## + ## Accepted values: A list of strings + ## Each entry can be one of: "Popular", "Trending", + ## "Subscriptions", "Playlists" + ## + ## Default: ["Popular", "Trending", "Subscriptions", "Playlists"] (show all feeds) + ## + #feed_menu: ["Popular", "Trending", "Subscriptions", "Playlists"] + + ## + ## Default feed to display on the home page. + ## + ## Note: setting this option to "Popular" has no + ## effect when 'popular_enabled' is set to false. + ## + ## Accepted values: Popular, Trending, Subscriptions, Playlists, + ## Default: Popular + ## + #default_home: Popular + + ## + ## Default number of results to display per page. + ## + ## Note: this affects invidious-generated pages only, such + ## as watch history and subscription feeds. Playlists, search + ## results and channel videos depend on the data returned by + ## the Youtube API. + ## + ## Accepted values: any positive integer + ## Default: 40 + ## + #max_results: 40 + + ## + ## Show/hide annotations. + ## + ## Accepted values: true, false + ## Default: false + ## + #annotations: false + + ## + ## Show/hide annotation. + ## + ## Accepted values: true, false + ## Default: false + ## + #annotations_subscribed: false + + ## + ## Type of comments to display below video. + ## + ## Accepted values: a two-entries array. + ## Each entry can be one of: "youtube", "reddit", "" + ## + ## Default: ["youtube", ""] + ## + #comments: ["youtube", ""] + + ## + ## Default player style. + ## + ## Accepted values: invidious, youtube + ## Default: invidious + ## + #player_style: invidious + + ## + ## Show/Hide the "related videos" sidebar when + ## watching a video. + ## + ## Accepted values: true, false + ## Default: true + ## + #related_videos: true + + + # ----------------------------- + # Video player behavior + # ----------------------------- + + ## + ## This option controls the value of the HTML5