diff --git a/roles/docker/defaults/main.yml b/roles/docker/defaults/main.yml index 11979f40..5477414c 100644 --- a/roles/docker/defaults/main.yml +++ b/roles/docker/defaults/main.yml @@ -48,7 +48,7 @@ services: allowed_sender_domain: true restic: - file: restic_backup.yml + file: restic.yml user: dc-user domain: rynkeby.skovgaard.tel host_key: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBLGol2G+a87ssy0nu/STKBZSiGyhZhZKx/ujfe9IeFo diff --git a/roles/docker/tasks/services/drone.yml b/roles/docker/tasks/services/drone.yml index 22b71cc7..de8720e5 100644 --- a/roles/docker/tasks/services/drone.yml +++ b/roles/docker/tasks/services/drone.yml @@ -1,52 +1,12 @@ # vim: ft=yaml.ansible --- -- name: set up drone with docker runner +- name: Upload Compose file for Drone + template: + src: compose-files/drone.yml.j2 + dest: "{{ services.drone.volume_folder }}/docker-compose.yml" + +- name: Deploy Drone docker_compose: - project_name: drone - pull: yes - definition: - version: "3.6" - services: - drone: - container_name: "drone" - image: "drone/drone:{{ services.drone.version }}" - restart: unless-stopped - networks: - - external_services - - drone - volumes: - - "{{ services.drone.volume_folder }}:/data" - - "/var/run/docker.sock:/var/run/docker.sock" - environment: - DRONE_GITEA_SERVER: "https://{{ services.forgejo.domain }}" - DRONE_GITEA_CLIENT_ID: "{{ drone_secrets.oauth_client_id }}" - DRONE_GITEA_CLIENT_SECRET: "{{ drone_secrets.oauth_client_secret }}" - DRONE_GIT_ALWAYS_AUTH: "true" - DRONE_SERVER_HOST: "{{ services.drone.domain }}" - DRONE_SERVER_PROTO: "https" - DRONE_RPC_SECRET: "{{ drone_secrets.rpc_shared_secret }}" - PLUGIN_CUSTOM_DNS: "91.239.100.100" - VIRTUAL_HOST: "{{ services.drone.domain }}" - LETSENCRYPT_HOST: "{{ services.drone.domain }}" - LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" - - drone-runner-docker: - container_name: "drone-runner-docker" - image: "drone/drone-runner-docker:{{ services.drone.version }}" - restart: unless-stopped - networks: - - drone - volumes: - - "/var/run/docker.sock:/var/run/docker.sock" - environment: - DRONE_RPC_HOST: "{{ services.drone.domain }}" - DRONE_RPC_PROTO: "https" - DRONE_RPC_SECRET: "{{ drone_secrets.rpc_shared_secret }}" - DRONE_RUNNER_CAPACITY: 2 - DRONE_RUNNER_NAME: "data.coop_drone_runner" - - networks: - drone: - external_services: - external: - name: external_services + project_src: "{{ services.drone.volume_folder }}" + pull: true + state: present diff --git a/roles/docker/tasks/services/hedgedoc.yml b/roles/docker/tasks/services/hedgedoc.yml index 8160a66c..6e5c874a 100644 --- a/roles/docker/tasks/services/hedgedoc.yml +++ b/roles/docker/tasks/services/hedgedoc.yml @@ -16,52 +16,13 @@ dest: "{{ services.hedgedoc.volume_folder }}/sso.data.coop.pem" mode: "0644" +- name: Upload Compose file for for HedgeDoc + template: + src: compose-files/hedgedoc.yml.j2 + dest: "{{ services.hedgedoc.volume_folder }}/docker-compose.yml" + - name: setup hedgedoc docker_compose: - project_name: "hedgedoc" - pull: "yes" - definition: - services: - database: - image: "postgres:{{ services.hedgedoc.postgres_version }}" - environment: - POSTGRES_USER: "codimd" - POSTGRES_PASSWORD: "{{ postgres_passwords.hedgedoc }}" - POSTGRES_DB: "codimd" - restart: "unless-stopped" - networks: - - "hedgedoc" - volumes: - - "{{ services.hedgedoc.volume_folder }}/db:/var/lib/postgresql/data" - - app: - image: "quay.io/hedgedoc/hedgedoc:{{ services.hedgedoc.version }}" - environment: - CMD_DB_URL: "postgres://codimd:{{ postgres_passwords.hedgedoc }}@hedgedoc_database_1:5432/codimd" - CMD_DOMAIN: "{{ services.hedgedoc.domain }}" - CMD_ALLOW_EMAIL_REGISTER: "False" - CMD_IMAGE_UPLOAD_TYPE: "filesystem" - CMD_EMAIL: "False" - CMD_SAML_IDPCERT: "/sso.data.coop.pem" - CMD_SAML_IDPSSOURL: "https://sso.data.coop/auth/realms/datacoop/protocol/saml" - CMD_SAML_ISSUER: "hedgedoc" - CMD_SAML_IDENTIFIERFORMAT: "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" - CMD_USECDN: "false" - CMD_PROTOCOL_USESSL: "true" - VIRTUAL_HOST: "{{ services.hedgedoc.domain }}" - LETSENCRYPT_HOST: "{{ services.hedgedoc.domain }}" - LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" - volumes: - - "{{ services.hedgedoc.volume_folder }}/hedgedoc/uploads:/hedgedoc/public/uploads" - - "{{ services.hedgedoc.volume_folder }}/sso.data.coop.pem:/sso.data.coop.pem" - restart: "unless-stopped" - networks: - - "hedgedoc" - - "external_services" - depends_on: - - database - - networks: - hedgedoc: - external_services: - external: true + project_src: "{{ services.hedgedoc.volume_folder }}" + pull: true + state: present diff --git a/roles/docker/tasks/services/keycloak.yml b/roles/docker/tasks/services/keycloak.yml index 7c23cfdd..45feb25b 100644 --- a/roles/docker/tasks/services/keycloak.yml +++ b/roles/docker/tasks/services/keycloak.yml @@ -1,50 +1,12 @@ # vim: ft=yaml.ansible --- -- name: setup keycloak containers for sso.data.coop +- name: Upload Compose file for for Keycloak + template: + src: compose-files/keycloak.yml.j2 + dest: "{{ services.keycloak.volume_folder }}/docker-compose.yml" + +- name: Deploy Keycloak docker_compose: - project_name: "keycloak" - pull: "yes" - definition: - version: "3.6" - services: - postgres: - image: "postgres:{{ services.keycloak.postgres_version }}" - restart: "unless-stopped" - networks: - - "keycloak" - volumes: - - "{{ services.keycloak.volume_folder }}/data:/var/lib/postgresql/data" - environment: - POSTGRES_USER: "keycloak" - POSTGRES_PASSWORD: "{{ postgres_passwords.keycloak }}" - POSTGRES_DB: "keycloak" - - app: - image: "quay.io/keycloak/keycloak:{{ services.keycloak.version }}" - restart: "unless-stopped" - networks: - - "keycloak" - - "postfix" - - "external_services" - command: - - "start" - - "--db=postgres" - - "--db-url=jdbc:postgresql://postgres:5432/keycloak" - - "--db-username=keycloak" - - "--db-password={{ postgres_passwords.keycloak }}" - - "--hostname={{ services.keycloak.domain }}" - - "--proxy=edge" - - "--https-port=8080" - - "--http-relative-path=/auth" - environment: - VIRTUAL_HOST: "{{ services.keycloak.domain }}" - VIRTUAL_PORT: "8080" - LETSENCRYPT_HOST: "{{ services.keycloak.domain }}" - LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" - - networks: - keycloak: - postfix: - external: true - external_services: - external: true + project_src: "{{ services.keycloak.volume_folder }}" + pull: true + state: present diff --git a/roles/docker/tasks/services/mailu.yml b/roles/docker/tasks/services/mailu.yml index 168609a0..de4916d9 100644 --- a/roles/docker/tasks/services/mailu.yml +++ b/roles/docker/tasks/services/mailu.yml @@ -33,7 +33,7 @@ src: "{{ services.nginx_proxy.volume_folder }}/certs/{{ services.mailu.domain }}/fullchain.pem" dest: "{{ services.mailu.volume_folder }}/certs/cert.pem" state: hard - force: yes + force: true when: letsencrypt_enabled - name: hard link to Let's Encrypt TLS key @@ -41,141 +41,16 @@ src: "{{ services.nginx_proxy.volume_folder }}/certs/{{ services.mailu.domain }}/key.pem" dest: "{{ services.mailu.volume_folder }}/certs/key.pem" state: hard - force: yes + force: true when: letsencrypt_enabled -- name: run mail server containers +- name: Upload Compose file for for Mailu + template: + src: compose-files/mailu.yml.j2 + dest: "{{ services.mailu.volume_folder }}/docker-compose.yml" + +- name: Deploy Mailu docker_compose: - project_name: mail_server - pull: yes - definition: - version: '3.6' - services: - postgres: - image: postgres:14-alpine - restart: always - environment: - POSTGRES_DB: mailu - POSTGRES_USER: mailu - POSTGRES_PASSWORD: "{{ postgres_passwords.mailu }}" - volumes: - - "{{ services.mailu.volume_folder }}/postgres:/var/lib/postgresql/data" - dns: - - "{{ services.mailu.dns }}" - - redis: - image: redis:alpine - restart: always - volumes: - - "{{ services.mailu.volume_folder }}/redis:/data" - depends_on: - - resolver - dns: - - "{{ services.mailu.dns }}" - - front: - image: ghcr.io/mailu/nginx:{{ services.mailu.version }} - restart: always - env_file: "{{ services.mailu.volume_folder }}/mailu.env" - environment: - VIRTUAL_HOST: "{{ services.mailu.domain }}" - LETSENCRYPT_HOST: "{{ services.mailu.domain }}" - LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" - volumes: - - "{{ services.mailu.volume_folder }}/certs:/certs" - - "{{ services.mailu.volume_folder }}/overrides/nginx:/overrides:ro" - expose: - - "80" - ports: - - "993:993" - - "25:25" - - "587:587" - - "465:465" - networks: - - default - - external_services - - resolver: - image: ghcr.io/mailu/unbound:{{ services.mailu.version }} - restart: always - env_file: "{{ services.mailu.volume_folder }}/mailu.env" - networks: - default: - ipv4_address: "{{ services.mailu.dns }}" - - admin: - image: ghcr.io/mailu/admin:{{ services.mailu.version }} - restart: always - env_file: "{{ services.mailu.volume_folder }}/mailu.env" - volumes: - - "{{ services.mailu.volume_folder }}/data:/data" - - "{{ services.mailu.volume_folder }}/dkim:/dkim" - depends_on: - - redis - - resolver - dns: - - "{{ services.mailu.dns }}" - - imap: - image: ghcr.io/mailu/dovecot:{{ services.mailu.version }} - restart: always - env_file: "{{ services.mailu.volume_folder }}/mailu.env" - volumes: - - "{{ services.mailu.volume_folder }}/mail:/mail" - - "{{ services.mailu.volume_folder }}/overrides/dovecot:/overrides:ro" - depends_on: - - front - - resolver - dns: - - "{{ services.mailu.dns }}" - - smtp: - image: ghcr.io/mailu/postfix:{{ services.mailu.version }} - restart: always - env_file: "{{ services.mailu.volume_folder }}/mailu.env" - volumes: - - "{{ services.mailu.volume_folder }}/mailqueue:/queue" - - "{{ services.mailu.volume_folder }}/overrides/postfix:/overrides:ro" - depends_on: - - front - - resolver - dns: - - "{{ services.mailu.dns }}" - - antispam: - image: ghcr.io/mailu/rspamd:{{ services.mailu.version }} - hostname: antispam - restart: always - env_file: "{{ services.mailu.volume_folder }}/mailu.env" - volumes: - - "{{ services.mailu.volume_folder }}/filter:/var/lib/rspamd" - - "{{ services.mailu.volume_folder }}/overrides/rspamd:/etc/rspamd/override.d:ro" - depends_on: - - front - - resolver - dns: - - "{{ services.mailu.dns }}" - - webmail: - image: ghcr.io/mailu/rainloop:{{ services.mailu.version }} - restart: always - env_file: "{{ services.mailu.volume_folder }}/mailu.env" - volumes: - - "{{ services.mailu.volume_folder }}/webmail:/data" - - "{{ services.mailu.volume_folder }}/overrides/rainloop:/overrides:ro" - depends_on: - - imap - - resolver - dns: - - "{{ services.mailu.dns }}" - - networks: - default: - driver: bridge - ipam: - driver: default - config: - - subnet: "{{ services.mailu.subnet }}" - external_services: - external: - name: external_services + project_src: "{{ services.mailu.volume_folder }}" + pull: true + state: present diff --git a/roles/docker/tasks/services/mastodon.yml b/roles/docker/tasks/services/mastodon.yml index 1c100cee..95a14c08 100644 --- a/roles/docker/tasks/services/mastodon.yml +++ b/roles/docker/tasks/services/mastodon.yml @@ -32,9 +32,9 @@ - name: Copy mastodon environment file template: src: mastodon/env.j2 - dest: "{{ services.mastodon.volume_folder }}/env_file" + dest: "{{ services.mastodon.volume_folder }}/mastodon.env" -- name: Upload vhost config for root domain +- name: Upload vhost config for Mastodon domain copy: src: vhost/mastodon dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.mastodon.domain }}" @@ -44,164 +44,17 @@ src: mastodon/postgresql.conf dest: "{{ services.mastodon.volume_folder }}/postgres_config/postgresql.conf" -- name: Set up Mastodon +- name: Upload Compose file for Mastodon + template: + src: compose-files/mastodon.yml.j2 + dest: "{{ services.mastodon.volume_folder }}/docker-compose.yml" + +- name: Deploy Mastodon docker_compose: - project_name: mastodon + project_src: "{{ services.mastodon.volume_folder }}" pull: true restarted: true - definition: - x-sidekiq: &sidekiq - image: "tootsuite/mastodon:{{ services.mastodon.version }}" - restart: always - env_file: "{{ services.mastodon.volume_folder }}/env_file" - depends_on: - db: - condition: "service_healthy" - redis: - condition: "service_healthy" - networks: - - postfix - - external_services - - internal_network - volumes: - - "{{ services.mastodon.volume_folder }}/mastodon_data:/mastodon/public/system" - healthcheck: - test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"] - - version: '3' - services: - db: - restart: always - image: "postgres:{{ services.mastodon.postgres_version }}" - shm_size: 256mb - networks: - - internal_network - healthcheck: - test: ['CMD', 'pg_isready', '-U', 'postgres'] - volumes: - - "{{ services.mastodon.volume_folder }}/postgres_data:/var/lib/postgresql/data" - - "{{ services.mastodon.volume_folder }}/postgres_config:/config:ro" - command: postgres -c config_file=/config/postgresql.conf - environment: - - 'POSTGRES_HOST_AUTH_METHOD=trust' - - redis: - restart: always - image: "redis:{{ services.mastodon.redis_version }}" - networks: - - internal_network - healthcheck: - test: ['CMD', 'redis-cli', 'ping'] - volumes: - - "{{ services.mastodon.volume_folder }}/redis_data:/data" - - web: - image: "tootsuite/mastodon:{{ services.mastodon.version }}" - restart: always - env_file: "{{ services.mastodon.volume_folder }}/env_file" - command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000" - networks: - - external_services - - internal_network - healthcheck: - # prettier-ignore - test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:3000/health || exit 1'] - depends_on: - db: - condition: "service_healthy" - redis: - condition: "service_healthy" - volumes: - - "{{ services.mastodon.volume_folder }}/mastodon_data:/mastodon/public/system" - environment: - MAX_THREADS: 10 - WEB_CONCURRENCY: 3 - VIRTUAL_HOST: "{{ services.mastodon.domain }}" - VIRTUAL_PORT: "3000" - VIRTUAL_PATH: "/" - LETSENCRYPT_HOST: "{{ services.mastodon.domain }}" - LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" - - streaming: - image: "tootsuite/mastodon:{{ services.mastodon.version }}" - restart: always - env_file: "{{ services.mastodon.volume_folder }}/env_file" - command: node ./streaming - networks: - - external_services - - internal_network - healthcheck: - # prettier-ignore - test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1'] - ports: - - '127.0.0.1:4000:4000' - depends_on: - db: - condition: "service_healthy" - redis: - condition: "service_healthy" - environment: - DB_POOL: 15 - VIRTUAL_HOST: "{{ services.mastodon.domain }}" - VIRTUAL_PORT: "4000" - VIRTUAL_PATH: "/api/v1/streaming" - - # sidekiq-default-push-pull: DB_POOL = 25, -c 25 for 25 connections - sidekiq-default-push-pull: - <<: *sidekiq - command: bundle exec sidekiq -c 25 -q default -q push -q pull - environment: - DB_POOL: 25 - - # sidekiq-default-pull-push: DB_POOL = 25, -c 25 for 25 connections - sidekiq-default-pull-push: - <<: *sidekiq - command: bundle exec sidekiq -c 25 -q default -q pull -q push - environment: - DB_POOL: 25 - - # sidekiq-pull-default-push: DB_POOL = 25, -c 25 for 25 connections - sidekiq-pull-default-push: - <<: *sidekiq - command: bundle exec sidekiq -c 25 -q pull -q default -q push - environment: - DB_POOL: 25 - - # sidekiq-push-default-pull: DB_POOL = 25, -c 25 for 25 connections - sidekiq-push-default-pull: - <<: *sidekiq - command: bundle exec sidekiq -c 25 -q push -q default -q pull - environment: - DB_POOL: 25 - - # sidekiq-push-scheduler: DB_POOL = 5, -c 5 for 5 connections - sidekiq-push-scheduler: - <<: *sidekiq - command: bundle exec sidekiq -c 5 -q push -q scheduler - environment: - DB_POOL: 5 - - # sidekiq-push-mailers: DB_POOL = 5, -c 5 for 5 connections - sidekiq-push-mailers: - <<: *sidekiq - command: bundle exec sidekiq -c 5 -q push -q mailers - environment: - DB_POOL: 5 - - # sidekiq-push-ingress: DB_POOL = 10, -c 10 for 10 connections - sidekiq-push-ingress: - <<: *sidekiq - command: bundle exec sidekiq -c 10 -q push -q ingress - environment: - DB_POOL: 10 - - networks: - external_services: - external: true - postfix: - external: true - internal_network: - internal: true + state: present - name: Configure cron job to remove old Mastodon media daily cron: diff --git a/roles/docker/tasks/services/matrix_element.yml b/roles/docker/tasks/services/matrix_element.yml index b5a04b0d..605084b3 100644 --- a/roles/docker/tasks/services/matrix_element.yml +++ b/roles/docker/tasks/services/matrix_element.yml @@ -58,63 +58,13 @@ src: matrix/log.config dest: "{{ services.matrix.volume_folder }}/data/matrix.data.coop.log.config" -- name: Set up Matrix and Element +- name: Upload Compose file for Matrix and Element + template: + src: compose-files/matrix_element.yml.j2 + dest: "{{ services.matrix.volume_folder }}/docker-compose.yml" + +- name: Deploy Matrix and Element docker_compose: - project_name: matrix + project_src: "{{ services.matrix.volume_folder }}" pull: true - definition: - version: "3.6" - services: - postgres: - image: "postgres:{{ services.matrix.postgres_version }}" - restart: unless-stopped - networks: - - matrix - volumes: - - "{{ services.matrix.volume_folder }}/db:/var/lib/postgresql/data" - environment: - POSTGRES_USER: "synapse" - POSTGRES_PASSWORD: "{{ postgres_passwords.matrix }}" - - synapse: - image: "matrixdotorg/synapse:{{ services.matrix.version }}" - restart: unless-stopped - networks: - - matrix - - external_services - - postfix - volumes: - - "{{ services.matrix.volume_folder }}/data:/data" - environment: - SYNAPSE_CONFIG_PATH: "/data/homeserver.yaml" - SYNAPSE_CACHE_FACTOR: "2" - SYNAPSE_LOG_LEVEL: "INFO" - VIRTUAL_HOST: "{{ services.matrix.domain }}" - VIRTUAL_PORT: "8008" - LETSENCRYPT_HOST: "{{ services.matrix.domain }}" - LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" - - element: - image: "avhost/docker-matrix-element:{{ services.element.version }}" - restart: unless-stopped - networks: - - matrix - - external_services - expose: - - 8080 - volumes: - - "{{ services.element.volume_folder }}/data:/data" - environment: - VIRTUAL_HOST: "{{ services.element.domains | join(',') }}" - VIRTUAL_PORT: "8080" - LETSENCRYPT_HOST: "{{ services.element.domains | join(',') }}" - LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" - - networks: - external_services: - external: - name: external_services - postfix: - external: true - matrix: - name: "matrix" + state: present diff --git a/roles/docker/tasks/services/membersystem.yml b/roles/docker/tasks/services/membersystem.yml index d310554b..ba9135e8 100644 --- a/roles/docker/tasks/services/membersystem.yml +++ b/roles/docker/tasks/services/membersystem.yml @@ -1,52 +1,12 @@ # vim: ft=yaml.ansible --- -- name: run membersystem containers +- name: Upload Compose file for Membersystem + template: + src: compose-files/membersystem.yml.j2 + dest: "{{ services.membersystem.volume_folder }}/docker-compose.yml" + +- name: Deploy Membersystem docker_compose: - project_name: "member.data.coop" - pull: yes - definition: - version: "3" - services: - backend: - image: "docker.data.coop/membersystem:{{ services.membersystem.version }}" - restart: always - user: $UID:$GID - tty: true - depends_on: - - postgres - networks: - - membersystem - - external_services - - postfix - environment: - SECRET_KEY: "{{ membersystem_secrets.secret_key }}" - DATABASE_URL: postgres://postgres:{{ postgres_passwords.membersystem }}@postgres:5432/postgres - POSTGRES_HOST: postgres - POSTGRES_PORT: 5432 - EMAIL_BACKEND: "django.core.mail.backends.smtp.EmailBackend" - EMAIL_URL: "smtp://noop@{{ smtp_host }}:{{ smtp_port }}" - VIRTUAL_HOST: "{{ services.membersystem.domain }}" - VIRTUAL_PORT: "8000" - LETSENCRYPT_HOST: "{{ services.membersystem.domain }}" - LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" - ALLOWED_HOSTS: "{{ services.membersystem.domain }}" - CSRF_TRUSTED_ORIGINS: "https://{{ services.membersystem.domain }}" - DJANGO_ADMINS: "{{ services.membersystem.django_admins }}" - DEFAULT_FROM_EMAIL: "noreply@{{ services.membersystem.domain }}" - - postgres: - image: "postgres:{{ services.membersystem.postgres_version }}" - restart: always - volumes: - - "{{ volume_root_folder }}/membersystem/postgres/data:/var/lib/postgresql/data" - networks: - - membersystem - environment: - POSTGRES_PASSWORD: "{{ postgres_passwords.membersystem }}" - - networks: - membersystem: - external_services: - external: true - postfix: - external: true + project_src: "{{ services.membersystem.volume_folder }}" + pull: true + state: present diff --git a/roles/docker/tasks/services/nextcloud.yml b/roles/docker/tasks/services/nextcloud.yml index f1d19b0b..acfa587c 100644 --- a/roles/docker/tasks/services/nextcloud.yml +++ b/roles/docker/tasks/services/nextcloud.yml @@ -6,71 +6,13 @@ dest: "{{ services.nginx_proxy.volume_folder }}/vhost/{{ services.nextcloud.domain }}" notify: "restart nginx" -- name: setup nextcloud containers +- name: Upload Compose file for Nextcloud + template: + src: compose-files/nextcloud.yml.j2 + dest: "{{ services.nextcloud.volume_folder }}/docker-compose.yml" + +- name: Deploy Nextcloud docker_compose: - project_name: "nextcloud" - pull: "yes" - definition: - services: - postgres: - image: "postgres:{{ services.nextcloud.postgres_version }}" - restart: "unless-stopped" - networks: - - "nextcloud" - volumes: - - "{{ services.nextcloud.volume_folder }}/postgres:/var/lib/postgresql/data" - environment: - POSTGRES_DB: "nextcloud" - POSTGRES_PASSWORD: "{{ postgres_passwords.nextcloud }}" - POSTGRES_USER: "nextcloud" - - redis: - image: "redis:{{ services.nextcloud.redis_version }}" - restart: "unless-stopped" - command: "redis-server --requirepass {{ nextcloud_secrets.redis_password }}" - tmpfs: - - /var/lib/redis - networks: - - "nextcloud" - - cron: - image: "nextcloud:{{ services.nextcloud.version }}" - restart: "unless-stopped" - entrypoint: "/cron.sh" - networks: - - "nextcloud" - volumes: - - "{{ services.nextcloud.volume_folder }}/app:/var/www/html" - depends_on: - - "postgres" - - "redis" - - app: - image: "nextcloud:{{ services.nextcloud.version }}" - restart: "unless-stopped" - networks: - - "nextcloud" - - "postfix" - - "external_services" - volumes: - - "{{ services.nextcloud.volume_folder }}/app:/var/www/html" - environment: - VIRTUAL_HOST: "{{ services.nextcloud.domain }}" - LETSENCRYPT_HOST: "{{ services.nextcloud.domain }}" - LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" - POSTGRES_HOST: "postgres" - POSTGRES_DB: "nextcloud" - POSTGRES_USER: "nextcloud" - POSTGRES_PASSWORD: "{{ postgres_passwords.nextcloud }}" - REDIS_HOST: "redis" - REDIS_HOST_PASSWORD: "{{ nextcloud_secrets.redis_password }}" - depends_on: - - "postgres" - - "redis" - - networks: - nextcloud: - postfix: - external: true - external_services: - external: true + project_src: "{{ services.nextcloud.volume_folder }}" + pull: true + state: present diff --git a/roles/docker/tasks/services/passit.yml b/roles/docker/tasks/services/passit.yml index 58e87a6b..eaf5baad 100644 --- a/roles/docker/tasks/services/passit.yml +++ b/roles/docker/tasks/services/passit.yml @@ -7,47 +7,13 @@ group: root state: directory -- name: setup passit containers +- name: Upload Compose file for Passit + template: + src: compose-files/passit.yml.j2 + dest: "{{ services.passit.volume_folder }}/docker-compose.yml" + +- name: Deploy Passit docker_compose: - project_name: "passit" - pull: "yes" - definition: - version: "3.6" - services: - passit_db: - image: "postgres:{{ services.passit.postgres_version }}" - restart: "always" - networks: - - "passit" - volumes: - - "{{ services.passit.volume_folder }}/data:/var/lib/postgresql/data" - environment: - POSTGRES_USER: "passit" - POSTGRES_PASSWORD: "{{ postgres_passwords.passit }}" - - passit_app: - image: "passit/passit:{{ services.passit.version }}" - command: "bin/start.sh" - restart: "always" - networks: - - "passit" - - "postfix" - - "external_services" - environment: - DATABASE_URL: "postgres://passit:{{ postgres_passwords.passit }}@passit_db:5432/passit" - SECRET_KEY: "{{ passit_secret_key }}" - IS_DEBUG: 'False' - EMAIL_URL: "smtp://noop@{{ smtp_host }}:{{ smtp_port }}" - DEFAULT_FROM_EMAIL: "noreply@{{ services.passit.domain }}" - EMAIL_CONFIRMATION_HOST: "https://{{ services.passit.domain }}" - FIDO_SERVER_ID: "{{ services.passit.domain }}" - VIRTUAL_HOST: "{{ services.passit.domain }}" - LETSENCRYPT_HOST: "{{ services.passit.domain }}" - LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" - - networks: - passit: - postfix: - external: true - external_services: - external: true + project_src: "{{ services.passit.volume_folder }}" + pull: true + state: present diff --git a/roles/docker/tasks/services/rallly.yml b/roles/docker/tasks/services/rallly.yml index 400073f9..e5f2b27b 100644 --- a/roles/docker/tasks/services/rallly.yml +++ b/roles/docker/tasks/services/rallly.yml @@ -8,54 +8,15 @@ - name: Copy Rallly environment file template: src: rallly/env.j2 - dest: "{{ services.rallly.volume_folder }}/env_file" + dest: "{{ services.rallly.volume_folder }}/rallly.env" -- name: Set up Rallly +- name: Upload Compose file for Rallly + template: + src: compose-files/rallly.yml.j2 + dest: "{{ services.rallly.volume_folder }}/docker-compose.yml" + +- name: Deploy Rallly docker_compose: - project_name: "rallly" - pull: "yes" - definition: - version: "3.8" - services: - rallly_db: - image: "postgres:{{ services.rallly.postgres_version }}" - restart: "always" - shm_size: "256mb" - networks: - rallly_internal: - volumes: - - "{{ services.rallly.volume_folder }}/postgres:/var/lib/postgresql/data" - environment: - POSTGRES_PASSWORD: "{{ postgres_passwords.rallly }}" - POSTGRES_DB: "rallly_db" - healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] - interval: 5s - timeout: 5s - retries: 5 - - rallly: - image: "lukevella/rallly:{{ services.rallly.version }}" - restart: "always" - networks: - rallly_internal: - external_services: - postfix: - depends_on: - rallly_db: - condition: "service_healthy" - env_file: - - "{{ services.rallly.volume_folder }}/env_file" - environment: - VIRTUAL_HOST: "{{ services.rallly.domain }}" - VIRTUAL_PORT: "3000" - LETSENCRYPT_HOST: "{{ services.rallly.domain }}" - LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" - - networks: - rallly_internal: - internal: true - external_services: - external: true - postfix: - external: true + project_src: "{{ services.rallly.volume_folder }}" + pull: true + state: present diff --git a/roles/docker/tasks/services/restic.yml b/roles/docker/tasks/services/restic.yml new file mode 100644 index 00000000..c838e265 --- /dev/null +++ b/roles/docker/tasks/services/restic.yml @@ -0,0 +1,59 @@ +# vim: ft=yaml.ansible +--- +- name: Create SSH directory + file: + path: "{{ services.restic.volume_folder }}/ssh" + owner: root + group: root + mode: '0755' + state: directory + +- name: Copy private SSH key + copy: + dest: "{{ services.restic.volume_folder }}/ssh/id_ed25519" + owner: root + group: root + mode: '0600' + content: "{{ restic_secrets.ssh_privkey }}" + +- name: Derive public SSH key + shell: >- + ssh-keygen -f {{ services.restic.volume_folder }}/ssh/id_ed25519 -y + > {{ services.restic.volume_folder }}/ssh/id_ed25519.pub + args: + creates: "{{ services.restic.volume_folder }}/ssh/id_ed25519.pub" + +- name: Set file permissions on public SSH key + file: + path: "{{ services.restic.volume_folder }}/ssh/id_ed25519.pub" + owner: root + group: root + mode: '0644' + state: touch + +- name: Create SSH config + template: + src: restic/ssh.config.j2 + dest: "{{ services.restic.volume_folder }}/ssh/config" + owner: root + group: root + mode: '0600' + +- name: Create SSH known_hosts file + template: + src: restic/ssh.known_hosts.j2 + dest: "{{ services.restic.volume_folder }}/ssh/known_hosts" + owner: root + group: root + mode: '0600' + +- name: Upload Compose file for Restic + template: + src: compose-files/restic.yml.j2 + dest: "{{ services.restic.volume_folder }}/docker-compose.yml" + +- name: Deploy Restic + docker_compose: + project_src: "{{ services.restic.volume_folder }}" + pull: true + state: present diff --git a/roles/docker/tasks/services/restic_backup.yml b/roles/docker/tasks/services/restic_backup.yml deleted file mode 100644 index df0c278d..00000000 --- a/roles/docker/tasks/services/restic_backup.yml +++ /dev/null @@ -1,89 +0,0 @@ -# vim: ft=yaml.ansible ---- -- name: Create SSH directory - file: - path: "{{ services.restic.volume_folder }}/ssh" - owner: root - group: root - mode: '0755' - state: directory - -- name: Copy private SSH key - copy: - dest: "{{ services.restic.volume_folder }}/ssh/id_ed25519" - owner: root - group: root - mode: '0600' - content: "{{ restic_secrets.ssh_privkey }}" - -- name: Derive public SSH key - shell: >- - ssh-keygen -f {{ services.restic.volume_folder }}/ssh/id_ed25519 -y - > {{ services.restic.volume_folder }}/ssh/id_ed25519.pub - args: - creates: "{{ services.restic.volume_folder }}/ssh/id_ed25519.pub" - -- name: Set file permissions on public SSH key - file: - path: "{{ services.restic.volume_folder }}/ssh/id_ed25519.pub" - owner: root - group: root - mode: '0644' - state: touch - -- name: Create SSH config - template: - src: restic/ssh.config.j2 - dest: "{{ services.restic.volume_folder }}/ssh/config" - owner: root - group: root - mode: '0600' - -- name: Create SSH known_hosts file - template: - src: restic/ssh.known_hosts.j2 - dest: "{{ services.restic.volume_folder }}/ssh/known_hosts" - owner: root - group: root - mode: '0600' - -- name: Setup restic backup - docker_compose: - project_name: restic - pull: true - definition: - version: '3.6' - services: - backup: - image: mazzolino/restic:{{ services.restic.version }} - restart: always - environment: - RUN_ON_STARTUP: "false" - BACKUP_CRON: "0 30 3 * * *" - RESTIC_REPOSITORY: "sftp:{{ services.restic.user }}@{{ services.restic.domain }}:{{ services.restic.repository }}" - RESTIC_PASSWORD: "{{ restic_secrets.repository_password }}" - RESTIC_BACKUP_SOURCES: "/mnt/volumes" - RESTIC_BACKUP_ARGS: >- - --tag datacoop-volumes - --exclude '*.tmp' - --verbose - RESTIC_FORGET_ARGS: >- - --keep-last 10 - --keep-daily 7 - --keep-weekly 5 - --keep-monthly 12 - TZ: Europe/Copenhagen - volumes: - - "{{ services.restic.volume_folder }}/ssh:/run/secrets/.ssh:ro" - - /docker-volumes:/mnt/volumes:ro - - prune: - image: "mazzolino/restic:{{ services.restic.version }}" - environment: - RUN_ON_STARTUP: "false" - PRUNE_CRON: "0 0 4 * * *" - RESTIC_REPOSITORY: "sftp:{{ services.restic.user }}@{{ services.restic.domain }}:{{ services.restic.repository }}" - RESTIC_PASSWORD: "{{ restic_secrets.repository_password }}" - TZ: Europe/copenhagen - volumes: - - "{{ services.restic.volume_folder }}/ssh:/run/secrets/.ssh:ro" diff --git a/roles/docker/templates/compose-files/drone.yml.j2 b/roles/docker/templates/compose-files/drone.yml.j2 new file mode 100644 index 00000000..d62eb4b1 --- /dev/null +++ b/roles/docker/templates/compose-files/drone.yml.j2 @@ -0,0 +1,40 @@ +# vim: ft=yaml.docker-compose +version: "3.8" + +services: + drone: + image: drone/drone:{{ services.drone.version }} + restart: unless-stopped + networks: + - default + - external_services + volumes: + - ".:/data" + - "/var/run/docker.sock:/var/run/docker.sock" + environment: + DRONE_GITEA_SERVER: https://{{ services.forgejo.domain }} + DRONE_GITEA_CLIENT_ID: "{{ drone_secrets.oauth_client_id }}" + DRONE_GITEA_CLIENT_SECRET: "{{ drone_secrets.oauth_client_secret }}" + DRONE_GIT_ALWAYS_AUTH: true + DRONE_SERVER_HOST: "{{ services.drone.domain }}" + DRONE_SERVER_PROTO: https + DRONE_RPC_SECRET: "{{ drone_secrets.rpc_shared_secret }}" + VIRTUAL_HOST: "{{ services.drone.domain }}" + LETSENCRYPT_HOST: "{{ services.drone.domain }}" + LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" + + runner: + image: drone/drone-runner-docker:{{ services.drone.version }} + restart: unless-stopped + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + environment: + DRONE_RPC_HOST: "{{ services.drone.domain }}" + DRONE_RPC_PROTO: https + DRONE_RPC_SECRET: "{{ drone_secrets.rpc_shared_secret }}" + DRONE_RUNNER_CAPACITY: 2 + DRONE_RUNNER_NAME: data.coop_drone_runner + +networks: + external_services: + external: true diff --git a/roles/docker/templates/compose-files/hedgedoc.yml.j2 b/roles/docker/templates/compose-files/hedgedoc.yml.j2 new file mode 100644 index 00000000..b361116c --- /dev/null +++ b/roles/docker/templates/compose-files/hedgedoc.yml.j2 @@ -0,0 +1,44 @@ +# vim: ft=yaml.docker-compose +version: "3.8" + +services: + db: + image: postgres:{{ services.hedgedoc.postgres_version }} + restart: unless-stopped + volumes: + - "./db:/var/lib/postgresql/data" + environment: + POSTGRES_USER: codimd + POSTGRES_PASSWORD: "{{ postgres_passwords.hedgedoc }}" + POSTGRES_DB: codimd + + app: + image: quay.io/hedgedoc/hedgedoc:{{ services.hedgedoc.version }} + volumes: + - "./hedgedoc/uploads:/hedgedoc/public/uploads" + - "./sso.data.coop.pem:/sso.data.coop.pem" + restart: unless-stopped + networks: + - default + - external_services + environment: + CMD_DB_URL: postgres://codimd:{{ postgres_passwords.hedgedoc }}@db:5432/codimd + CMD_DOMAIN: "{{ services.hedgedoc.domain }}" + CMD_ALLOW_EMAIL_REGISTER: False + CMD_IMAGE_UPLOAD_TYPE: filesystem + CMD_EMAIL: False + CMD_SAML_IDPCERT: /sso.data.coop.pem + CMD_SAML_IDPSSOURL: https://{{ services.keycloak.domain }}/auth/realms/datacoop/protocol/saml + CMD_SAML_ISSUER: hedgedoc + CMD_SAML_IDENTIFIERFORMAT: urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified + CMD_USECDN: false + CMD_PROTOCOL_USESSL: true + VIRTUAL_HOST: "{{ services.hedgedoc.domain }}" + LETSENCRYPT_HOST: "{{ services.hedgedoc.domain }}" + LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" + depends_on: + - db + +networks: + external_services: + external: true diff --git a/roles/docker/templates/compose-files/keycloak.yml.j2 b/roles/docker/templates/compose-files/keycloak.yml.j2 new file mode 100644 index 00000000..43c5bb9f --- /dev/null +++ b/roles/docker/templates/compose-files/keycloak.yml.j2 @@ -0,0 +1,42 @@ +# vim: ft=yaml.docker-compose +version: "3.8" + +services: + db: + image: postgres:{{ services.keycloak.postgres_version }} + restart: unless-stopped + volumes: + - "./data:/var/lib/postgresql/data" + environment: + POSTGRES_USER: keycloak + POSTGRES_PASSWORD: "{{ postgres_passwords.keycloak }}" + POSTGRES_DB: keycloak + + app: + image: quay.io/keycloak/keycloak:{{ services.keycloak.version }} + restart: unless-stopped + networks: + - default + - postfix + - external_services + command: + - "start" + - "--db=postgres" + - "--db-url=jdbc:postgresql://db:5432/keycloak" + - "--db-username=keycloak" + - "--db-password={{ postgres_passwords.keycloak }}" + - "--hostname={{ services.keycloak.domain }}" + - "--proxy=edge" + - "--https-port=8080" + - "--http-relative-path=/auth" + environment: + VIRTUAL_HOST: "{{ services.keycloak.domain }}" + VIRTUAL_PORT: "8080" + LETSENCRYPT_HOST: "{{ services.keycloak.domain }}" + LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" + +networks: + postfix: + external: true + external_services: + external: true diff --git a/roles/docker/templates/compose-files/mailu.yml.j2 b/roles/docker/templates/compose-files/mailu.yml.j2 new file mode 100644 index 00000000..eddc18a9 --- /dev/null +++ b/roles/docker/templates/compose-files/mailu.yml.j2 @@ -0,0 +1,131 @@ +# vim: ft=yaml.docker-compose +version: '3.6' + +services: + postgres: + image: postgres:14-alpine + restart: always + environment: + POSTGRES_DB: mailu + POSTGRES_USER: mailu + POSTGRES_PASSWORD: "{{ postgres_passwords.mailu }}" + volumes: + - "./postgres:/var/lib/postgresql/data" + dns: + - "{{ services.mailu.dns }}" + + redis: + image: redis:alpine + restart: always + volumes: + - "./redis:/data" + depends_on: + - resolver + dns: + - "{{ services.mailu.dns }}" + + front: + image: ghcr.io/mailu/nginx:{{ services.mailu.version }} + restart: always + env_file: mailu.env + environment: + VIRTUAL_HOST: "{{ services.mailu.domain }}" + LETSENCRYPT_HOST: "{{ services.mailu.domain }}" + LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" + volumes: + - "./certs:/certs" + - "./overrides/nginx:/overrides:ro" + expose: + - "80" + ports: + - "993:993" + - "25:25" + - "587:587" + - "465:465" + networks: + - default + - external_services + + resolver: + image: ghcr.io/mailu/unbound:{{ services.mailu.version }} + restart: always + env_file: mailu.env + networks: + default: + ipv4_address: "{{ services.mailu.dns }}" + + admin: + image: ghcr.io/mailu/admin:{{ services.mailu.version }} + restart: always + env_file: "{{ services.mailu.volume_folder }}/mailu.env" + volumes: + - "./data:/data" + - "./dkim:/dkim" + depends_on: + - redis + - resolver + dns: + - "{{ services.mailu.dns }}" + + imap: + image: ghcr.io/mailu/dovecot:{{ services.mailu.version }} + restart: always + env_file: mailu.env + volumes: + - "./mail:/mail" + - "./overrides/dovecot:/overrides:ro" + depends_on: + - front + - resolver + dns: + - "{{ services.mailu.dns }}" + + smtp: + image: ghcr.io/mailu/postfix:{{ services.mailu.version }} + restart: always + env_file: mailu.env + volumes: + - "./mailqueue:/queue" + - "./overrides/postfix:/overrides:ro" + depends_on: + - front + - resolver + dns: + - "{{ services.mailu.dns }}" + + antispam: + image: ghcr.io/mailu/rspamd:{{ services.mailu.version }} + hostname: antispam + restart: always + env_file: mailu.env + volumes: + - "./filter:/var/lib/rspamd" + - "./overrides/rspamd:/etc/rspamd/override.d:ro" + depends_on: + - front + - resolver + dns: + - "{{ services.mailu.dns }}" + + webmail: + image: ghcr.io/mailu/rainloop:{{ services.mailu.version }} + restart: always + env_file: mailu.env + volumes: + - "./webmail:/data" + - "./overrides/rainloop:/overrides:ro" + depends_on: + - imap + - resolver + dns: + - "{{ services.mailu.dns }}" + +networks: + default: + driver: bridge + ipam: + driver: default + config: + - subnet: "{{ services.mailu.subnet }}" + external_services: + external: true diff --git a/roles/docker/templates/compose-files/mastodon.yml.j2 b/roles/docker/templates/compose-files/mastodon.yml.j2 new file mode 100644 index 00000000..2fcec433 --- /dev/null +++ b/roles/docker/templates/compose-files/mastodon.yml.j2 @@ -0,0 +1,146 @@ +# vim: ft=yaml.docker-compose +x-sidekiq: &sidekiq + image: tootsuite/mastodon:{{ services.mastodon.version }} + restart: always + env_file: mastodon.env + networks: + - default + - postfix + - external_services + volumes: + - "./mastodon_data:/mastodon/public/system" + healthcheck: + test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"] + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + +version: "3.8" + +services: + db: + restart: always + image: postgres:{{ services.mastodon.postgres_version }} + shm_size: 256mb + volumes: + - "./postgres_data:/var/lib/postgresql/data" + - "./postgres_config:/config:ro" + command: postgres -c config_file=/config/postgresql.conf + environment: + POSTGRES_HOST_AUTH_METHOD: trust + healthcheck: + test: ['CMD', 'pg_isready', '-U', 'postgres'] + + redis: + restart: always + image: redis:{{ services.mastodon.redis_version }} + volumes: + - "./redis_data:/data" + healthcheck: + test: ['CMD', 'redis-cli', 'ping'] + + web: + image: tootsuite/mastodon:{{ services.mastodon.version }} + restart: always + env_file: mastodon.env + command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000" + networks: + - default + - external_services + volumes: + - "./mastodon_data:/mastodon/public/system" + environment: + MAX_THREADS: 10 + WEB_CONCURRENCY: 3 + VIRTUAL_HOST: "{{ services.mastodon.domain }}" + VIRTUAL_PORT: "3000" + VIRTUAL_PATH: / + LETSENCRYPT_HOST: "{{ services.mastodon.domain }}" + LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" + healthcheck: + test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:3000/health || exit 1'] + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + + streaming: + image: tootsuite/mastodon:{{ services.mastodon.version }} + restart: always + env_file: mastodon.env + command: node ./streaming + networks: + - default + - external_services + ports: + - "127.0.0.1:4000:4000" + environment: + DB_POOL: 15 + VIRTUAL_HOST: "{{ services.mastodon.domain }}" + VIRTUAL_PORT: "4000" + VIRTUAL_PATH: "/api/v1/streaming" + healthcheck: + test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1'] + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + + # sidekiq-default-push-pull: DB_POOL = 25, -c 25 for 25 connections + sidekiq-default-push-pull: + <<: *sidekiq + command: bundle exec sidekiq -c 25 -q default -q push -q pull + environment: + DB_POOL: 25 + + # sidekiq-default-pull-push: DB_POOL = 25, -c 25 for 25 connections + sidekiq-default-pull-push: + <<: *sidekiq + command: bundle exec sidekiq -c 25 -q default -q pull -q push + environment: + DB_POOL: 25 + + # sidekiq-pull-default-push: DB_POOL = 25, -c 25 for 25 connections + sidekiq-pull-default-push: + <<: *sidekiq + command: bundle exec sidekiq -c 25 -q pull -q default -q push + environment: + DB_POOL: 25 + + # sidekiq-push-default-pull: DB_POOL = 25, -c 25 for 25 connections + sidekiq-push-default-pull: + <<: *sidekiq + command: bundle exec sidekiq -c 25 -q push -q default -q pull + environment: + DB_POOL: 25 + + # sidekiq-push-scheduler: DB_POOL = 5, -c 5 for 5 connections + sidekiq-push-scheduler: + <<: *sidekiq + command: bundle exec sidekiq -c 5 -q push -q scheduler + environment: + DB_POOL: 5 + + # sidekiq-push-mailers: DB_POOL = 5, -c 5 for 5 connections + sidekiq-push-mailers: + <<: *sidekiq + command: bundle exec sidekiq -c 5 -q push -q mailers + environment: + DB_POOL: 5 + + # sidekiq-push-ingress: DB_POOL = 10, -c 10 for 10 connections + sidekiq-push-ingress: + <<: *sidekiq + command: bundle exec sidekiq -c 10 -q push -q ingress + environment: + DB_POOL: 10 + +networks: + external_services: + external: true + postfix: + external: true diff --git a/roles/docker/templates/compose-files/matrix_element.yml.j2 b/roles/docker/templates/compose-files/matrix_element.yml.j2 new file mode 100644 index 00000000..f787e61f --- /dev/null +++ b/roles/docker/templates/compose-files/matrix_element.yml.j2 @@ -0,0 +1,52 @@ +# vim: ft=yaml.docker-compose +version: "3.8" + +services: + postgres: + image: postgres:{{ services.matrix.postgres_version }} + restart: unless-stopped + volumes: + - "./db:/var/lib/postgresql/data" + environment: + POSTGRES_USER: synapse + POSTGRES_PASSWORD: "{{ postgres_passwords.matrix }}" + + synapse: + image: matrixdotorg/synapse:{{ services.matrix.version }} + restart: unless-stopped + networks: + - default + - external_services + - postfix + volumes: + - "./data:/data" + environment: + SYNAPSE_CONFIG_PATH: /data/homeserver.yaml + SYNAPSE_CACHE_FACTOR: "2" + SYNAPSE_LOG_LEVEL: INFO + VIRTUAL_HOST: "{{ services.matrix.domain }}" + VIRTUAL_PORT: "8008" + LETSENCRYPT_HOST: "{{ services.matrix.domain }}" + LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" + + element: + image: avhost/docker-matrix-element:{{ services.element.version }} + restart: unless-stopped + networks: + - default + - external_services + expose: + - "8080" + volumes: + - "{{ services.element.volume_folder }}/data:/data" + environment: + VIRTUAL_HOST: "{{ services.element.domains | join(',') }}" + VIRTUAL_PORT: "8080" + LETSENCRYPT_HOST: "{{ services.element.domains | join(',') }}" + LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" + +networks: + external_services: + external: true + postfix: + external: true diff --git a/roles/docker/templates/compose-files/membersystem.yml.j2 b/roles/docker/templates/compose-files/membersystem.yml.j2 new file mode 100644 index 00000000..fae37672 --- /dev/null +++ b/roles/docker/templates/compose-files/membersystem.yml.j2 @@ -0,0 +1,44 @@ +# vim: ft=yaml.docker-compose +version: "3.8" + +services: + app: + image: docker.data.coop/membersystem:{{ services.membersystem.version }} + restart: always + user: "$UID:$GID" + tty: true + networks: + - default + - external_services + - postfix + environment: + SECRET_KEY: "{{ membersystem_secrets.secret_key }}" + DATABASE_URL: postgres://postgres:{{ postgres_passwords.membersystem }}@postgres:5432/postgres + POSTGRES_HOST: postgres + POSTGRES_PORT: 5432 + EMAIL_BACKEND: django.core.mail.backends.smtp.EmailBackend + EMAIL_URL: smtp://noop@{{ smtp_host }}:{{ smtp_port }} + VIRTUAL_HOST: "{{ services.membersystem.domain }}" + VIRTUAL_PORT: "8000" + LETSENCRYPT_HOST: "{{ services.membersystem.domain }}" + LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" + ALLOWED_HOSTS: "{{ services.membersystem.domain }}" + CSRF_TRUSTED_ORIGINS: https://{{ services.membersystem.domain }} + DJANGO_ADMINS: "{{ services.membersystem.django_admins }}" + DEFAULT_FROM_EMAIL: noreply@{{ services.membersystem.domain }} + depends_on: + - postgres + + postgres: + image: postgres:{{ services.membersystem.postgres_version }} + restart: always + volumes: + - "./postgres/data:/var/lib/postgresql/data" + environment: + POSTGRES_PASSWORD: "{{ postgres_passwords.membersystem }}" + +networks: + external_services: + external: true + postfix: + external: true diff --git a/roles/docker/templates/compose-files/nextcloud.yml.j2 b/roles/docker/templates/compose-files/nextcloud.yml.j2 new file mode 100644 index 00000000..b95c55dd --- /dev/null +++ b/roles/docker/templates/compose-files/nextcloud.yml.j2 @@ -0,0 +1,59 @@ +# vim: ft=yaml.docker-compose +version: "3.8" + +services: + postgres: + image: postgres:{{ services.nextcloud.postgres_version }} + restart: unless-stopped + volumes: + - "./postgres:/var/lib/postgresql/data" + environment: + POSTGRES_DB: nextcloud + POSTGRES_PASSWORD: "{{ postgres_passwords.nextcloud }}" + POSTGRES_USER: nextcloud + + redis: + image: redis:{{ services.nextcloud.redis_version }} + restart: unless-stopped + command: redis-server --requirepass {{ nextcloud_secrets.redis_password }} + tmpfs: + - /var/lib/redis + + cron: + image: nextcloud:{{ services.nextcloud.version }} + restart: unless-stopped + entrypoint: /cron.sh + volumes: + - "./app:/var/www/html" + depends_on: + - postgres + - redis + + app: + image: nextcloud:{{ services.nextcloud.version }} + restart: unless-stopped + networks: + - default + - postfix + - external_services + volumes: + - "./app:/var/www/html" + environment: + VIRTUAL_HOST: "{{ services.nextcloud.domain }}" + LETSENCRYPT_HOST: "{{ services.nextcloud.domain }}" + LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" + POSTGRES_HOST: postgres + POSTGRES_DB: nextcloud + POSTGRES_USER: nextcloud + POSTGRES_PASSWORD: "{{ postgres_passwords.nextcloud }}" + REDIS_HOST: redis + REDIS_HOST_PASSWORD: "{{ nextcloud_secrets.redis_password }}" + depends_on: + - postgres + - redis + +networks: + postfix: + external: true + external_services: + external: true diff --git a/roles/docker/templates/compose-files/passit.yml.j2 b/roles/docker/templates/compose-files/passit.yml.j2 new file mode 100644 index 00000000..810d76e3 --- /dev/null +++ b/roles/docker/templates/compose-files/passit.yml.j2 @@ -0,0 +1,38 @@ +# vim: ft=yaml.docker-compose +version: "3.8" + +services: + db: + image: postgres:{{ services.passit.postgres_version }} + restart: always + volumes: + - "./data:/var/lib/postgresql/data" + environment: + POSTGRES_USER: passit + POSTGRES_PASSWORD: "{{ postgres_passwords.passit }}" + + app: + image: passit/passit:{{ services.passit.version }} + command: bin/start.sh + restart: always + networks: + - default + - postfix + - external_services + environment: + DATABASE_URL: postgres://passit:{{ postgres_passwords.passit }}@db:5432/passit + SECRET_KEY: "{{ passit_secret_key }}" + IS_DEBUG: "False" + EMAIL_URL: smtp://noop@{{ smtp_host }}:{{ smtp_port }} + DEFAULT_FROM_EMAIL: noreply@{{ services.passit.domain }} + EMAIL_CONFIRMATION_HOST: https://{{ services.passit.domain }} + FIDO_SERVER_ID: "{{ services.passit.domain }}" + VIRTUAL_HOST: "{{ services.passit.domain }}" + LETSENCRYPT_HOST: "{{ services.passit.domain }}" + LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" + +networks: + postfix: + external: true + external_services: + external: true diff --git a/roles/docker/templates/compose-files/rallly.yml.j2 b/roles/docker/templates/compose-files/rallly.yml.j2 new file mode 100644 index 00000000..f8cf987c --- /dev/null +++ b/roles/docker/templates/compose-files/rallly.yml.j2 @@ -0,0 +1,41 @@ +# vim: ft=yaml.docker-compose +version: "3.8" + +services: + db: + image: postgres:{{ services.rallly.postgres_version }} + restart: always + shm_size: 256mb + volumes: + - "./postgres:/var/lib/postgresql/data" + environment: + POSTGRES_PASSWORD: "{{ postgres_passwords.rallly }}" + POSTGRES_DB: rallly_db + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 5s + timeout: 5s + retries: 5 + + rallly: + image: lukevella/rallly:{{ services.rallly.version }} + restart: always + networks: + - default + - external_services + - postfix + depends_on: + db: + condition: service_healthy + env_file: rallly.env + environment: + VIRTUAL_HOST: "{{ services.rallly.domain }}" + VIRTUAL_PORT: "3000" + LETSENCRYPT_HOST: "{{ services.rallly.domain }}" + LETSENCRYPT_EMAIL: "{{ letsencrypt_email }}" + +networks: + external_services: + external: true + postfix: + external: true diff --git a/roles/docker/templates/compose-files/restic.yml.j2 b/roles/docker/templates/compose-files/restic.yml.j2 new file mode 100644 index 00000000..1f2ed2b0 --- /dev/null +++ b/roles/docker/templates/compose-files/restic.yml.j2 @@ -0,0 +1,37 @@ +# vim: ft=yaml.docker-compose +version: "3.8" + +services: + backup: + image: mazzolino/restic:{{ services.restic.version }} + restart: always + environment: + RUN_ON_STARTUP: false + BACKUP_CRON: "0 30 3 * * *" + RESTIC_REPOSITORY: sftp:{{ services.restic.user }}@{{ services.restic.domain }}:{{ services.restic.repository }} + RESTIC_PASSWORD: "{{ restic_secrets.repository_password }}" + RESTIC_BACKUP_SOURCES: /mnt/volumes + RESTIC_BACKUP_ARGS: >- + --tag datacoop-volumes + --exclude '*.tmp' + --verbose + RESTIC_FORGET_ARGS: >- + --keep-last 10 + --keep-daily 7 + --keep-weekly 5 + --keep-monthly 12 + TZ: Europe/Copenhagen + volumes: + - "./ssh:/run/secrets/.ssh:ro" + - "/docker-volumes:/mnt/volumes:ro" + + prune: + image: mazzolino/restic:{{ services.restic.version }} + environment: + RUN_ON_STARTUP: false + PRUNE_CRON: "0 30 4 * * *" + RESTIC_REPOSITORY: sftp:{{ services.restic.user }}@{{ services.restic.domain }}:{{ services.restic.repository }} + RESTIC_PASSWORD: "{{ restic_secrets.repository_password }}" + TZ: Europe/copenhagen + volumes: + - "./ssh:/run/secrets/.ssh:ro" diff --git a/roles/docker/templates/rallly/env.j2 b/roles/docker/templates/rallly/env.j2 index 64036967..5fa89ea7 100644 --- a/roles/docker/templates/rallly/env.j2 +++ b/roles/docker/templates/rallly/env.j2 @@ -1,5 +1,5 @@ NEXT_PUBLIC_BASE_URL="https://{{ services.rallly.domain }}" -DATABASE_URL="postgres://postgres:{{ postgres_passwords.rallly }}@rallly_db:5432/rallly_db" +DATABASE_URL="postgres://postgres:{{ postgres_passwords.rallly }}@db:5432/rallly_db" SECRET_PASSWORD="{{ rallly_secrets.secret_password }}" SUPPORT_EMAIL="noreply@{{ services.rallly.domain }}" SMTP_HOST="{{ smtp_host }}"