From e3b09e7f1ac5e9af2f74c7adf860a207a0e9801c Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Fri, 15 Aug 2025 20:06:56 +0200 Subject: [PATCH] Refactoring of discourse role during debugging --- roles/web-app-discourse/Administration.md | 2 +- roles/web-app-discourse/config/main.yml | 11 +-- roles/web-app-discourse/handlers/main.yml | 10 +-- roles/web-app-discourse/tasks/01_core.yml | 74 +------------------ roles/web-app-discourse/tasks/02_reset.yml | 6 +- roles/web-app-discourse/tasks/03_docker.yml | 43 +++++++++++ roles/web-app-discourse/tasks/04_network.yml | 21 ++++++ .../web-app-discourse/templates/config.yml.j2 | 12 +-- .../templates/docker-compose.yml.j2 | 2 +- roles/web-app-discourse/vars/main.yml | 35 +++++---- 10 files changed, 111 insertions(+), 105 deletions(-) create mode 100644 roles/web-app-discourse/tasks/03_docker.yml create mode 100644 roles/web-app-discourse/tasks/04_network.yml diff --git a/roles/web-app-discourse/Administration.md b/roles/web-app-discourse/Administration.md index ffdb9df5..bc3969dd 100644 --- a/roles/web-app-discourse/Administration.md +++ b/roles/web-app-discourse/Administration.md @@ -13,7 +13,7 @@ pry(main)> SiteSetting.all.each { |setting| puts "#{setting.name}: #{setting.val To reinitialize the container execute: ```bash -docker network connect discourse_default central-postgres && /opt/docker/discourse/services/discourse_repository/launcher rebuild discourse_application +docker network connect discourse_default central-postgres && /opt/docker/discourse/services/repository/launcher rebuild discourse_application ``` ### 🔍 Logging with `journalctl` diff --git a/roles/web-app-discourse/config/main.yml b/roles/web-app-discourse/config/main.yml index 4c44d3ab..e48ceb2d 100644 --- a/roles/web-app-discourse/config/main.yml +++ b/roles/web-app-discourse/config/main.yml @@ -1,12 +1,12 @@ -repository: "discourse_repository" # Name of the repository folder +repository: "repository" # Name of the repository folder features: matomo: true css: true - desktop: true + desktop: true oidc: true central_database: true ldap: false # @todo implement and activate - logout: true + logout: true server: csp: flags: @@ -27,10 +27,11 @@ docker: redis: enabled: true discourse: - name: "discourse" - image: "local_discourse/<< defaults_applications[web-app-discourse].docker.services.discourse.name >>" # Necessary to define this for the docker 2 loc backup + name: "discourse" + image: "local_discourse/<< defaults_applications[web-app-discourse].docker.services.discourse.name >>" # Necessary to define this for the docker 2 loc backup backup: no_stop_required: true + repository: "https://github.com/discourse/discourse_docker.git" volumes: data: discourse_data network: discourse diff --git a/roles/web-app-discourse/handlers/main.yml b/roles/web-app-discourse/handlers/main.yml index a01f8da8..4c0b5175 100644 --- a/roles/web-app-discourse/handlers/main.yml +++ b/roles/web-app-discourse/handlers/main.yml @@ -1,14 +1,14 @@ --- - name: "stop and remove discourse container if it exist" community.docker.docker_container: - name: "{{ discourse_container }}" + name: "{{ DISCOURSE_CONTAINER }}" state: absent register: container_action failed_when: container_action.failed and 'No such container' not in container_action.msg listen: recreate discourse - name: "add central database temporary to discourse network" - command: "docker network connect {{ discourse_network }} {{ database_host }}" + command: "docker network connect {{ DISCOURSE_NETWORK }} {{ database_host }}" failed_when: > result.rc != 0 and 'already exists in network' not in result.stderr @@ -17,10 +17,8 @@ listen: recreate discourse - name: rebuild discourse - shell: ./launcher rebuild {{ discourse_container }} + shell: ./launcher rebuild {{ DISCOURSE_CONTAINER }} args: executable: /bin/bash - chdir: "{{docker_repository_directory }}" - async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}" - poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}" + chdir: "{{ DISCOURSE_REPOSITORY_DIR }}" listen: recreate discourse \ No newline at end of file diff --git a/roles/web-app-discourse/tasks/01_core.yml b/roles/web-app-discourse/tasks/01_core.yml index e86e26f2..b39fd95d 100644 --- a/roles/web-app-discourse/tasks/01_core.yml +++ b/roles/web-app-discourse/tasks/01_core.yml @@ -2,74 +2,8 @@ include_tasks: 02_reset.yml when: MODE_RESET | bool -# Necessary for building: https://chat.openai.com/share/99d258cc-294b-4924-8eef-02fe419bb838 -- name: install which - community.general.pacman: - name: which - state: present +- name: "Setup '{{ application_id }}' docker" + include_tasks: 03_docker.yml -- name: "load docker, db and proxy for {{ application_id }}" - include_role: - name: cmp-db-docker-proxy - -- name: pull docker repository - git: - repo: "https://github.com/discourse/discourse_docker.git" - dest: "{{docker_repository_directory }}" - update: yes - notify: recreate discourse - become: true - ignore_errors: true - -- name: set chmod 700 for {{docker_repository_directory }}containers - ansible.builtin.file: - path: "{{docker_repository_directory }}/containers" - mode: '700' - state: directory - -- name: "copy configuration to {{discourse_application_yml_destination}}" - template: - src: config.yml.j2 - dest: "{{ discourse_application_yml_destination }}" - mode: '0640' - notify: recreate discourse - -- name: "Verify that '{{ discourse_container }}' is running" - command: docker compose ps --filter status=running --format '{{"{{"}}.Name{{"}}"}}' | grep -x {{ discourse_container }} - register: docker_ps - changed_when: docker_ps.rc == 1 - failed_when: docker_ps.rc not in [0, 1] - notify: recreate discourse - -- name: flush, to recreate discourse app - meta: flush_handlers - -- name: Set error string for network already exists - set_fact: - docker_discourse_already_in_net: "Error response from daemon: endpoint with name {{ discourse_container }} already exists in network {{ discourse_pg_network }}" - -- name: "Connect {{ discourse_container }} to network {{ discourse_pg_network }}" - command: > - docker network connect {{ discourse_pg_network }} {{ discourse_container }} - register: network_connect - failed_when: > - network_connect.rc != 0 and - docker_discourse_already_in_net not in network_connect.stderr - changed_when: network_connect.rc == 0 - when: - - applications | get_app_conf(application_id, 'features.central_database', False) - -- name: Set error string for network not connected - set_fact: - docker_discourse_not_connected: 'is not connected to network {{ discourse_network }}' - -- name: "Remove {{ discourse_network }} from {{ database_host }}" - command: > - docker network disconnect {{ discourse_network }} {{ database_host }} - register: network_disconnect - failed_when: > - network_disconnect.rc != 0 and - docker_discourse_not_connected not in network_disconnect.stderr - changed_when: network_disconnect.rc == 0 - when: - - applications | get_app_conf(application_id, 'features.central_database', False) \ No newline at end of file +- name: "Setup '{{ application_id }}' network" + include_tasks: 04_network.yml \ No newline at end of file diff --git a/roles/web-app-discourse/tasks/02_reset.yml b/roles/web-app-discourse/tasks/02_reset.yml index b4636ddb..9a2a50bf 100644 --- a/roles/web-app-discourse/tasks/02_reset.yml +++ b/roles/web-app-discourse/tasks/02_reset.yml @@ -6,9 +6,9 @@ cmd: "docker network disconnect {{applications | get_app_conf(application_id, 'network', True)}} {{ database_host }}" ignore_errors: true -- name: "destroy container {{ discourse_container }}" +- name: "destroy container {{ DISCOURSE_CONTAINER }}" command: - cmd: "./launcher destroy {{ discourse_container }}" - chdir: "{{ docker_repository_directory }}" + cmd: "./launcher destroy {{ DISCOURSE_CONTAINER }}" + chdir: "{{ DISCOURSE_REPOSITORY_DIR }}" ignore_errors: true notify: recreate discourse \ No newline at end of file diff --git a/roles/web-app-discourse/tasks/03_docker.yml b/roles/web-app-discourse/tasks/03_docker.yml new file mode 100644 index 00000000..0a8afe35 --- /dev/null +++ b/roles/web-app-discourse/tasks/03_docker.yml @@ -0,0 +1,43 @@ +# Necessary for building: https://chat.openai.com/share/99d258cc-294b-4924-8eef-02fe419bb838 +- name: install which + community.general.pacman: + name: which + state: present + +- name: "load docker, db and proxy for {{ application_id }}" + include_role: + name: cmp-db-docker-proxy + vars: + docker_compose_flush_handlers: true + +- name: pull docker repository + git: + repo: "{{ DISCOURSE_REPOSITORY_URL }}" + dest: "{{ DISCOURSE_REPOSITORY_DIR }}" + update: yes + notify: recreate discourse + become: true + ignore_errors: true + +- name: set chmod 700 for '{{ DISCOURSE_CONTAINERS_DIR}}' + ansible.builtin.file: + path: "{{ DISCOURSE_CONTAINERS_DIR }}" + mode: '700' + state: directory + +- name: "copy configuration to '{{ DISCOURSE_APPLICATION_YML_DEST }}'" + template: + src: config.yml.j2 + dest: "{{ DISCOURSE_APPLICATION_YML_DEST }}" + mode: '0640' + notify: recreate discourse + +- name: "Verify that '{{ DISCOURSE_CONTAINER }}' is running" + command: docker compose ps --filter status=running --format '{{"{{"}}.Name{{"}}"}}' | grep -x {{ DISCOURSE_CONTAINER }} + register: docker_ps + changed_when: docker_ps.rc == 1 + failed_when: docker_ps.rc not in [0, 1] + notify: recreate discourse + +- name: flush, to recreate discourse app + meta: flush_handlers diff --git a/roles/web-app-discourse/tasks/04_network.yml b/roles/web-app-discourse/tasks/04_network.yml new file mode 100644 index 00000000..17a0fbd4 --- /dev/null +++ b/roles/web-app-discourse/tasks/04_network.yml @@ -0,0 +1,21 @@ +- name: "Connect '{{ DISCOURSE_CONTAINER }}' to network '{{ DISCOURSE_PG_NETWORK }}'" + command: > + docker network connect {{ DISCOURSE_PG_NETWORK }} {{ DISCOURSE_CONTAINER }} + register: network_connect + failed_when: > + network_connect.rc != 0 and + DISCOURSE_ERROR_ALREADY_IN_NET not in network_connect.stderr + changed_when: network_connect.rc == 0 + when: + - applications | get_app_conf(application_id, 'features.central_database', False) + +- name: "Remove {{ DISCOURSE_NETWORK }} from {{ database_host }}" + command: > + docker network disconnect {{ DISCOURSE_NETWORK }} {{ database_host }} + register: network_disconnect + failed_when: > + network_disconnect.rc != 0 and + DISCOURSE_ERROR_NOT_CONNECTED not in network_disconnect.stderr + changed_when: network_disconnect.rc == 0 + when: + - applications | get_app_conf(application_id, 'features.central_database', False) \ No newline at end of file diff --git a/roles/web-app-discourse/templates/config.yml.j2 b/roles/web-app-discourse/templates/config.yml.j2 index aa1cf89d..a7df4837 100644 --- a/roles/web-app-discourse/templates/config.yml.j2 +++ b/roles/web-app-discourse/templates/config.yml.j2 @@ -74,7 +74,7 @@ env: DISCOURSE_DB_NAME: {{ database_name }} # Redis Configuration - DISCOURSE_REDIS_HOST: {{ discourse_redis_host }} + DISCOURSE_REDIS_HOST: {{ DISCOURSE_REDIS_HOST }} ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate #LETSENCRYPT_ACCOUNT_EMAIL: administrator@veen.world @@ -90,7 +90,7 @@ env: ## The Docker container is stateless; all data is stored in /shared volumes: - volume: - host: {{ discourse_volume }} + host: {{ DISCOURSE_VOLUME }} guest: /shared - volume: host: /var/discourse/shared/standalone/log/var-log @@ -103,7 +103,7 @@ hooks: - exec: cd: $home/plugins cmd: -{% for plugin_name, plugin_config in discourse_plugins.items() %} +{% for plugin_name, plugin_config in DISCOURSE_PLUGINS.items() %} {% if plugin_config.enabled %} - git clone --depth=1 https://github.com/discourse/{{ plugin_name }}.git {% endif %} @@ -132,7 +132,7 @@ run: #- exec: rails r "User.find_by_email('{{ users.administrator.email }}').update(username: '{{users.administrator.username}}')" # The following code is just an inspiration, how to connect with the oidc account. as long as this is not set the admini account needs to be manually connected with oidc - # docker exec -it {{ discourse_container }} rails runner "user = User.find_by_email('test@infinito.nexus'); UserAuth.create(user_id: user.id, provider: 'oidc', uid: 'eindeutige_oidc_id', info: { name: user.username, email: user.email })" + # docker exec -it {{ DISCOURSE_CONTAINER }} rails runner "user = User.find_by_email('test@infinito.nexus'); UserAuth.create(user_id: user.id, provider: 'oidc', uid: 'eindeutige_oidc_id', info: { name: user.username, email: user.email })" # OIDC Activation - exec: rails r "SiteSetting.openid_connect_enabled = true" @@ -170,5 +170,5 @@ run: - exec: echo "End of custom commands" docker_args: - - --network={{ discourse_network }} - - --name={{ discourse_container }} + - --network={{ DISCOURSE_NETWORK }} + - --name={{ DISCOURSE_CONTAINER }} diff --git a/roles/web-app-discourse/templates/docker-compose.yml.j2 b/roles/web-app-discourse/templates/docker-compose.yml.j2 index f1521ccb..3fece8a5 100644 --- a/roles/web-app-discourse/templates/docker-compose.yml.j2 +++ b/roles/web-app-discourse/templates/docker-compose.yml.j2 @@ -3,5 +3,5 @@ {% include 'roles/docker-compose/templates/volumes.yml.j2' %} {% include 'roles/docker-compose/templates/networks.yml.j2' %} - {{ discourse_network }}: + {{ DISCOURSE_NETWORK }}: external: true \ No newline at end of file diff --git a/roles/web-app-discourse/vars/main.yml b/roles/web-app-discourse/vars/main.yml index 853cfa55..3d2f2452 100644 --- a/roles/web-app-discourse/vars/main.yml +++ b/roles/web-app-discourse/vars/main.yml @@ -1,18 +1,27 @@ -application_id: "web-app-discourse" +application_id: "web-app-discourse" # Database -database_password: "{{ applications | get_app_conf(application_id, 'credentials.database_password') }}" -database_type: "postgres" +database_password: "{{ applications | get_app_conf(application_id, 'credentials.database_password') }}" +database_type: "postgres" # Discourse -discourse_container: "{{ applications | get_app_conf(application_id, 'docker.services.discourse.name') }}" -discourse_network: "{{ applications | get_app_conf(application_id, 'docker.network') }}" -discourse_volume: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}" -discourse_plugins: "{{ applications | get_app_conf(application_id, 'plugins') }}" -discourse_pg_network: "{{ applications | get_app_conf('svc-db-postgres', 'docker.network' ) }}" -discourse_application_yml_destination: "{{ docker_repository_directory }}containers/{{ discourse_container }}.yml" -discourse_redis_host: "{{ application_id |get_entity_name }}-redis" -# General Docker Configuration -docker_repository_directory : "{{ docker_compose.directories.services}}{{applications | get_app_conf( application_id, 'repository') }}/" -docker_compose_flush_handlers: true \ No newline at end of file +## General +DISCOURSE_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.discourse.name') }}" +DISCOURSE_NETWORK: "{{ applications | get_app_conf(application_id, 'docker.network') }}" +DISCOURSE_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}" +DISCOURSE_PLUGINS: "{{ applications | get_app_conf(application_id, 'plugins') }}" +DISCOURSE_PG_NETWORK: "{{ applications | get_app_conf('svc-db-postgres', 'docker.network' ) }}" +DISCOURSE_REDIS_HOST: "{{ application_id | get_entity_name }}-redis" +DISCOURSE_REPOSITORY_URL: "{{ applications | get_app_conf(application_id, 'docker.services.discourse.repository') }}" + +## Directories +DISCOURSE_REPOSITORY_DIR: "{{ docker_compose.directories.services }}{{ applications | get_app_conf( application_id, 'repository') }}/" +DISCOURSE_CONTAINERS_DIR: "{{ DISCOURSE_REPOSITORY_DIR }}/containers/" + +## Files +DISCOURSE_APPLICATION_YML_DEST: "{{ DISCOURSE_CONTAINERS_DIR }}{{ DISCOURSE_CONTAINER }}.yml" + +## Error Strings +DISCOURSE_ERROR_ALREADY_IN_NET: "Error response from daemon: endpoint with name {{ DISCOURSE_CONTAINER }} already exists in network {{ DISCOURSE_PG_NETWORK }}" +DISCOURSE_ERROR_NOT_CONNECTED: 'is not connected to network {{ DISCOURSE_NETWORK }}' \ No newline at end of file