Initial commit after Claude implementation

This commit is contained in:
Ian Roddis
2026-03-23 14:29:32 -03:00
commit 5920d3fd7a
62 changed files with 1847 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
---
authentik_data_dir: "{{ sovereign_base_dir }}/authentik"
+6
View File
@@ -0,0 +1,6 @@
---
- name: restart authentik
community.docker.docker_compose_v2:
project_src: "{{ authentik_data_dir }}"
state: present
recreate: always
+34
View File
@@ -0,0 +1,34 @@
---
- name: Create Authentik directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ authentik_data_dir }}"
- "{{ authentik_data_dir }}/media"
- "{{ authentik_data_dir }}/custom-templates"
- "{{ authentik_data_dir }}/certs"
- "{{ authentik_data_dir }}/postgres"
- name: Deploy Authentik docker-compose
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ authentik_data_dir }}/docker-compose.yml"
mode: '0644'
notify: restart authentik
- name: Start Authentik
community.docker.docker_compose_v2:
project_src: "{{ authentik_data_dir }}"
state: present
- name: Wait for Authentik to be ready
ansible.builtin.uri:
url: "http://localhost:9001/-/health/ready/"
method: GET
status_code: 200
register: result
until: result.status == 200
retries: 30
delay: 10
@@ -0,0 +1,116 @@
services:
authentik-postgresql:
image: docker.io/library/postgres:16-alpine
container_name: authentik-postgresql
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
interval: 30s
timeout: 5s
retries: 5
environment:
POSTGRES_PASSWORD: "{{ authentik_db_password }}"
POSTGRES_USER: authentik
POSTGRES_DB: authentik
volumes:
- {{ authentik_data_dir }}/postgres:/var/lib/postgresql/data
networks:
- internal
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "authentik-postgresql"
authentik-redis:
image: docker.io/library/redis:alpine
container_name: authentik-redis
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
interval: 30s
timeout: 3s
retries: 5
networks:
- internal
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "authentik-redis"
authentik-server:
image: ghcr.io/goauthentik/server:{{ authentik_version }}
container_name: authentik-server
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: authentik-redis
AUTHENTIK_POSTGRESQL__HOST: authentik-postgresql
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: "{{ authentik_db_password }}"
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_SECRET_KEY: "{{ authentik_secret_key }}"
AUTHENTIK_ERROR_REPORTING__ENABLED: "false"
AUTHENTIK_EMAIL__HOST: "{{ smtp_host }}"
AUTHENTIK_EMAIL__PORT: "{{ smtp_port }}"
AUTHENTIK_EMAIL__USERNAME: "{{ smtp_user }}"
AUTHENTIK_EMAIL__PASSWORD: "{{ smtp_password }}"
AUTHENTIK_EMAIL__FROM: "{{ smtp_from }}"
AUTHENTIK_EMAIL__USE_TLS: "true"
volumes:
- {{ authentik_data_dir }}/media:/media
- {{ authentik_data_dir }}/custom-templates:/templates
- {{ authentik_data_dir }}/certs:/certs
ports:
- "127.0.0.1:9001:9000"
depends_on:
- authentik-postgresql
- authentik-redis
labels:
- "traefik.enable=true"
- "traefik.http.routers.authentik.rule=Host(`{{ authentik_domain }}`)"
- "traefik.http.routers.authentik.tls=true"
- "traefik.http.routers.authentik.tls.certresolver=letsencrypt"
- "traefik.http.services.authentik.loadbalancer.server.port=9000"
networks:
- internal
- {{ sovereign_network_name }}
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "authentik-server"
authentik-worker:
image: ghcr.io/goauthentik/server:{{ authentik_version }}
container_name: authentik-worker
restart: unless-stopped
command: worker
environment:
AUTHENTIK_REDIS__HOST: authentik-redis
AUTHENTIK_POSTGRESQL__HOST: authentik-postgresql
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: "{{ authentik_db_password }}"
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_SECRET_KEY: "{{ authentik_secret_key }}"
AUTHENTIK_ERROR_REPORTING__ENABLED: "false"
volumes:
- {{ authentik_data_dir }}/media:/media
- {{ authentik_data_dir }}/certs:/certs
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- authentik-postgresql
- authentik-redis
networks:
- internal
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "authentik-worker"
networks:
internal:
{{ sovereign_network_name }}:
external: true
+4
View File
@@ -0,0 +1,4 @@
---
sovereign_network_name: sovereign
traefik_version: "v3.1"
traefik_data_dir: "{{ sovereign_base_dir }}/traefik"
+6
View File
@@ -0,0 +1,6 @@
---
- name: restart traefik
community.docker.docker_compose_v2:
project_src: "{{ traefik_data_dir }}"
state: present
recreate: always
+71
View File
@@ -0,0 +1,71 @@
---
- name: Install required packages
ansible.builtin.apt:
name:
- apt-transport-https
- ca-certificates
- curl
- gnupg
- lsb-release
- python3-pip
- python3-docker
state: present
update_cache: true
- name: Add Docker GPG key
ansible.builtin.apt_key:
url: https://download.docker.com/linux/ubuntu/gpg
state: present
- name: Add Docker repository
ansible.builtin.apt_repository:
repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
state: present
- name: Install Docker
ansible.builtin.apt:
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-compose-plugin
state: present
update_cache: true
- name: Enable and start Docker
ansible.builtin.systemd:
name: docker
enabled: true
state: started
- name: Create sovereign Docker network
community.docker.docker_network:
name: "{{ sovereign_network_name }}"
state: present
- name: Create Traefik data directory
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ traefik_data_dir }}"
- "{{ traefik_data_dir }}/config"
- name: Create acme.json for Let's Encrypt
ansible.builtin.file:
path: "{{ traefik_data_dir }}/acme.json"
state: touch
mode: '0600'
- name: Deploy Traefik docker-compose
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ traefik_data_dir }}/docker-compose.yml"
mode: '0644'
notify: restart traefik
- name: Start Traefik
community.docker.docker_compose_v2:
project_src: "{{ traefik_data_dir }}"
state: present
@@ -0,0 +1,46 @@
services:
traefik:
image: traefik:{{ traefik_version }}
container_name: traefik
restart: unless-stopped
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network={{ sovereign_network_name }}"
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.email={{ traefik_acme_email }}"
- "--certificatesresolvers.letsencrypt.acme.storage=/acme.json"
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
- "--log.level=INFO"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- {{ traefik_data_dir }}/acme.json:/acme.json
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik-dashboard.rule=Host(`{{ traefik_domain }}`)"
- "traefik.http.routers.traefik-dashboard.tls=true"
- "traefik.http.routers.traefik-dashboard.tls.certresolver=letsencrypt"
- "traefik.http.routers.traefik-dashboard.service=api@internal"
- "traefik.http.routers.traefik-dashboard.middlewares=traefik-auth"
- "traefik.http.middlewares.traefik-auth.basicauth.users={{ traefik_dashboard_password }}"
- "traefik.http.middlewares.authentik.forwardauth.address=http://authentik-server:9000/outpost.goauthentik.io/auth/traefik"
- "traefik.http.middlewares.authentik.forwardauth.trustForwardHeader=true"
- "traefik.http.middlewares.authentik.forwardauth.authResponseHeaders=X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-version"
networks:
- {{ sovereign_network_name }}
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "traefik"
networks:
{{ sovereign_network_name }}:
external: true
+2
View File
@@ -0,0 +1,2 @@
---
forgejo_data_dir: "{{ sovereign_base_dir }}/forgejo"
+6
View File
@@ -0,0 +1,6 @@
---
- name: restart forgejo
community.docker.docker_compose_v2:
project_src: "{{ forgejo_data_dir }}"
state: present
recreate: always
+22
View File
@@ -0,0 +1,22 @@
---
- name: Create Forgejo directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ forgejo_data_dir }}"
- "{{ forgejo_data_dir }}/data"
- "{{ forgejo_data_dir }}/config"
- name: Deploy Forgejo docker-compose
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ forgejo_data_dir }}/docker-compose.yml"
mode: '0644'
notify: restart forgejo
- name: Start Forgejo
community.docker.docker_compose_v2:
project_src: "{{ forgejo_data_dir }}"
state: present
@@ -0,0 +1,77 @@
services:
forgejo-db:
image: postgres:16-alpine
container_name: forgejo-db
restart: unless-stopped
environment:
POSTGRES_DB: forgejo
POSTGRES_USER: forgejo
POSTGRES_PASSWORD: "{{ forgejo_db_password }}"
volumes:
- {{ forgejo_data_dir }}/db:/var/lib/postgresql/data
networks:
- internal
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "forgejo-db"
forgejo:
image: codeberg.org/forgejo/forgejo:{{ forgejo_version }}
container_name: forgejo
restart: unless-stopped
depends_on:
- forgejo-db
environment:
USER_UID: 1000
USER_GID: 1000
FORGEJO__database__DB_TYPE: postgres
FORGEJO__database__HOST: forgejo-db:5432
FORGEJO__database__NAME: forgejo
FORGEJO__database__USER: forgejo
FORGEJO__database__PASSWD: "{{ forgejo_db_password }}"
FORGEJO__server__DOMAIN: "{{ forgejo_domain }}"
FORGEJO__server__ROOT_URL: "https://{{ forgejo_domain }}"
FORGEJO__server__SSH_DOMAIN: "{{ forgejo_domain }}"
FORGEJO__server__SSH_PORT: "{{ forgejo_ssh_port }}"
FORGEJO__server__SSH_LISTEN_PORT: 22
FORGEJO__security__SECRET_KEY: "{{ forgejo_secret_key }}"
FORGEJO__security__INTERNAL_TOKEN: "{{ forgejo_internal_token }}"
FORGEJO__lfs__JWT_SECRET: "{{ forgejo_lfs_jwt_secret }}"
FORGEJO__mailer__ENABLED: "true"
FORGEJO__mailer__SMTP_ADDR: "{{ smtp_host }}"
FORGEJO__mailer__SMTP_PORT: "{{ smtp_port }}"
FORGEJO__mailer__FROM: "{{ smtp_from }}"
FORGEJO__mailer__USER: "{{ smtp_user }}"
FORGEJO__mailer__PASSWD: "{{ smtp_password }}"
FORGEJO__openid__ENABLE_OPENID_SIGNIN: "true"
FORGEJO__openid__ENABLE_OPENID_SIGNUP: "false"
FORGEJO__oauth2_client__REGISTER_EMAIL_CONFIRM: "false"
FORGEJO__oauth2_client__ENABLE_AUTO_REGISTRATION: "true"
FORGEJO__log__LEVEL: warn
ports:
- "{{ forgejo_ssh_port }}:22"
volumes:
- {{ forgejo_data_dir }}/data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.forgejo.rule=Host(`{{ forgejo_domain }}`)"
- "traefik.http.routers.forgejo.tls=true"
- "traefik.http.routers.forgejo.tls.certresolver=letsencrypt"
- "traefik.http.services.forgejo.loadbalancer.server.port=3000"
networks:
- internal
- {{ sovereign_network_name }}
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "forgejo"
networks:
internal:
{{ sovereign_network_name }}:
external: true
+4
View File
@@ -0,0 +1,4 @@
---
graylog_data_dir: "{{ sovereign_base_dir }}/graylog"
opensearch_version: "2.15.0"
mongodb_version: "6.0"
+6
View File
@@ -0,0 +1,6 @@
---
- name: restart graylog
community.docker.docker_compose_v2:
project_src: "{{ graylog_data_dir }}"
state: present
recreate: always
+50
View File
@@ -0,0 +1,50 @@
---
- name: Create Graylog directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ graylog_data_dir }}"
- "{{ graylog_data_dir }}/data"
- "{{ graylog_data_dir }}/config"
- "{{ graylog_data_dir }}/opensearch"
- name: Set OpenSearch data directory permissions
ansible.builtin.file:
path: "{{ graylog_data_dir }}/opensearch"
owner: "1000"
group: "1000"
mode: '0775'
- name: Set vm.max_map_count for OpenSearch
ansible.posix.sysctl:
name: vm.max_map_count
value: '262144'
state: present
sysctl_set: true
- name: Deploy Graylog docker-compose
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ graylog_data_dir }}/docker-compose.yml"
mode: '0644'
notify: restart graylog
- name: Start Graylog
community.docker.docker_compose_v2:
project_src: "{{ graylog_data_dir }}"
state: present
- name: Wait for Graylog to be ready
ansible.builtin.uri:
url: "http://localhost:9000/api/system/loglevel"
method: GET
user: admin
password: "{{ graylog_root_password_sha2 }}"
force_basic_auth: true
status_code: 200
register: result
until: result.status == 200
retries: 30
delay: 10
@@ -0,0 +1,70 @@
services:
mongodb:
image: mongo:{{ mongodb_version }}
container_name: graylog-mongodb
restart: unless-stopped
volumes:
- {{ graylog_data_dir }}/data/mongodb:/data/db
networks:
- internal
opensearch:
image: opensearchproject/opensearch:{{ opensearch_version }}
container_name: graylog-opensearch
restart: unless-stopped
environment:
- "OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g"
- "bootstrap.memory_lock=true"
- "discovery.type=single-node"
- "action.auto_create_index=false"
- "plugins.security.ssl.http.enabled=false"
- "plugins.security.disabled=true"
- "OPENSEARCH_INITIAL_ADMIN_PASSWORD=changeme_os_admin"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- {{ graylog_data_dir }}/opensearch:/usr/share/opensearch/data
networks:
- internal
graylog:
image: graylog/graylog:{{ graylog_version }}
container_name: graylog
restart: unless-stopped
depends_on:
- mongodb
- opensearch
environment:
GRAYLOG_NODE_ID_FILE: "/usr/share/graylog/data/config/node-id"
GRAYLOG_HTTP_BIND_ADDRESS: "0.0.0.0:9000"
GRAYLOG_ELASTICSEARCH_HOSTS: "http://opensearch:9200"
GRAYLOG_MONGODB_URI: "mongodb://mongodb:27017/graylog"
GRAYLOG_PASSWORD_SECRET: "{{ graylog_password_secret }}"
GRAYLOG_ROOT_PASSWORD_SHA2: "{{ graylog_root_password_sha2 }}"
GRAYLOG_HTTP_EXTERNAL_URI: "https://{{ graylog_domain }}/"
GRAYLOG_TRANSPORT_EMAIL_ENABLED: "true"
GRAYLOG_TRANSPORT_EMAIL_HOSTNAME: "{{ smtp_host }}"
GRAYLOG_TRANSPORT_EMAIL_PORT: "{{ smtp_port }}"
GRAYLOG_TRANSPORT_EMAIL_FROM_EMAIL: "{{ smtp_from }}"
ports:
- "127.0.0.1:9000:9000"
- "0.0.0.0:12201:12201/udp" # GELF UDP - must be accessible from all containers
volumes:
- {{ graylog_data_dir }}/data/graylog:/usr/share/graylog/data
- {{ graylog_data_dir }}/config:/usr/share/graylog/data/config
labels:
- "traefik.enable=true"
- "traefik.http.routers.graylog.rule=Host(`{{ graylog_domain }}`)"
- "traefik.http.routers.graylog.tls=true"
- "traefik.http.routers.graylog.tls.certresolver=letsencrypt"
- "traefik.http.services.graylog.loadbalancer.server.port=9000"
networks:
- internal
- {{ sovereign_network_name }}
networks:
internal:
{{ sovereign_network_name }}:
external: true
+2
View File
@@ -0,0 +1,2 @@
---
headscale_data_dir: "{{ sovereign_base_dir }}/headscale"
+6
View File
@@ -0,0 +1,6 @@
---
- name: restart headscale
community.docker.docker_compose_v2:
project_src: "{{ headscale_data_dir }}"
state: present
recreate: always
+29
View File
@@ -0,0 +1,29 @@
---
- name: Create Headscale directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ headscale_data_dir }}"
- "{{ headscale_data_dir }}/config"
- "{{ headscale_data_dir }}/data"
- name: Deploy Headscale config
ansible.builtin.template:
src: headscale-config.yaml.j2
dest: "{{ headscale_data_dir }}/config/config.yaml"
mode: '0644'
notify: restart headscale
- name: Deploy Headscale docker-compose
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ headscale_data_dir }}/docker-compose.yml"
mode: '0644'
notify: restart headscale
- name: Start Headscale
community.docker.docker_compose_v2:
project_src: "{{ headscale_data_dir }}"
state: present
@@ -0,0 +1,28 @@
services:
headscale:
image: headscale/headscale:{{ headscale_version }}
container_name: headscale
restart: unless-stopped
command: serve
volumes:
- {{ headscale_data_dir }}/config:/etc/headscale
- {{ headscale_data_dir }}/data:/var/lib/headscale
ports:
- "{{ wireguard_port }}:{{ wireguard_port }}/udp"
labels:
- "traefik.enable=true"
- "traefik.http.routers.headscale.rule=Host(`{{ headscale_domain }}`)"
- "traefik.http.routers.headscale.tls=true"
- "traefik.http.routers.headscale.tls.certresolver=letsencrypt"
- "traefik.http.services.headscale.loadbalancer.server.port=8080"
networks:
- {{ sovereign_network_name }}
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "headscale"
networks:
{{ sovereign_network_name }}:
external: true
@@ -0,0 +1,50 @@
server_url: "https://{{ headscale_domain }}"
listen_addr: 0.0.0.0:8080
grpc_listen_addr: 0.0.0.0:50443
grpc_allow_insecure: false
private_key_path: /var/lib/headscale/private.key
noise:
private_key_path: /var/lib/headscale/noise_private.key
prefixes:
v6: fd7a:115c:a1e0::/48
v4: 100.64.0.0/10
allocation: sequential
derp:
server:
enabled: false
urls:
- https://controlplane.tailscale.com/derpmap/default
auto_update_enabled: true
update_frequency: 24h
disable_check_updates: true
ephemeral_node_inactivity_timeout: 30m
database:
type: sqlite
sqlite:
path: /var/lib/headscale/db.sqlite
log:
format: text
level: info
dns:
magic_dns: true
base_domain: "{{ base_domain }}"
nameservers:
global:
- 1.1.1.1
- 8.8.8.8
oidc:
only_start_if_oidc_is_available: true
issuer: "https://{{ authentik_domain }}/application/o/headscale/"
client_id: "headscale"
client_secret: "changeme_headscale_oidc_secret"
scope: ["openid", "profile", "email"]
extra_params:
domain_hint: "{{ base_domain }}"
+2
View File
@@ -0,0 +1,2 @@
---
jitsi_data_dir: "{{ sovereign_base_dir }}/jitsi"
+6
View File
@@ -0,0 +1,6 @@
---
- name: restart jitsi
community.docker.docker_compose_v2:
project_src: "{{ jitsi_data_dir }}"
state: present
recreate: always
+24
View File
@@ -0,0 +1,24 @@
---
- name: Create Jitsi directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ jitsi_data_dir }}"
- "{{ jitsi_data_dir }}/web"
- "{{ jitsi_data_dir }}/prosody"
- "{{ jitsi_data_dir }}/jicofo"
- "{{ jitsi_data_dir }}/jvb"
- name: Deploy Jitsi docker-compose
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ jitsi_data_dir }}/docker-compose.yml"
mode: '0644'
notify: restart jitsi
- name: Start Jitsi
community.docker.docker_compose_v2:
project_src: "{{ jitsi_data_dir }}"
state: present
+131
View File
@@ -0,0 +1,131 @@
services:
jitsi-web:
image: jitsi/web:{{ jitsi_version }}
container_name: jitsi-web
restart: unless-stopped
environment:
PUBLIC_URL: "https://{{ jitsi_domain }}"
XMPP_SERVER: jitsi-prosody
XMPP_DOMAIN: meet.jitsi
XMPP_AUTH_DOMAIN: auth.meet.jitsi
XMPP_INTERNAL_MUC_DOMAIN: internal-muc.meet.jitsi
XMPP_MUC_DOMAIN: muc.meet.jitsi
XMPP_BOSH_URL_BASE: http://jitsi-prosody:5280
XMPP_RECORDER_DOMAIN: recorder.meet.jitsi
ENABLE_AUTH: 1
ENABLE_GUESTS: 1
AUTH_TYPE: jwt
JWT_APP_ID: "jitsi"
JWT_APP_SECRET: "{{ jitsi_turn_secret }}"
TURN_CREDENTIALS: "{{ jitsi_turn_secret }}"
LETSENCRYPT_DOMAIN: "{{ jitsi_domain }}"
TZ: UTC
volumes:
- {{ jitsi_data_dir }}/web:/config
labels:
- "traefik.enable=true"
- "traefik.http.routers.jitsi.rule=Host(`{{ jitsi_domain }}`)"
- "traefik.http.routers.jitsi.tls=true"
- "traefik.http.routers.jitsi.tls.certresolver=letsencrypt"
- "traefik.http.services.jitsi.loadbalancer.server.port=80"
networks:
- internal
- {{ sovereign_network_name }}
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "jitsi-web"
jitsi-prosody:
image: jitsi/prosody:{{ jitsi_version }}
container_name: jitsi-prosody
restart: unless-stopped
environment:
XMPP_DOMAIN: meet.jitsi
XMPP_AUTH_DOMAIN: auth.meet.jitsi
XMPP_MUC_DOMAIN: muc.meet.jitsi
XMPP_INTERNAL_MUC_DOMAIN: internal-muc.meet.jitsi
XMPP_RECORDER_DOMAIN: recorder.meet.jitsi
JICOFO_AUTH_USER: focus
JICOFO_AUTH_PASSWORD: "{{ jitsi_jicofo_auth_password }}"
JVB_AUTH_USER: jvb
JVB_AUTH_PASSWORD: "{{ jitsi_jvb_auth_password }}"
JIBRI_RECORDER_USER: recorder
JIBRI_RECORDER_PASSWORD: "{{ jitsi_jibri_recorder_password }}"
JIBRI_XMPP_USER: jibri
JIBRI_XMPP_PASSWORD: "{{ jitsi_jibri_xmpp_password }}"
JWT_APP_ID: "jitsi"
JWT_APP_SECRET: "{{ jitsi_turn_secret }}"
ENABLE_AUTH: 1
ENABLE_GUESTS: 1
AUTH_TYPE: jwt
TZ: UTC
volumes:
- {{ jitsi_data_dir }}/prosody:/config
networks:
- internal
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "jitsi-prosody"
jitsi-jicofo:
image: jitsi/jicofo:{{ jitsi_version }}
container_name: jitsi-jicofo
restart: unless-stopped
depends_on:
- jitsi-prosody
environment:
XMPP_SERVER: jitsi-prosody
XMPP_DOMAIN: meet.jitsi
XMPP_AUTH_DOMAIN: auth.meet.jitsi
XMPP_INTERNAL_MUC_DOMAIN: internal-muc.meet.jitsi
JICOFO_AUTH_USER: focus
JICOFO_AUTH_PASSWORD: "{{ jitsi_jicofo_auth_password }}"
JVB_BREWERY_MUC: jvbbrewery
TZ: UTC
volumes:
- {{ jitsi_data_dir }}/jicofo:/config
networks:
- internal
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "jitsi-jicofo"
jitsi-jvb:
image: jitsi/jvb:{{ jitsi_version }}
container_name: jitsi-jvb
restart: unless-stopped
depends_on:
- jitsi-prosody
environment:
XMPP_SERVER: jitsi-prosody
XMPP_DOMAIN: meet.jitsi
XMPP_AUTH_DOMAIN: auth.meet.jitsi
XMPP_INTERNAL_MUC_DOMAIN: internal-muc.meet.jitsi
JVB_AUTH_USER: jvb
JVB_AUTH_PASSWORD: "{{ jitsi_jvb_auth_password }}"
JVB_BREWERY_MUC: jvbbrewery
JVB_PORT: 10000
JVB_TCP_HARVESTER_DISABLED: "true"
TZ: UTC
ports:
- "10000:10000/udp"
volumes:
- {{ jitsi_data_dir }}/jvb:/config
networks:
- internal
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "jitsi-jvb"
networks:
internal:
{{ sovereign_network_name }}:
external: true
+2
View File
@@ -0,0 +1,2 @@
---
matrix_data_dir: "{{ sovereign_base_dir }}/matrix"
+6
View File
@@ -0,0 +1,6 @@
---
- name: restart matrix
community.docker.docker_compose_v2:
project_src: "{{ matrix_data_dir }}"
state: present
recreate: always
+39
View File
@@ -0,0 +1,39 @@
---
- name: Create Matrix directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ matrix_data_dir }}"
- "{{ matrix_data_dir }}/synapse"
- "{{ matrix_data_dir }}/element"
- name: Generate Synapse config if not present
ansible.builtin.command:
cmd: >
docker run --rm
-v {{ matrix_data_dir }}/synapse:/data
-e SYNAPSE_SERVER_NAME={{ matrix_domain }}
-e SYNAPSE_REPORT_STATS=no
ghcr.io/element-hq/synapse:{{ matrix_version }}
generate
creates: "{{ matrix_data_dir }}/synapse/homeserver.yaml"
- name: Deploy Element config
ansible.builtin.template:
src: element-config.json.j2
dest: "{{ matrix_data_dir }}/element/config.json"
mode: '0644'
- name: Deploy Matrix docker-compose
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ matrix_data_dir }}/docker-compose.yml"
mode: '0644'
notify: restart matrix
- name: Start Matrix
community.docker.docker_compose_v2:
project_src: "{{ matrix_data_dir }}"
state: present
@@ -0,0 +1,69 @@
services:
matrix-db:
image: postgres:16-alpine
container_name: matrix-db
restart: unless-stopped
environment:
POSTGRES_USER: synapse
POSTGRES_PASSWORD: "{{ matrix_db_password }}"
POSTGRES_DB: synapse
POSTGRES_INITDB_ARGS: "--encoding='UTF8' --lc-collate='C' --lc-ctype='C'"
volumes:
- {{ matrix_data_dir }}/db:/var/lib/postgresql/data
networks:
- internal
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "matrix-db"
synapse:
image: ghcr.io/element-hq/synapse:{{ matrix_version }}
container_name: synapse
restart: unless-stopped
depends_on:
- matrix-db
environment:
SYNAPSE_CONFIG_PATH: /data/homeserver.yaml
volumes:
- {{ matrix_data_dir }}/synapse:/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.matrix.rule=Host(`{{ matrix_domain }}`)"
- "traefik.http.routers.matrix.tls=true"
- "traefik.http.routers.matrix.tls.certresolver=letsencrypt"
- "traefik.http.services.matrix.loadbalancer.server.port=8008"
networks:
- internal
- {{ sovereign_network_name }}
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "synapse"
element:
image: vectorim/element-web:latest
container_name: element
restart: unless-stopped
volumes:
- {{ matrix_data_dir }}/element/config.json:/app/config.json:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.element.rule=Host(`{{ element_domain }}`)"
- "traefik.http.routers.element.tls=true"
- "traefik.http.routers.element.tls.certresolver=letsencrypt"
- "traefik.http.services.element.loadbalancer.server.port=80"
networks:
- {{ sovereign_network_name }}
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "element"
networks:
internal:
{{ sovereign_network_name }}:
external: true
@@ -0,0 +1,32 @@
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://{{ matrix_domain }}",
"server_name": "{{ matrix_domain }}"
}
},
"brand": "Element",
"integrations_ui_url": "https://scalar.vector.im/",
"integrations_rest_url": "https://scalar.vector.im/api",
"bug_report_endpoint_url": "",
"default_country_code": "US",
"show_labs_settings": false,
"features": {},
"default_federate": true,
"default_theme": "light",
"room_directory": {
"servers": ["{{ matrix_domain }}"]
},
"enable_presence_by_hs_url": {
"https://{{ matrix_domain }}": false
},
"setting_defaults": {
"breadcrumbs": true
},
"jitsi": {
"preferred_domain": "{{ jitsi_domain }}"
},
"sso_redirect_options": {
"immediate": false
}
}
+2
View File
@@ -0,0 +1,2 @@
---
minio_data_dir: "{{ sovereign_base_dir }}/minio"
+6
View File
@@ -0,0 +1,6 @@
---
- name: restart minio
community.docker.docker_compose_v2:
project_src: "{{ minio_data_dir }}"
state: present
recreate: always
+40
View File
@@ -0,0 +1,40 @@
---
- name: Create MinIO directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ minio_data_dir }}"
- "{{ minio_data_dir }}/data"
- name: Deploy MinIO docker-compose
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ minio_data_dir }}/docker-compose.yml"
mode: '0644'
notify: restart minio
- name: Start MinIO
community.docker.docker_compose_v2:
project_src: "{{ minio_data_dir }}"
state: present
- name: Wait for MinIO to be ready
ansible.builtin.uri:
url: "http://localhost:9010/minio/health/live"
method: GET
status_code: 200
register: result
until: result.status == 200
retries: 15
delay: 5
- name: Create Nextcloud bucket in MinIO
community.general.minio:
endpoint: "http://localhost:9010"
access_key: "{{ minio_root_user }}"
secret_key: "{{ minio_root_password }}"
name: "{{ minio_nextcloud_bucket }}"
state: present
ignore_errors: true
@@ -0,0 +1,42 @@
services:
minio:
image: quay.io/minio/minio:{{ minio_version }}
container_name: minio
restart: unless-stopped
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: "{{ minio_root_user }}"
MINIO_ROOT_PASSWORD: "{{ minio_root_password }}"
MINIO_BROWSER_REDIRECT_URL: "https://{{ minio_console_domain }}"
MINIO_IDENTITY_OPENID_CONFIG_URL: "https://{{ authentik_domain }}/application/o/minio/.well-known/openid-configuration"
MINIO_IDENTITY_OPENID_CLIENT_ID: "minio"
MINIO_IDENTITY_OPENID_CLIENT_SECRET: "changeme_minio_oidc_secret"
MINIO_IDENTITY_OPENID_CLAIM_NAME: "policy"
MINIO_IDENTITY_OPENID_REDIRECT_URI: "https://{{ minio_console_domain }}/oauth_callback"
ports:
- "127.0.0.1:9010:9000"
volumes:
- {{ minio_data_dir }}/data:/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.minio-api.rule=Host(`{{ minio_domain }}`)"
- "traefik.http.routers.minio-api.tls=true"
- "traefik.http.routers.minio-api.tls.certresolver=letsencrypt"
- "traefik.http.routers.minio-api.service=minio-api"
- "traefik.http.services.minio-api.loadbalancer.server.port=9000"
- "traefik.http.routers.minio-console.rule=Host(`{{ minio_console_domain }}`)"
- "traefik.http.routers.minio-console.tls=true"
- "traefik.http.routers.minio-console.tls.certresolver=letsencrypt"
- "traefik.http.routers.minio-console.service=minio-console"
- "traefik.http.services.minio-console.loadbalancer.server.port=9001"
networks:
- {{ sovereign_network_name }}
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "minio"
networks:
{{ sovereign_network_name }}:
external: true
+2
View File
@@ -0,0 +1,2 @@
---
nextcloud_data_dir: "{{ sovereign_base_dir }}/nextcloud"
+6
View File
@@ -0,0 +1,6 @@
---
- name: restart nextcloud
community.docker.docker_compose_v2:
project_src: "{{ nextcloud_data_dir }}"
state: present
recreate: always
+21
View File
@@ -0,0 +1,21 @@
---
- name: Create Nextcloud directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ nextcloud_data_dir }}"
- "{{ nextcloud_data_dir }}/data"
- name: Deploy Nextcloud docker-compose
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ nextcloud_data_dir }}/docker-compose.yml"
mode: '0644'
notify: restart nextcloud
- name: Start Nextcloud
community.docker.docker_compose_v2:
project_src: "{{ nextcloud_data_dir }}"
state: present
@@ -0,0 +1,97 @@
services:
nextcloud-db:
image: mariadb:10.11
container_name: nextcloud-db
restart: unless-stopped
command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
environment:
MYSQL_ROOT_PASSWORD: "{{ nextcloud_db_root_password }}"
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: "{{ nextcloud_db_password }}"
volumes:
- {{ nextcloud_data_dir }}/db:/var/lib/mysql
networks:
- internal
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "nextcloud-db"
nextcloud-redis:
image: redis:alpine
container_name: nextcloud-redis
restart: unless-stopped
networks:
- internal
nextcloud:
image: nextcloud:{{ nextcloud_version }}
container_name: nextcloud
restart: unless-stopped
depends_on:
- nextcloud-db
- nextcloud-redis
environment:
MYSQL_HOST: nextcloud-db
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: "{{ nextcloud_db_password }}"
REDIS_HOST: nextcloud-redis
NEXTCLOUD_ADMIN_USER: "{{ nextcloud_admin_user }}"
NEXTCLOUD_ADMIN_PASSWORD: "{{ nextcloud_admin_password }}"
NEXTCLOUD_TRUSTED_DOMAINS: "{{ nextcloud_domain }}"
OVERWRITEPROTOCOL: https
OVERWRITECLIURL: "https://{{ nextcloud_domain }}"
SMTP_HOST: "{{ smtp_host }}"
SMTP_PORT: "{{ smtp_port }}"
SMTP_NAME: "{{ smtp_user }}"
SMTP_PASSWORD: "{{ smtp_password }}"
MAIL_FROM_ADDRESS: "noreply"
MAIL_DOMAIN: "{{ base_domain }}"
OBJECTSTORE_S3_HOST: minio
OBJECTSTORE_S3_PORT: 9000
OBJECTSTORE_S3_SSL: "false"
OBJECTSTORE_S3_BUCKET: "{{ minio_nextcloud_bucket }}"
OBJECTSTORE_S3_KEY: "{{ minio_nextcloud_access_key }}"
OBJECTSTORE_S3_SECRET: "{{ minio_nextcloud_secret_key }}"
OBJECTSTORE_S3_USEPATH_STYLE: "true"
volumes:
- {{ nextcloud_data_dir }}/data:/var/www/html
labels:
- "traefik.enable=true"
- "traefik.http.routers.nextcloud.rule=Host(`{{ nextcloud_domain }}`)"
- "traefik.http.routers.nextcloud.tls=true"
- "traefik.http.routers.nextcloud.tls.certresolver=letsencrypt"
- "traefik.http.services.nextcloud.loadbalancer.server.port=80"
- "traefik.http.middlewares.nextcloud-redirect.redirectregex.permanent=true"
- "traefik.http.middlewares.nextcloud-redirect.redirectregex.regex=https://(.*)/.well-known/(?:card|cal)dav"
- "traefik.http.middlewares.nextcloud-redirect.redirectregex.replacement=https://$${1}/remote.php/dav"
- "traefik.http.routers.nextcloud.middlewares=nextcloud-redirect"
networks:
- internal
- {{ sovereign_network_name }}
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "nextcloud"
nextcloud-cron:
image: nextcloud:{{ nextcloud_version }}
container_name: nextcloud-cron
restart: unless-stopped
volumes:
- {{ nextcloud_data_dir }}/data:/var/www/html
entrypoint: /cron.sh
depends_on:
- nextcloud-db
- nextcloud-redis
networks:
- internal
networks:
internal:
{{ sovereign_network_name }}:
external: true
+2
View File
@@ -0,0 +1,2 @@
---
roundcube_data_dir: "{{ sovereign_base_dir }}/roundcube"
+6
View File
@@ -0,0 +1,6 @@
---
- name: restart roundcube
community.docker.docker_compose_v2:
project_src: "{{ roundcube_data_dir }}"
state: present
recreate: always
+20
View File
@@ -0,0 +1,20 @@
---
- name: Create Roundcube directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ roundcube_data_dir }}"
- name: Deploy Roundcube docker-compose
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ roundcube_data_dir }}/docker-compose.yml"
mode: '0644'
notify: restart roundcube
- name: Start Roundcube
community.docker.docker_compose_v2:
project_src: "{{ roundcube_data_dir }}"
state: present
@@ -0,0 +1,57 @@
services:
roundcube-db:
image: postgres:16-alpine
container_name: roundcube-db
restart: unless-stopped
environment:
POSTGRES_DB: roundcube
POSTGRES_USER: roundcube
POSTGRES_PASSWORD: "{{ roundcube_db_password }}"
volumes:
- {{ roundcube_data_dir }}/db:/var/lib/postgresql/data
networks:
- internal
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "roundcube-db"
roundcube:
image: roundcube/roundcubemail:{{ roundcube_version }}
container_name: roundcube
restart: unless-stopped
depends_on:
- roundcube-db
environment:
ROUNDCUBEMAIL_DB_TYPE: pgsql
ROUNDCUBEMAIL_DB_HOST: roundcube-db
ROUNDCUBEMAIL_DB_NAME: roundcube
ROUNDCUBEMAIL_DB_USER: roundcube
ROUNDCUBEMAIL_DB_PASSWORD: "{{ roundcube_db_password }}"
ROUNDCUBEMAIL_DEFAULT_HOST: "ssl://stalwart"
ROUNDCUBEMAIL_DEFAULT_PORT: 993
ROUNDCUBEMAIL_SMTP_SERVER: "tls://stalwart"
ROUNDCUBEMAIL_SMTP_PORT: 587
ROUNDCUBEMAIL_DES_KEY: "{{ roundcube_des_key }}"
ROUNDCUBEMAIL_PLUGINS: "archive,zipdownload,managesieve,jqueryui"
ROUNDCUBEMAIL_SKIN: elastic
labels:
- "traefik.enable=true"
- "traefik.http.routers.roundcube.rule=Host(`{{ roundcube_domain }}`)"
- "traefik.http.routers.roundcube.tls=true"
- "traefik.http.routers.roundcube.tls.certresolver=letsencrypt"
- "traefik.http.services.roundcube.loadbalancer.server.port=80"
networks:
- internal
- {{ sovereign_network_name }}
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "roundcube"
networks:
internal:
{{ sovereign_network_name }}:
external: true
+2
View File
@@ -0,0 +1,2 @@
---
stalwart_data_dir: "{{ sovereign_base_dir }}/stalwart"
+6
View File
@@ -0,0 +1,6 @@
---
- name: restart stalwart
community.docker.docker_compose_v2:
project_src: "{{ stalwart_data_dir }}"
state: present
recreate: always
+21
View File
@@ -0,0 +1,21 @@
---
- name: Create Stalwart directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ stalwart_data_dir }}"
- "{{ stalwart_data_dir }}/data"
- name: Deploy Stalwart docker-compose
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ stalwart_data_dir }}/docker-compose.yml"
mode: '0644'
notify: restart stalwart
- name: Start Stalwart
community.docker.docker_compose_v2:
project_src: "{{ stalwart_data_dir }}"
state: present
@@ -0,0 +1,32 @@
services:
stalwart:
image: stalwartlabs/mail-server:{{ stalwart_version }}
container_name: stalwart
restart: unless-stopped
volumes:
- {{ stalwart_data_dir }}/data:/opt/stalwart-mail
ports:
- "25:25" # SMTP
- "465:465" # SMTPS
- "587:587" # SMTP submission
- "993:993" # IMAPS
- "4190:4190" # ManageSieve
environment:
TZ: UTC
labels:
- "traefik.enable=true"
- "traefik.http.routers.stalwart.rule=Host(`{{ stalwart_domain }}`)"
- "traefik.http.routers.stalwart.tls=true"
- "traefik.http.routers.stalwart.tls.certresolver=letsencrypt"
- "traefik.http.services.stalwart.loadbalancer.server.port=8080"
networks:
- {{ sovereign_network_name }}
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "stalwart"
networks:
{{ sovereign_network_name }}:
external: true
+2
View File
@@ -0,0 +1,2 @@
---
vaultwarden_data_dir: "{{ sovereign_base_dir }}/vaultwarden"
+6
View File
@@ -0,0 +1,6 @@
---
- name: restart vaultwarden
community.docker.docker_compose_v2:
project_src: "{{ vaultwarden_data_dir }}"
state: present
recreate: always
+21
View File
@@ -0,0 +1,21 @@
---
- name: Create Vaultwarden directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ vaultwarden_data_dir }}"
- "{{ vaultwarden_data_dir }}/data"
- name: Deploy Vaultwarden docker-compose
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ vaultwarden_data_dir }}/docker-compose.yml"
mode: '0644'
notify: restart vaultwarden
- name: Start Vaultwarden
community.docker.docker_compose_v2:
project_src: "{{ vaultwarden_data_dir }}"
state: present
@@ -0,0 +1,63 @@
services:
vaultwarden-db:
image: postgres:16-alpine
container_name: vaultwarden-db
restart: unless-stopped
environment:
POSTGRES_DB: vaultwarden
POSTGRES_USER: vaultwarden
POSTGRES_PASSWORD: "{{ vaultwarden_db_password }}"
volumes:
- {{ vaultwarden_data_dir }}/db:/var/lib/postgresql/data
networks:
- internal
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "vaultwarden-db"
vaultwarden:
image: vaultwarden/server:{{ vaultwarden_version }}
container_name: vaultwarden
restart: unless-stopped
depends_on:
- vaultwarden-db
environment:
DATABASE_URL: "postgresql://vaultwarden:{{ vaultwarden_db_password }}@vaultwarden-db/vaultwarden"
ADMIN_TOKEN: "{{ vaultwarden_admin_token }}"
DOMAIN: "https://{{ vaultwarden_domain }}"
SMTP_HOST: "{{ smtp_host }}"
SMTP_FROM: "{{ smtp_from }}"
SMTP_PORT: "{{ smtp_port }}"
SMTP_SECURITY: "{{ smtp_tls }}"
SMTP_USERNAME: "{{ smtp_user }}"
SMTP_PASSWORD: "{{ smtp_password }}"
SIGNUPS_ALLOWED: "false"
SSO_ENABLED: "true"
SSO_ONLY: "false"
SSO_AUTHORITY: "https://{{ authentik_domain }}/application/o/vaultwarden/"
SSO_CLIENT_ID: "vaultwarden"
SSO_CLIENT_SECRET: "changeme_vaultwarden_oidc_secret"
LOG_LEVEL: warn
volumes:
- {{ vaultwarden_data_dir }}/data:/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.vaultwarden.rule=Host(`{{ vaultwarden_domain }}`)"
- "traefik.http.routers.vaultwarden.tls=true"
- "traefik.http.routers.vaultwarden.tls.certresolver=letsencrypt"
- "traefik.http.services.vaultwarden.loadbalancer.server.port=80"
networks:
- internal
- {{ sovereign_network_name }}
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "vaultwarden"
networks:
internal:
{{ sovereign_network_name }}:
external: true
+3
View File
@@ -0,0 +1,3 @@
---
wazuh_data_dir: "{{ sovereign_base_dir }}/wazuh"
wazuh_indexer_memory: "512m"
+6
View File
@@ -0,0 +1,6 @@
---
- name: restart wazuh
community.docker.docker_compose_v2:
project_src: "{{ wazuh_data_dir }}"
state: present
recreate: always
+28
View File
@@ -0,0 +1,28 @@
---
- name: Create Wazuh directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ wazuh_data_dir }}"
- "{{ wazuh_data_dir }}/config"
- name: Set vm.max_map_count for Wazuh indexer (OpenSearch)
ansible.posix.sysctl:
name: vm.max_map_count
value: '262144'
state: present
sysctl_set: true
- name: Deploy Wazuh docker-compose
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ wazuh_data_dir }}/docker-compose.yml"
mode: '0644'
notify: restart wazuh
- name: Start Wazuh
community.docker.docker_compose_v2:
project_src: "{{ wazuh_data_dir }}"
state: present
+106
View File
@@ -0,0 +1,106 @@
services:
wazuh-manager:
image: wazuh/wazuh-manager:{{ wazuh_version }}
container_name: wazuh-manager
restart: unless-stopped
hostname: wazuh.manager
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 655360
hard: 655360
environment:
INDEXER_URL: "https://wazuh-indexer:9200"
INDEXER_USERNAME: admin
INDEXER_PASSWORD: "{{ wazuh_admin_password }}"
FILEBEAT_SSL_VERIFICATION_MODE: full
SSL_CERTIFICATE_AUTHORITIES: /etc/ssl/root-ca.pem
SSL_CERTIFICATE: /etc/ssl/filebeat.pem
SSL_KEY: /etc/ssl/filebeat.key
API_USERNAME: wazuh-wui
API_PASSWORD: "{{ wazuh_api_password }}"
ports:
- "1514:1514"
- "1515:1515"
- "514:514/udp"
- "55000:55000"
volumes:
- {{ wazuh_data_dir }}/wazuh-manager-master:/var/ossec/data
- {{ wazuh_data_dir }}/wazuh-indexer-certs/root-ca-manager.pem:/etc/ssl/root-ca.pem
- {{ wazuh_data_dir }}/wazuh-indexer-certs/wazuh.manager.pem:/etc/ssl/filebeat.pem
- {{ wazuh_data_dir }}/wazuh-indexer-certs/wazuh.manager-key.pem:/etc/ssl/filebeat.key
- {{ wazuh_data_dir }}/config:/wazuh-config-mount/etc
networks:
- internal
- {{ sovereign_network_name }}
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "wazuh-manager"
wazuh-indexer:
image: wazuh/wazuh-indexer:{{ wazuh_version }}
container_name: wazuh-indexer
restart: unless-stopped
hostname: wazuh-indexer
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
environment:
OPENSEARCH_JAVA_OPTS: "-Xms{{ wazuh_indexer_memory }} -Xmx{{ wazuh_indexer_memory }}"
volumes:
- {{ wazuh_data_dir }}/wazuh-indexer-data:/var/lib/wazuh-indexer
- {{ wazuh_data_dir }}/wazuh-indexer-certs/root-ca.pem:/usr/share/wazuh-indexer/certs/root-ca.pem
- {{ wazuh_data_dir }}/wazuh-indexer-certs/wazuh.indexer-key.pem:/usr/share/wazuh-indexer/certs/wazuh.indexer.key
- {{ wazuh_data_dir }}/wazuh-indexer-certs/wazuh.indexer.pem:/usr/share/wazuh-indexer/certs/wazuh.indexer.pem
- {{ wazuh_data_dir }}/wazuh-indexer-certs/admin.pem:/usr/share/wazuh-indexer/certs/admin.pem
- {{ wazuh_data_dir }}/wazuh-indexer-certs/admin-key.pem:/usr/share/wazuh-indexer/certs/admin-key.pem
networks:
- internal
wazuh-dashboard:
image: wazuh/wazuh-dashboard:{{ wazuh_version }}
container_name: wazuh-dashboard
restart: unless-stopped
hostname: wazuh-dashboard
depends_on:
- wazuh-indexer
environment:
INDEXER_USERNAME: admin
INDEXER_PASSWORD: "{{ wazuh_admin_password }}"
WAZUH_API_URL: https://wazuh-manager
DASHBOARD_USERNAME: kibanaserver
DASHBOARD_PASSWORD: "{{ wazuh_admin_password }}"
API_USERNAME: wazuh-wui
API_PASSWORD: "{{ wazuh_api_password }}"
volumes:
- {{ wazuh_data_dir }}/wazuh-indexer-certs/wazuh.dashboard.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard.pem
- {{ wazuh_data_dir }}/wazuh-indexer-certs/wazuh.dashboard-key.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard-key.pem
- {{ wazuh_data_dir }}/wazuh-indexer-certs/root-ca.pem:/usr/share/wazuh-dashboard/certs/root-ca.pem
labels:
- "traefik.enable=true"
- "traefik.http.routers.wazuh.rule=Host(`{{ wazuh_domain }}`)"
- "traefik.http.routers.wazuh.tls=true"
- "traefik.http.routers.wazuh.tls.certresolver=letsencrypt"
- "traefik.http.services.wazuh.loadbalancer.server.port=5601"
- "traefik.http.services.wazuh.loadbalancer.server.scheme=https"
networks:
- internal
- {{ sovereign_network_name }}
logging:
driver: gelf
options:
gelf-address: "udp://{{ graylog_host }}:{{ graylog_gelf_port }}"
tag: "wazuh-dashboard"
networks:
internal:
{{ sovereign_network_name }}:
external: true