diff --git a/group_vars/ticketsystem.yml b/group_vars/ticketsystem.yml new file mode 100644 index 000000000..cda18c0b8 --- /dev/null +++ b/group_vars/ticketsystem.yml @@ -0,0 +1,8 @@ +--- +hostname: "ticketsystem.bi.privat" +zammad_compose_dir: /opt/zammad-docker-compose +docker_service_enabled: true +software_groups_to_install: + - admin + - editors + - utils diff --git a/hosts b/hosts index 26cf71f3b..eae17feeb 100644 --- a/hosts +++ b/hosts @@ -114,3 +114,6 @@ sn12.galaxyproject.eu [osiris] osiris.denbi.de ansible_ssh_user=rocky + +[ticketsystem] +ticketsystem.bi.privat diff --git a/templates/ticketsystem/docker_compose.yml.j2 b/templates/ticketsystem/docker_compose.yml.j2 new file mode 100644 index 000000000..e051ed951 --- /dev/null +++ b/templates/ticketsystem/docker_compose.yml.j2 @@ -0,0 +1,212 @@ +--- +# This is copied from https://github.com/zammad/zammad-docker-compose.git +# Based on a1feeee 🏷 v15.2.0 +x-shared: + zammad-service: &zammad-service + environment: &zammad-environment + MEMCACHE_SERVERS: ${MEMCACHE_SERVERS:-zammad-memcached:11211} + POSTGRESQL_DB: ${POSTGRES_DB:-zammad_production} + POSTGRESQL_HOST: ${POSTGRES_HOST:-zammad-postgresql} + POSTGRESQL_USER: ${POSTGRES_USER:-zammad} + POSTGRESQL_PASS: ${POSTGRES_PASS:-zammad} + POSTGRESQL_PORT: ${POSTGRES_PORT:-5432} + POSTGRESQL_OPTIONS: ${POSTGRESQL_OPTIONS:-?pool=50} + POSTGRESQL_DB_CREATE: + + # Redis standalone + REDIS_URL: ${REDIS_URL:-redis://zammad-redis:6379} + # Redis sentinel + REDIS_SENTINELS: + REDIS_SENTINEL_NAME: + REDIS_USERNAME: + REDIS_PASSWORD: + REDIS_SENTINEL_USERNAME: + REDIS_SENTINEL_PASSWORD: + + S3_URL: + # Backup settings + BACKUP_DIR: "${BACKUP_DIR:-/var/tmp/zammad}" + BACKUP_TIME: "${BACKUP_TIME:-03:00}" + HOLD_DAYS: "${HOLD_DAYS:-10}" + TZ: "${TZ:-Europe/Berlin}" + # Allow passing in these variables via .env: + AUTOWIZARD_JSON: + AUTOWIZARD_RELATIVE_PATH: + ELASTICSEARCH_ENABLED: + ELASTICSEARCH_SCHEMA: + ELASTICSEARCH_HOST: + ELASTICSEARCH_PORT: + ELASTICSEARCH_USER: + ELASTICSEARCH_PASS: + ELASTICSEARCH_NAMESPACE: + ELASTICSEARCH_REINDEX: + NGINX_PORT: + NGINX_CLIENT_MAX_BODY_SIZE: + NGINX_SERVER_NAME: + NGINX_SERVER_SCHEME: "https" + RAILS_TRUSTED_PROXIES: "['132.230.103.37','127.0.0.1','172.16.0.0/16','localhost',]" + ZAMMAD_HTTP_TYPE: https + ZAMMAD_FQDN: ticketsystem.galaxyproject.eu + ZAMMAD_WEB_CONCURRENCY: + ZAMMAD_MANAGE_SESSIONS_JOBS_WORKERS: + ZAMMAD_PROCESS_SESSIONS_JOBS_WORKERS: + ZAMMAD_PROCESS_SCHEDULED_JOBS_WORKERS: + ZAMMAD_PROCESS_DELAYED_JOBS_WORKERS: + ZAMMAD_PROCESS_DELAYED_JOBS_WORKER_THREADS: + ZAMMAD_PROCESS_DELAYED_AI_JOBS_WORKERS: + ZAMMAD_PROCESS_DELAYED_AI_JOBS_WORKER_THREADS: + ZAMMAD_PROCESS_DELAYED_COMMUNICATION_INBOUND_JOBS_WORKERS: + ZAMMAD_PROCESS_DELAYED_COMMUNICATION_INBOUND_JOBS_WORKER_THREADS: + ZAMMAD_OTRS_IMPORT_READ_TIMEOUT: + ZAMMAD_OTRS_IMPORT_TOTAL_TIMEOUT: + + # ZAMMAD_SESSION_JOBS_CONCURRENT is deprecated, please use ZAMMAD_PROCESS_SESSIONS_JOBS_WORKERS instead. + ZAMMAD_SESSION_JOBS_CONCURRENT: + # Variables used by ngingx-proxy container for reverse proxy creations + # for docs refer to https://github.com/nginx-proxy/nginx-proxy + VIRTUAL_HOST: + VIRTUAL_PORT: + # Variables used by acme-companion for retrieval of LetsEncrypt certificate + # for docs refer to https://github.com/nginx-proxy/acme-companion + LETSENCRYPT_HOST: + LETSENCRYPT_EMAIL: + + image: ${IMAGE_REPO:-ghcr.io/zammad/zammad}:${VERSION:-7.0.0-0042} + restart: ${RESTART:-always} + volumes: + - zammad-backup:/var/tmp/zammad:ro # needed for waiting on restore operations + - zammad-storage:/opt/zammad/storage + depends_on: + - zammad-memcached + - zammad-postgresql + - zammad-redis + +services: + zammad-backup: + <<: *zammad-service + command: ["zammad-backup"] + volumes: + - zammad-backup:/var/tmp/zammad + - zammad-storage:/opt/zammad/storage + user: 0:0 + + zammad-elasticsearch: + image: elasticsearch:${ELASTICSEARCH_VERSION:-9.3.2} + restart: ${RESTART:-always} + volumes: + - elasticsearch-data:/usr/share/elasticsearch/data + environment: + discovery.type: single-node + xpack.security.enabled: 'false' + ES_JAVA_OPTS: ${ELASTICSEARCH_JAVA_OPTS:--Xms1g -Xmx1g} + + zammad-init: + <<: *zammad-service + command: ["zammad-init"] + depends_on: + - zammad-postgresql + restart: on-failure + user: 0:0 + + zammad-memcached: + command: memcached -m 256M + image: memcached:${MEMCACHE_VERSION:-1.6.41-alpine} + restart: ${RESTART:-always} + zammad-nginx: + <<: *zammad-service + command: ["zammad-nginx"] + expose: + - "${NGINX_PORT:-8080}" + depends_on: + - zammad-railsserver + networks: + - default + - traefik + labels: + - "traefik.enable=true" + - "traefik.http.routers.tailscale.rule=Host(`ticketsystem.springhare-dinosaur.ts.net`)||Host(`ticketsystem.galaxyproject.eu`)" + - "traefik.http.routers.tailscale.entrypoints=websecure" + - "traefik.http.routers.tailscale.tls.certresolver=ts" + - "traefik.http.routers.tailscale.service=zammad-app" + - "traefik.http.routers.galaxyproject.rule=Host(`ticketsystem.galaxyproject.eu`)" + - "traefik.http.routers.galaxyproject.entrypoints=web" + - "traefik.http.routers.galaxyproject.service=zammad-app" + - "traefik.http.services.zammad-app.loadbalancer.server.port=${NGINX_PORT:-8080}" + + zammad-postgresql: + environment: + POSTGRES_DB: ${POSTGRES_DB:-zammad_production} + POSTGRES_USER: ${POSTGRES_USER:-zammad} + POSTGRES_PASSWORD: ${POSTGRES_PASS:-zammad} + image: postgres:${POSTGRES_VERSION:-17.9-alpine} + restart: ${RESTART:-always} + volumes: + - postgresql-data:/var/lib/postgresql/data + + zammad-railsserver: + <<: *zammad-service + command: ["zammad-railsserver"] + + zammad-redis: + image: redis:${REDIS_VERSION:-8.6.1-alpine} + restart: ${RESTART:-always} + volumes: + - redis-data:/data + + zammad-scheduler: + <<: *zammad-service + command: ["zammad-scheduler"] + + zammad-websocket: + <<: *zammad-service + command: ["zammad-websocket"] + + traefik: + image: traefik:v3.7.0 + restart: ${RESTART:-always} + command: + - --ping + - --ping.entryPoint=websecure + - --api=true + - --api.dashboard=false + - --api.insecure=false + - --global.sendAnonymousUsage=false + - --global.checkNewVersion=false + - --entryPoints.websecure.address=:443 + - --entryPoints.web.address=:80 + - --entryPoints.websecure.http.tls=true + - --providers.docker=true + - --providers.docker.exposedByDefault=false + - --providers.docker.network=zammad-docker-compose_traefik + - --certificatesResolvers.ts.tailscale=true + - --log.level=INFO + - --accesslog=true + labels: + - "traefik.enable=false" + ports: + - "443:443" + - "80:80" + networks: + - traefik + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - /var/run/tailscale:/var/run/tailscale:ro + security_opt: + - "label:type:container_runtime_t" + +networks: + traefik: + driver: bridge + +volumes: + elasticsearch-data: + driver: local + postgresql-data: + driver: local + redis-data: + driver: local + zammad-backup: + driver: local + zammad-storage: + driver: local + diff --git a/ticketsystem.yml b/ticketsystem.yml new file mode 100644 index 000000000..5f4f2ce47 --- /dev/null +++ b/ticketsystem.yml @@ -0,0 +1,62 @@ +--- +- name: Ticket System with Traefik and Zammad + become: true + hosts: ticketsystem + vars_files: + - secret_group_vars/all.yml + + pre_tasks: + - name: Install Ansible dependencies + ansible.builtin.package: + name: + - python3-policycoreutils + - python3-libselinux + - policycoreutils-python-utils + - python3-pip + state: present + + - name: Install python docker + become: true + ansible.builtin.pip: + name: "{{ item }}" + virtualenv_command: "python3 -m venv" + loop: + - docker + - selinux + + roles: + - geerlingguy.repo-epel + - role: usegalaxy_eu.handy.os_setup + vars: + enable_hostname: true + enable_powertools: false + enable_remap_user: false + enable_exclude_packages: true + enable_pam_limits: true + enable_install_software: true + - artis3n.tailscale + - geerlingguy.docker + - usegalaxy_eu.firewall + + tasks: + - name: Ensure Zammad compose directory exists + ansible.builtin.file: + path: "{{ zammad_compose_dir }}" + state: directory + owner: root + group: root + mode: '0755' + + - name: Template Docker Compose file + ansible.builtin.template: + src: ticketsystem/docker_compose.yml.j2 + dest: "{{ zammad_compose_dir }}/docker-compose.yml" + owner: root + group: root + mode: '0644' + register: zammad_compose_templated + + - name: Start Zammad services + community.docker.docker_compose_v2: + project_src: "{{ zammad_compose_dir }}" + state: present