From 5d8c78a10d9d912e7e141ddf33472756dc2db28e Mon Sep 17 00:00:00 2001 From: Ralf Schmid Date: Tue, 4 Mar 2025 11:18:49 +0100 Subject: [PATCH 01/18] Added scenario page, first sections --- .../portainer-additional-paths.png | Bin 0 -> 20687 bytes install/docker-compose.rst | 9 +++ .../docker-compose-scenarios.rst | 76 ++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 images/install/docker-compose/additional-scenarios/portainer-additional-paths.png create mode 100644 install/docker-compose/docker-compose-scenarios.rst diff --git a/images/install/docker-compose/additional-scenarios/portainer-additional-paths.png b/images/install/docker-compose/additional-scenarios/portainer-additional-paths.png new file mode 100644 index 0000000000000000000000000000000000000000..e676f440a98eb92ba3b1713b54e707f5dd1ab417 GIT binary patch literal 20687 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 Wj|{fG?4}YS5NT;{ZB}7&Gv` to keep this +section clean. How to Run Commands in the Stack -------------------------------- diff --git a/install/docker-compose/docker-compose-scenarios.rst b/install/docker-compose/docker-compose-scenarios.rst new file mode 100644 index 00000000..a752e1be --- /dev/null +++ b/install/docker-compose/docker-compose-scenarios.rst @@ -0,0 +1,76 @@ +Docker Compose Scenarios +======================== + +Overview +-------- + +The following scenarios are supported: + +- add-cloudflare-tunnel.yml +- add-external-network-to-nginx.yml +- add-nginx-proxy-manager.yml +- disable-backup-service.yml +- disable-elasticsearch-service.yml + +You can find the files in the +`Zammad-Docker-Compose repository `_. + +Usage with Portainer +-------------------- + +Follow the +:doc:`general deployment guide <../docker-compose>` +and apply the following changes. + +Below the "Compose path" field, click on the **Add file** button. This opens +the "Additional paths" section where you can specify the scenario you want to +use. Add ``/scenarios/{scenario you want to use}.yml`` and replace the last +part with the name of one of the scenario files. + +.. figure:: /images/install/docker-compose/additional-scenarios/portainer-additional-paths.png + :alt: Screenshot shows where to add additional paths in Portainer + :scale: 70% + +Usage with Docker Compose +------------------------- + + +Scenario Details +---------------- + +Add Cloudflare Tunnel +^^^^^^^^^^^^^^^^^^^^^ + +Relevant file: ``/scenarios/add-cloudflare-tunnel.yml`` + +**Why?** + +If you want to publish Zammad in a very easy way and without taking +care about e.g. SSL certificates, you can use a +`Cloudflare `_ tunnel. + +**How?** + +- Use the relevant scenario file +- Provide your Cloudflare token as environment variable (``CLOUDFLARE_TUNNEL_TOKEN``) + +Add External Network to Nginx +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Relevant file: ``/scenarios/add-external-network-to-nginx.yml`` + +Add Nginx Proxy Manager +^^^^^^^^^^^^^^^^^^^^^^^ + +Relevant file: ``/scenarios/add-nginx-proxy-manager.yml`` + +Disable Backup Service +^^^^^^^^^^^^^^^^^^^^^^ + +Relevant file: ``/scenarios/disable-backup-service.yml`` + + +Disable Elasticsearch Service +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Relevant file: ``/scenarios/disable-elasticsearch-service.yml`` \ No newline at end of file From 7a1dc8fccd3e875ecdb5a02eaa32a1f4a3d46a99 Mon Sep 17 00:00:00 2001 From: Ralf Schmid Date: Tue, 4 Mar 2025 12:03:02 +0100 Subject: [PATCH 02/18] Added Docker Compose usage --- install/docker-compose.rst | 2 +- .../docker-compose-scenarios.rst | 25 ++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/install/docker-compose.rst b/install/docker-compose.rst index bc481a0f..83f6cbf3 100644 --- a/install/docker-compose.rst +++ b/install/docker-compose.rst @@ -64,7 +64,7 @@ Step 3: **Deploy the Stack** Stack creation with provided information in **Repository** screen You can configure your Portainer based deployment even more. Have a look at -our :doc:`advanced modules section ` on how +our :doc:`advanced modules section ` on how to do that. Deployment with Docker-Compose diff --git a/install/docker-compose/docker-compose-scenarios.rst b/install/docker-compose/docker-compose-scenarios.rst index a752e1be..5c6e9a65 100644 --- a/install/docker-compose/docker-compose-scenarios.rst +++ b/install/docker-compose/docker-compose-scenarios.rst @@ -25,7 +25,8 @@ and apply the following changes. Below the "Compose path" field, click on the **Add file** button. This opens the "Additional paths" section where you can specify the scenario you want to use. Add ``/scenarios/{scenario you want to use}.yml`` and replace the last -part with the name of one of the scenario files. +part in ``{}`` brackets with the name of one of the scenario files. You can +even combine the scenarios by adding additional paths. .. figure:: /images/install/docker-compose/additional-scenarios/portainer-additional-paths.png :alt: Screenshot shows where to add additional paths in Portainer @@ -34,6 +35,18 @@ part with the name of one of the scenario files. Usage with Docker Compose ------------------------- +Follow the first 2 steps of the +:doc:`general deployment guide <../docker-compose>`. To start the stack with +one or more additional scenarios, use the following command for step 3 in +the cloned repository folder instead: + +.. code-block:: yaml + + docker compose -f docker-compose.yml -f /scenarios/{scenario you want to use}.yml up -d + +Replace the part in ``{}`` brackets with the file name of one of the scenario +files. You can even combine the scenarios by adding additional files according +to the example above. Scenario Details ---------------- @@ -64,6 +77,16 @@ Add Nginx Proxy Manager Relevant file: ``/scenarios/add-nginx-proxy-manager.yml`` +**Why?** + +If you don't already have a reverse proxy, you can directly deploy it with +the Zammad stack. + +**How?** + +- Use the relevant scenario file +- Provide your Cloudflare token as environment variable (``CLOUDFLARE_TUNNEL_TOKEN``) + Disable Backup Service ^^^^^^^^^^^^^^^^^^^^^^ From 86fcf3bb08b895dd45172a4c6265df225bfea064 Mon Sep 17 00:00:00 2001 From: Ralf Schmid Date: Tue, 4 Mar 2025 12:16:48 +0100 Subject: [PATCH 03/18] NPM scenario --- install/docker-compose/docker-compose-scenarios.rst | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/install/docker-compose/docker-compose-scenarios.rst b/install/docker-compose/docker-compose-scenarios.rst index 5c6e9a65..44d1ae1c 100644 --- a/install/docker-compose/docker-compose-scenarios.rst +++ b/install/docker-compose/docker-compose-scenarios.rst @@ -79,13 +79,22 @@ Relevant file: ``/scenarios/add-nginx-proxy-manager.yml`` **Why?** -If you don't already have a reverse proxy, you can directly deploy it with +If you don't have a reverse proxy already, you can directly deploy it with the Zammad stack. **How?** - Use the relevant scenario file -- Provide your Cloudflare token as environment variable (``CLOUDFLARE_TUNNEL_TOKEN``) +- Provide your FQDN for Zammad by using the environment variable ``ZAMMAD_FQDN`` +- After deploying the stack, go to the NPM UI by accessing the IP of your + deployment and the port ``81`` (e.g. ``172.20.0.5:81``) +- Log in with ``admin@example.com`` (user) and ``changeme`` (password) +- You have to change the email address and the password after the log in +- Go to *Hosts > Proxy hosts* and select **Add Proxy Host**. +- Configure it according to your needs and make sure to set up a proper + SSL certificate +- Configure your DNS. The chosen Zammad FQDN should point to the NPM IP/host. + Disable Backup Service ^^^^^^^^^^^^^^^^^^^^^^ From ec1d14874babcbe528ca39f492c1173b64f9c484 Mon Sep 17 00:00:00 2001 From: Ralf Schmid Date: Tue, 4 Mar 2025 13:57:47 +0100 Subject: [PATCH 04/18] Added scenarios, added/reworked text --- .../docker-compose-scenarios.rst | 118 +++++++++++++----- 1 file changed, 88 insertions(+), 30 deletions(-) diff --git a/install/docker-compose/docker-compose-scenarios.rst b/install/docker-compose/docker-compose-scenarios.rst index 44d1ae1c..47cd0161 100644 --- a/install/docker-compose/docker-compose-scenarios.rst +++ b/install/docker-compose/docker-compose-scenarios.rst @@ -4,13 +4,22 @@ Docker Compose Scenarios Overview -------- +The best way to deploy Zammad with Docker Compose or Portainer is by using +the repository build method. With this, your Zammad can be updated regularly +and you are using the default compose file of the repository. This might be +good as default, but your situation may differ. This is why you can set +:doc:`environment variables for docker ` and/or even use our +pre-defined scenarios. + The following scenarios are supported: -- add-cloudflare-tunnel.yml -- add-external-network-to-nginx.yml -- add-nginx-proxy-manager.yml -- disable-backup-service.yml -- disable-elasticsearch-service.yml +- **Add a Cloudflare tunnel service to the stack** (add-cloudflare-tunnel.yml) +- **Add an external network to Elasticsearch** (add-external-network-to-elasticsearch.yml) +- **Add an external network to Nginx** (add-external-network-to-nginx.yml) +- **Add an host port to Elasticsearch** (add-hostport-to-elasticsearch.yml) +- **Add a Nginx Proxy Manager (NPM) to the stack** (add-nginx-proxy-manager.yml) +- **Disable the backup service** (disable-backup-service.yml) +- **Disable Elasticsearch service** (disable-elasticsearch-service.yml) You can find the files in the `Zammad-Docker-Compose repository `_. @@ -40,7 +49,7 @@ Follow the first 2 steps of the one or more additional scenarios, use the following command for step 3 in the cloned repository folder instead: -.. code-block:: yaml +.. code-block:: sh docker compose -f docker-compose.yml -f /scenarios/{scenario you want to use}.yml up -d @@ -56,53 +65,102 @@ Add Cloudflare Tunnel Relevant file: ``/scenarios/add-cloudflare-tunnel.yml`` -**Why?** - -If you want to publish Zammad in a very easy way and without taking -care about e.g. SSL certificates, you can use a -`Cloudflare `_ tunnel. +Why? + If you want to publish Zammad in a very easy way and without taking + care about e.g. SSL certificates, you can use a + `Cloudflare `_ tunnel. -**How?** - -- Use the relevant scenario file -- Provide your Cloudflare token as environment variable (``CLOUDFLARE_TUNNEL_TOKEN``) +How? + - Use the relevant scenario file + - Provide your Cloudflare token by using the environment variable + ``CLOUDFLARE_TUNNEL_TOKEN`` Add External Network to Nginx ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Relevant file: ``/scenarios/add-external-network-to-nginx.yml`` +Why? + If you need to connect your Zammad stack to another network on your + docker compose / Portainer instance where your NPM is running. + +How? + - Use the relevant scenario file + - Provide the name of your external network by using the environment + variable ``ZAMMAD_NGINX_EXTERNAL_NETWORK`` + +Add External Network to Elasticsearch +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Relevant file: ``/scenarios/add-external-network-to-elasticsearch.yml`` + +Why? + If you need to connect your Zammad stack to another network on your + docker compose / Portainer instance where your Elasticsearch is running. + +How? + - Use the relevant scenario file + - Provide the name of your external network by using the environment + variable ``ZAMMAD_ELASTICSEARCH_EXTERNAL_NETWORK`` + + Add Nginx Proxy Manager ^^^^^^^^^^^^^^^^^^^^^^^ Relevant file: ``/scenarios/add-nginx-proxy-manager.yml`` -**Why?** +Why? + If you don't have a reverse proxy already, you can directly deploy it with + the Zammad stack. -If you don't have a reverse proxy already, you can directly deploy it with -the Zammad stack. +How? + - Use the relevant scenario file + - Provide your FQDN for Zammad by using the environment variable ``ZAMMAD_FQDN`` + - After deploying the stack, go to the NPM UI by accessing the IP of your + deployment and the port ``81`` (e.g. ``172.20.0.5:81``) + - Log in with ``admin@example.com`` (user) and ``changeme`` (password) + - You have to change the email address and the password after the log in + - Go to *Hosts > Proxy hosts* and select **Add Proxy Host**. + - Configure it according to your needs and make sure to set up a proper + SSL certificate + - Configure your DNS. The chosen Zammad FQDN should point to the NPM IP/host. -**How?** +Add Host Port to Elasticsearch +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Use the relevant scenario file -- Provide your FQDN for Zammad by using the environment variable ``ZAMMAD_FQDN`` -- After deploying the stack, go to the NPM UI by accessing the IP of your - deployment and the port ``81`` (e.g. ``172.20.0.5:81``) -- Log in with ``admin@example.com`` (user) and ``changeme`` (password) -- You have to change the email address and the password after the log in -- Go to *Hosts > Proxy hosts* and select **Add Proxy Host**. -- Configure it according to your needs and make sure to set up a proper - SSL certificate -- Configure your DNS. The chosen Zammad FQDN should point to the NPM IP/host. +Relevant file: ``/scenarios/add-hostport-to-elasticsearch.yml`` +Why? + If you want to expose the Elasticsearch service of this stack, e.g. to + access it from an external Grafana instance. + +How? + Just use the relevant scenario file. Disable Backup Service ^^^^^^^^^^^^^^^^^^^^^^ Relevant file: ``/scenarios/disable-backup-service.yml`` +Why? + If you want to do the backups in a different way, you can disable the backup + service in the stack to save resources. + +How? + Just use the relevant scenario file. + Disable Elasticsearch Service ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Relevant file: ``/scenarios/disable-elasticsearch-service.yml`` \ No newline at end of file +Relevant file: ``/scenarios/disable-elasticsearch-service.yml`` + +Why? + If you have an Elasticsearch instance already and want to use it for Zammad + too, you can disable the Elasticsearch service in the stack to save + resources. + +How? + - Use the relevant scenario file + - Use the environment variable ``ELASTICSEARCH_ENABLED`` and set it to + ``false`` \ No newline at end of file From 4354f9ac5d9c74eff2a8c97c60523719d5b58e15 Mon Sep 17 00:00:00 2001 From: Ralf Schmid Date: Tue, 4 Mar 2025 13:59:44 +0100 Subject: [PATCH 05/18] Fixed ES port --- install/docker-compose/docker-compose-scenarios.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/docker-compose/docker-compose-scenarios.rst b/install/docker-compose/docker-compose-scenarios.rst index 47cd0161..14d07d2f 100644 --- a/install/docker-compose/docker-compose-scenarios.rst +++ b/install/docker-compose/docker-compose-scenarios.rst @@ -135,7 +135,8 @@ Why? access it from an external Grafana instance. How? - Just use the relevant scenario file. + - Use the relevant scenario file + - Your ES service is now accessible under port ``9200`` Disable Backup Service ^^^^^^^^^^^^^^^^^^^^^^ From da24aa39082821515f68781e9b6d378dfbf7922c Mon Sep 17 00:00:00 2001 From: Ralf Schmid Date: Tue, 4 Mar 2025 14:45:22 +0100 Subject: [PATCH 06/18] Added description for CF, added certificates section with NPM quick-start guide --- install/docker-compose.rst | 19 ++++++++++ .../docker-compose-scenarios.rst | 38 ++++++++++--------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/install/docker-compose.rst b/install/docker-compose.rst index 83f6cbf3..16173903 100644 --- a/install/docker-compose.rst +++ b/install/docker-compose.rst @@ -122,6 +122,25 @@ described in a :doc:`separate sub-page ` to keep this section clean. +SSL Certificates +---------------- + +Before publishing any service on the internet, you definitely have to request +certificates for your services. The two easiest ways of doing that is +either to use a Cloudflare tunnel. Alternatively, you could request certificates +from `Letsencrypt `_ by using the Zammad stack with +an included Nginx Proxy Manager (NPM). Both scenarios are covered in the +:doc:`Docker compose scenarios section `. + +Some notes for users who want a quick setup with NPM: + +- Use the relevant scenario file as described in the + :doc:`scenarios page ` +- Provide your FQDN for Zammad by using the environment variable ``ZAMMAD_FQDN`` +- Configure your DNS. The chosen Zammad FQDN should point to the NPM IP/host +- Configure a new proxy host and follow their steps to get a + certificate + How to Run Commands in the Stack -------------------------------- diff --git a/install/docker-compose/docker-compose-scenarios.rst b/install/docker-compose/docker-compose-scenarios.rst index 14d07d2f..9bd4147e 100644 --- a/install/docker-compose/docker-compose-scenarios.rst +++ b/install/docker-compose/docker-compose-scenarios.rst @@ -33,7 +33,7 @@ and apply the following changes. Below the "Compose path" field, click on the **Add file** button. This opens the "Additional paths" section where you can specify the scenario you want to -use. Add ``/scenarios/{scenario you want to use}.yml`` and replace the last +use. Add ``scenarios/{scenario you want to use}.yml`` and replace the last part in ``{}`` brackets with the name of one of the scenario files. You can even combine the scenarios by adding additional paths. @@ -63,7 +63,7 @@ Scenario Details Add Cloudflare Tunnel ^^^^^^^^^^^^^^^^^^^^^ -Relevant file: ``/scenarios/add-cloudflare-tunnel.yml`` +Relevant file: ``scenarios/add-cloudflare-tunnel.yml`` Why? If you want to publish Zammad in a very easy way and without taking @@ -72,13 +72,16 @@ Why? How? - Use the relevant scenario file + - Add a sub-domain to an already existing domain + - Forward it to your Zammad Nginx instance with port ``8080`` + - Create a tunnel. This is where you get your token for the next step - Provide your Cloudflare token by using the environment variable ``CLOUDFLARE_TUNNEL_TOKEN`` Add External Network to Nginx ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Relevant file: ``/scenarios/add-external-network-to-nginx.yml`` +Relevant file: ``scenarios/add-external-network-to-nginx.yml`` Why? If you need to connect your Zammad stack to another network on your @@ -92,7 +95,7 @@ How? Add External Network to Elasticsearch ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Relevant file: ``/scenarios/add-external-network-to-elasticsearch.yml`` +Relevant file: ``scenarios/add-external-network-to-elasticsearch.yml`` Why? If you need to connect your Zammad stack to another network on your @@ -107,7 +110,7 @@ How? Add Nginx Proxy Manager ^^^^^^^^^^^^^^^^^^^^^^^ -Relevant file: ``/scenarios/add-nginx-proxy-manager.yml`` +Relevant file: ``scenarios/add-nginx-proxy-manager.yml`` Why? If you don't have a reverse proxy already, you can directly deploy it with @@ -116,19 +119,14 @@ Why? How? - Use the relevant scenario file - Provide your FQDN for Zammad by using the environment variable ``ZAMMAD_FQDN`` - - After deploying the stack, go to the NPM UI by accessing the IP of your - deployment and the port ``81`` (e.g. ``172.20.0.5:81``) - - Log in with ``admin@example.com`` (user) and ``changeme`` (password) - - You have to change the email address and the password after the log in - - Go to *Hosts > Proxy hosts* and select **Add Proxy Host**. - - Configure it according to your needs and make sure to set up a proper - SSL certificate - Configure your DNS. The chosen Zammad FQDN should point to the NPM IP/host. + - Configure your NPM according to your needs and make sure to set up a proper + SSL certificate Add Host Port to Elasticsearch ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Relevant file: ``/scenarios/add-hostport-to-elasticsearch.yml`` +Relevant file: ``scenarios/add-hostport-to-elasticsearch.yml`` Why? If you want to expose the Elasticsearch service of this stack, e.g. to @@ -141,7 +139,7 @@ How? Disable Backup Service ^^^^^^^^^^^^^^^^^^^^^^ -Relevant file: ``/scenarios/disable-backup-service.yml`` +Relevant file: ``scenarios/disable-backup-service.yml`` Why? If you want to do the backups in a different way, you can disable the backup @@ -154,7 +152,7 @@ How? Disable Elasticsearch Service ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Relevant file: ``/scenarios/disable-elasticsearch-service.yml`` +Relevant file: ``scenarios/disable-elasticsearch-service.yml`` Why? If you have an Elasticsearch instance already and want to use it for Zammad @@ -163,5 +161,11 @@ Why? How? - Use the relevant scenario file - - Use the environment variable ``ELASTICSEARCH_ENABLED`` and set it to - ``false`` \ No newline at end of file + - Use the environment following environment variables to provide information + about your external ES: + + - ``ELASTICSEARCH_SCHEMA`` + - ``ELASTICSEARCH_HOST`` + - ``ELASTICSEARCH_PORT`` + - ``ELASTICSEARCH_USER`` + - ``ELASTICSEARCH_PASS`` \ No newline at end of file From 128a5731a62ddbe0823542f78910a2adf0d7d490 Mon Sep 17 00:00:00 2001 From: Martin Gruner Date: Wed, 5 Mar 2025 08:58:42 +0100 Subject: [PATCH 07/18] wip --- install/docker-compose.rst | 49 +++++++----------- .../docker-compose-scenarios.rst | 50 ++++++++++++++----- 2 files changed, 55 insertions(+), 44 deletions(-) diff --git a/install/docker-compose.rst b/install/docker-compose.rst index 16173903..62e7ea5b 100644 --- a/install/docker-compose.rst +++ b/install/docker-compose.rst @@ -98,14 +98,27 @@ Step 3: Start the stack After the stack is ready, you can access Zammad via the configured docker host and port, e.g. ``http://localhost:8080/``. +Exposing the Stack via HTTPS +---------------------------- + +To publish a Zammad stack on the internet, it needs be secured via the HTTPS protocol. +With the Zammad stack, you can: + +- Use a reverse proxy like Nginx Proxy Manager (NPM). It has a GUI that provides an easy `Letsencrypt `_ integration. +- Use a cloudflare tunnel, which provides SSL termination. + +Both scenarios are covered in the :doc:`Docker compose scenarios section `. + + Customizing the Zammad Stack ---------------------------- -Sometimes it's necessary to apply local changes to the Zammad docker stack, e.g. to -include additional services. If you plan to do so, we recommend that you do not change -the ``docker-compose.yml`` file, but instead create a local ``docker-compose.override.yml`` -that includes all your modifications. Docker-Compose will -`automatically load this file and merge its changes into your stack `_. +The Zammad stack can be customized by loading additional scenario files for common use cases. +For example, you can deploy the stack with an included Nginx Proxy Manager (NPM) or +with disabled Postgres or Elasticsearch services, in case you already have +these services running. + +Please see the :doc:`Docker compose scenarios section `. .. toctree:: :hidden: @@ -114,32 +127,6 @@ that includes all your modifications. Docker-Compose will /install/docker-compose/environment /install/docker-compose/docker-compose-scenarios -There are also some scenarios which are supported out of the box. For example, -you can deploy the stack with an included Nginx Proxy Manager (NPM) or -with disabled Postgres or Elasticsearch services, in case you already have -these services running. They are -described in a -:doc:`separate sub-page ` to keep this -section clean. - -SSL Certificates ----------------- - -Before publishing any service on the internet, you definitely have to request -certificates for your services. The two easiest ways of doing that is -either to use a Cloudflare tunnel. Alternatively, you could request certificates -from `Letsencrypt `_ by using the Zammad stack with -an included Nginx Proxy Manager (NPM). Both scenarios are covered in the -:doc:`Docker compose scenarios section `. - -Some notes for users who want a quick setup with NPM: - -- Use the relevant scenario file as described in the - :doc:`scenarios page ` -- Provide your FQDN for Zammad by using the environment variable ``ZAMMAD_FQDN`` -- Configure your DNS. The chosen Zammad FQDN should point to the NPM IP/host -- Configure a new proxy host and follow their steps to get a - certificate How to Run Commands in the Stack -------------------------------- diff --git a/install/docker-compose/docker-compose-scenarios.rst b/install/docker-compose/docker-compose-scenarios.rst index 9bd4147e..9479affd 100644 --- a/install/docker-compose/docker-compose-scenarios.rst +++ b/install/docker-compose/docker-compose-scenarios.rst @@ -13,13 +13,24 @@ pre-defined scenarios. The following scenarios are supported: -- **Add a Cloudflare tunnel service to the stack** (add-cloudflare-tunnel.yml) -- **Add an external network to Elasticsearch** (add-external-network-to-elasticsearch.yml) -- **Add an external network to Nginx** (add-external-network-to-nginx.yml) -- **Add an host port to Elasticsearch** (add-hostport-to-elasticsearch.yml) -- **Add a Nginx Proxy Manager (NPM) to the stack** (add-nginx-proxy-manager.yml) -- **Disable the backup service** (disable-backup-service.yml) -- **Disable Elasticsearch service** (disable-elasticsearch-service.yml) +- Making the stack available via HTTPS + + - **Add a Cloudflare tunnel service to the stack** (add-cloudflare-tunnel.yml) + - **Add a Nginx Proxy Manager (NPM) to the stack** (add-nginx-proxy-manager.yml) + - **Add an external docker network to Nginx** (add-external-network-to-nginx.yml) + +- Using external services + + - **Disable Elasticsearch service** (disable-elasticsearch-service.yml) + +- Making services externally available + + - **Add an external docker network to Elasticsearch** (add-external-network-to-elasticsearch.yml) + - **Add an host port to Elasticsearch** (add-hostport-to-elasticsearch.yml) + +- Additional scenarios + + - **Disable the backup service** (disable-backup-service.yml) You can find the files in the `Zammad-Docker-Compose repository `_. @@ -78,7 +89,7 @@ How? - Provide your Cloudflare token by using the environment variable ``CLOUDFLARE_TUNNEL_TOKEN`` -Add External Network to Nginx +Add External Docker Network to Nginx ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Relevant file: ``scenarios/add-external-network-to-nginx.yml`` @@ -92,7 +103,7 @@ How? - Provide the name of your external network by using the environment variable ``ZAMMAD_NGINX_EXTERNAL_NETWORK`` -Add External Network to Elasticsearch +Add External Docker Network to Elasticsearch ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Relevant file: ``scenarios/add-external-network-to-elasticsearch.yml`` @@ -119,9 +130,9 @@ Why? How? - Use the relevant scenario file - Provide your FQDN for Zammad by using the environment variable ``ZAMMAD_FQDN`` - - Configure your DNS. The chosen Zammad FQDN should point to the NPM IP/host. - - Configure your NPM according to your needs and make sure to set up a proper - SSL certificate + - Configure your DNS. The chosen Zammad FQDN should point to the IP address of the NPM host. + - Configure a new proxy host in your NPM and follow their steps to get an SSL certificate. + Add Host Port to Elasticsearch ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -168,4 +179,17 @@ How? - ``ELASTICSEARCH_HOST`` - ``ELASTICSEARCH_PORT`` - ``ELASTICSEARCH_USER`` - - ``ELASTICSEARCH_PASS`` \ No newline at end of file + - ``ELASTICSEARCH_PASS`` + +Other use cases +^^^^^^^^^^^^^^^ + +- suggest a new scenario… + +- or customize locally: + +Sometimes it's necessary to apply local changes to the Zammad docker stack, e.g. to +include additional services. If you plan to do so, we recommend that you do not change +the ``docker-compose.yml`` file, but instead create a local ``docker-compose.override.yml`` +that includes all your modifications. Docker-Compose will +`automatically load this file and merge its changes into your stack `_. From ea631738683cc896b976a5d8cba303bd28ad8551 Mon Sep 17 00:00:00 2001 From: Ralf Schmid Date: Wed, 5 Mar 2025 09:16:38 +0100 Subject: [PATCH 08/18] Replaced screenshot --- .../portainer-additional-paths.png | Bin 20687 -> 22464 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/images/install/docker-compose/additional-scenarios/portainer-additional-paths.png b/images/install/docker-compose/additional-scenarios/portainer-additional-paths.png index e676f440a98eb92ba3b1713b54e707f5dd1ab417..ffa6258309650dac3aaaabb6583f7cbb4461f3fb 100644 GIT binary patch literal 22464 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 Xi`g#>$BTD$bML7tYADpnnT7oik5yKm literal 20687 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 Wj|{fG?4}YS5NT;{ZB}7&Gv Date: Wed, 5 Mar 2025 09:50:35 +0100 Subject: [PATCH 09/18] Cleaned code blocks, intro for scenarios --- install/docker-compose.rst | 66 +++++++++++-------- .../docker-compose-scenarios.rst | 25 ++++--- 2 files changed, 52 insertions(+), 39 deletions(-) diff --git a/install/docker-compose.rst b/install/docker-compose.rst index 62e7ea5b..dc1c1dfc 100644 --- a/install/docker-compose.rst +++ b/install/docker-compose.rst @@ -9,8 +9,9 @@ graphical docker front ends like .. hint:: - We do not provide support in terms of Docker (-Compose) or Portainer specific problems. - If you choose to run Zammad via Docker, support is only provided for the Zammad application. + We do not provide support in terms of Docker (-Compose) or Portainer specific + problems. If you choose to run Zammad via Docker, support is only provided + for the Zammad application. Prerequisites ------------- @@ -22,13 +23,15 @@ Prerequisites .. code-block:: sh - $ sysctl -w vm.max_map_count=262144 + sysctl -w vm.max_map_count=262144 Deployment with Portainer ------------------------- -The easiest way to get Zammad running is via a graphical docker UI. We recommend `Portainer `_. -For installation instructions, check out `Portainer's documentation `_. +The easiest way to get Zammad running is via a graphical docker UI. We recommend +`Portainer `_. +For installation instructions, check out +`Portainer's documentation `_. Step 1: **Add Stack** In the Portainer GUI (e.g. ``https://yourdomain.tld:9443``), @@ -48,10 +51,12 @@ Step 2: **Build From Repository** them in the **Environment variable** section or even upload a ``.env`` file. See the `example env template `_. - Zammad runs on port ``8080`` by default. If you want to use another port, you can set it via the variable ``NGINX_EXPOSE_PORT``. + Zammad runs on port ``8080`` by default. If you want to use another port, you + can set it via the variable ``NGINX_EXPOSE_PORT``. Step 3: **Deploy the Stack** - After the stack is ready, you can access Zammad via the configured docker host and port, e.g. ``http://localhost:8080/``. + After the stack is ready, you can access Zammad via the configured docker + host and port, e.g. ``http://localhost:8080/``. .. figure:: /images/install/docker-compose/portainer/portainer-stacks.png :alt: Screenshot showing portainer UI with stacks section and highlighted "Add stack" button @@ -64,7 +69,7 @@ Step 3: **Deploy the Stack** Stack creation with provided information in **Repository** screen You can configure your Portainer based deployment even more. Have a look at -our :doc:`advanced modules section ` on how +our :doc:`scenarios section ` on how to do that. Deployment with Docker-Compose @@ -73,7 +78,7 @@ Deployment with Docker-Compose Step 1: **Clone the GitHub Repo** .. code-block:: sh - $ git clone https://github.com/zammad/zammad-docker-compose.git + git clone https://github.com/zammad/zammad-docker-compose.git Make sure to run ``git pull`` frequently to fetch updates. Alternatively, you can download the files from @@ -88,35 +93,40 @@ Step 2: **Adjust Environment as Needed** ``.env.dist`` file and copy it to ``.env``. That way it will be picked up by Docker-Compose automatically and not overwritten during updates. - Zammad runs on port ``8080`` by default. If you want to use another port, you can set it via the variable ``NGINX_EXPOSE_PORT``. + Zammad runs on port ``8080`` by default. If you want to use another port, you + can set it via the variable ``NGINX_EXPOSE_PORT``. Step 3: Start the stack .. code-block:: sh - $ cd zammad-docker-compose - $ docker compose up -d + cd zammad-docker-compose + docker compose up -d - After the stack is ready, you can access Zammad via the configured docker host and port, e.g. ``http://localhost:8080/``. + After the stack is ready, you can access Zammad via the configured docker + host and port, e.g. ``http://localhost:8080/``. Exposing the Stack via HTTPS ---------------------------- -To publish a Zammad stack on the internet, it needs be secured via the HTTPS protocol. +To publish a Zammad stack on the internet, it needs be secured via the HTTPS +protocol. With the Zammad stack, you can: -- Use a reverse proxy like Nginx Proxy Manager (NPM). It has a GUI that provides an easy `Letsencrypt `_ integration. +- Use a reverse proxy like Nginx Proxy Manager (NPM). It has a GUI that provides + an easy `Letsencrypt `_ integration. - Use a cloudflare tunnel, which provides SSL termination. -Both scenarios are covered in the :doc:`Docker compose scenarios section `. +Both scenarios are covered in the +:doc:`Docker compose scenarios section `. Customizing the Zammad Stack ---------------------------- -The Zammad stack can be customized by loading additional scenario files for common use cases. -For example, you can deploy the stack with an included Nginx Proxy Manager (NPM) or -with disabled Postgres or Elasticsearch services, in case you already have -these services running. +The Zammad stack can be customized by loading additional scenario files for +common use cases. For example, you can deploy the stack with an included Nginx +Proxy Manager (NPM) or with disabled Postgres or Elasticsearch services, in case +you already have these services running. Please see the :doc:`Docker compose scenarios section `. @@ -135,19 +145,23 @@ The docker entrypoint script sets up environment variables required by Zammad to function properly. That is why calling ``rails`` or ``rake`` on the console should be done via one of the following methods: +Directly execute a specific command: + .. code-block:: sh - # Directly execute a specific command: + docker compose run --rm zammad-railsserver rails r '...your rails command here...' - $ docker compose run --rm zammad-railsserver rails r '...your rails command here...' +Run the interactive rails console to manually enter Rails commands: - # Run the interactive rails console to manually enter Rails commands: +.. code-block:: sh - $ docker compose run --rm zammad-railsserver rails c + docker compose run --rm zammad-railsserver rails c - # Via 'docker exec': +Via 'docker exec': + +.. code-block:: sh - $ docker exec zammad-docker-compose-zammad-railsserver-1 /docker-entrypoint.sh rails r '...your rails command here...' + docker exec zammad-docker-compose-zammad-railsserver-1 /docker-entrypoint.sh rails r '...your rails command here...' If you need to retrieve information from the rails server, you can place for example ``pp`` (pretty print) in front of your rails command. This diff --git a/install/docker-compose/docker-compose-scenarios.rst b/install/docker-compose/docker-compose-scenarios.rst index 9479affd..47266bd1 100644 --- a/install/docker-compose/docker-compose-scenarios.rst +++ b/install/docker-compose/docker-compose-scenarios.rst @@ -4,33 +4,32 @@ Docker Compose Scenarios Overview -------- -The best way to deploy Zammad with Docker Compose or Portainer is by using -the repository build method. With this, your Zammad can be updated regularly -and you are using the default compose file of the repository. This might be -good as default, but your situation may differ. This is why you can set -:doc:`environment variables for docker ` and/or even use our -pre-defined scenarios. +If the "vanilla" Zammad stack doesn't cover your use-case, you can use one of +the pre-defined scenarios. We don't recommend to change the compose files +locally because upstream changes for the stack aren't reflected automatically +then. This is why you should either use Portainer's repository build method or +clone the repository and update it regularly. The following scenarios are supported: - Making the stack available via HTTPS - - **Add a Cloudflare tunnel service to the stack** (add-cloudflare-tunnel.yml) - - **Add a Nginx Proxy Manager (NPM) to the stack** (add-nginx-proxy-manager.yml) - - **Add an external docker network to Nginx** (add-external-network-to-nginx.yml) + - Add a Cloudflare tunnel service to the stack(add-cloudflare-tunnel.yml) + - dd a Nginx Proxy Manager (NPM) to the stack (add-nginx-proxy-manager.yml) + - Add an external docker network to Nginx (add-external-network-to-nginx.yml) - Using external services - - **Disable Elasticsearch service** (disable-elasticsearch-service.yml) + - Disable Elasticsearch service (disable-elasticsearch-service.yml) - Making services externally available - - **Add an external docker network to Elasticsearch** (add-external-network-to-elasticsearch.yml) - - **Add an host port to Elasticsearch** (add-hostport-to-elasticsearch.yml) + - Add an external docker network to Elasticsearch (add-external-network-to-elasticsearch.yml) + - Add an host port to Elasticsearch (add-hostport-to-elasticsearch.yml) - Additional scenarios - - **Disable the backup service** (disable-backup-service.yml) + - Disable the backup service (disable-backup-service.yml) You can find the files in the `Zammad-Docker-Compose repository `_. From c9b788a35a4d550b6fe49bf86882e871dbb4095a Mon Sep 17 00:00:00 2001 From: Ralf Schmid Date: Wed, 5 Mar 2025 10:38:43 +0100 Subject: [PATCH 10/18] Added portainer console with tabs and screenshots --- .../portainer/portainer-exec-console.png | Bin 0 -> 21399 bytes .../portainer/portainer-execute-command.png | Bin 0 -> 27109 bytes install/docker-compose.rst | 79 +++++++++++------- 3 files changed, 48 insertions(+), 31 deletions(-) create mode 100644 images/install/docker-compose/portainer/portainer-exec-console.png create mode 100644 images/install/docker-compose/portainer/portainer-execute-command.png diff --git a/images/install/docker-compose/portainer/portainer-exec-console.png b/images/install/docker-compose/portainer/portainer-exec-console.png new file mode 100644 index 0000000000000000000000000000000000000000..c496a8944ebce40eee9fa2b818d8724285689b9d GIT binary patch literal 21399 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 F{{Zh+8XN!s literal 0 HcmV?d00001 diff --git a/images/install/docker-compose/portainer/portainer-execute-command.png b/images/install/docker-compose/portainer/portainer-execute-command.png new file mode 100644 index 0000000000000000000000000000000000000000..c430566b3dfb281e10baa4e4f6068ddfa1e5434c GIT binary patch literal 27109 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
FWS3O3JT~6qKDS-sl@ftLj`|M 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 Ox%h{kdY&3C=zjp;E0U4` literal 0 HcmV?d00001 diff --git a/install/docker-compose.rst b/install/docker-compose.rst index dc1c1dfc..dd6bab9a 100644 --- a/install/docker-compose.rst +++ b/install/docker-compose.rst @@ -19,7 +19,7 @@ Prerequisites * This documentation expects you already have a working `Docker Compose `_ environment. * Make sure to have at least 4 GB of RAM to run the containers. -* You're required to adjust your host's settings to run Elasticsearch properly: +* You should adjust your host's settings to run Elasticsearch properly: .. code-block:: sh @@ -33,12 +33,12 @@ The easiest way to get Zammad running is via a graphical docker UI. We recommend For installation instructions, check out `Portainer's documentation `_. -Step 1: **Add Stack** +Step 1: Add Stack In the Portainer GUI (e.g. ``https://yourdomain.tld:9443``), choose your target environment, select **Stacks** and choose **Add stack** as you can see in the screenshot below. -Step 2: **Build From Repository** +Step 2: Build From Repository Switch to **Repository** build method and provide the information below: - **Name**: enter a desired name of the stack @@ -46,15 +46,13 @@ Step 2: **Build From Repository** - **Repository reference**: ``refs/heads/master`` - **Compose path**: ``docker-compose.yml`` (default) - Optional: if you need to provide - :doc:`environment variables <./docker-compose/environment>`, you can enter - them in the **Environment variable** section or even upload a ``.env`` file. - See the `example env template `_. + If you want to customize the stack, read on in + :ref:`this section ` below. Zammad runs on port ``8080`` by default. If you want to use another port, you can set it via the variable ``NGINX_EXPOSE_PORT``. -Step 3: **Deploy the Stack** +Step 3: Deploy the Stack After the stack is ready, you can access Zammad via the configured docker host and port, e.g. ``http://localhost:8080/``. @@ -68,14 +66,10 @@ Step 3: **Deploy the Stack** Stack creation with provided information in **Repository** screen -You can configure your Portainer based deployment even more. Have a look at -our :doc:`scenarios section ` on how -to do that. - Deployment with Docker-Compose ------------------------------ -Step 1: **Clone the GitHub Repo** +Step 1: Clone the GitHub Repo .. code-block:: sh git clone https://github.com/zammad/zammad-docker-compose.git @@ -84,14 +78,13 @@ Step 1: **Clone the GitHub Repo** Alternatively, you can download the files from `the releases page `_. -Step 2: **Adjust Environment as Needed** +Step 2: Adjust Environment as Needed In some cases our default environment is not what a docker-compose user is looking for. See :doc:`/install/docker-compose/environment` for details on which settings can be configured. - .. note:: If you want to use a ``.env`` file, you can use the provided - ``.env.dist`` file and copy it to ``.env``. That way it will be picked - up by Docker-Compose automatically and not overwritten during updates. + If you want to customize the stack, read on in + :ref:`this section ` below. Zammad runs on port ``8080`` by default. If you want to use another port, you can set it via the variable ``NGINX_EXPOSE_PORT``. @@ -102,6 +95,9 @@ Step 3: Start the stack cd zammad-docker-compose docker compose up -d + Optional: Use an additional ``.yml`` file from the scenarios folder to + apply one of the :doc:`pre-defined scenarios `. + After the stack is ready, you can access Zammad via the configured docker host and port, e.g. ``http://localhost:8080/``. @@ -109,8 +105,7 @@ Exposing the Stack via HTTPS ---------------------------- To publish a Zammad stack on the internet, it needs be secured via the HTTPS -protocol. -With the Zammad stack, you can: +protocol. With the Zammad stack, you can: - Use a reverse proxy like Nginx Proxy Manager (NPM). It has a GUI that provides an easy `Letsencrypt `_ integration. @@ -119,6 +114,7 @@ With the Zammad stack, you can: Both scenarios are covered in the :doc:`Docker compose scenarios section `. +.. _customizing-stack: Customizing the Zammad Stack ---------------------------- @@ -145,24 +141,45 @@ The docker entrypoint script sets up environment variables required by Zammad to function properly. That is why calling ``rails`` or ``rake`` on the console should be done via one of the following methods: -Directly execute a specific command: +.. tabs:: + + .. tab:: Docker Compose / console + + Directly execute a specific command: + + .. code-block:: sh + + docker compose run --rm zammad-railsserver rails r '...your rails command here...' + + Run the interactive rails console to manually enter Rails commands: + + .. code-block:: sh + + docker compose run --rm zammad-railsserver rails c -.. code-block:: sh + Via ``docker exec``: - docker compose run --rm zammad-railsserver rails r '...your rails command here...' + .. code-block:: sh -Run the interactive rails console to manually enter Rails commands: + docker exec zammad-docker-compose-zammad-railsserver-1 /docker-entrypoint.sh rails r '...your rails command here...' -.. code-block:: sh + If you need to retrieve information from the rails server, you can place + for example ``pp`` (pretty print) in front of your rails command. This + leads to an output in your terminal. - docker compose run --rm zammad-railsserver rails c + .. tab:: Portainer -Via 'docker exec': + In your Portainer GUI, go to the container view and select the running + rails container from your Zammad stack. Click on the **Exec Console** + icon in the "Quick Actions" column. -.. code-block:: sh + .. figure:: /images/install/docker-compose/portainer/portainer-exec-console.png + :alt: + :width: 70% - docker exec zammad-docker-compose-zammad-railsserver-1 /docker-entrypoint.sh rails r '...your rails command here...' + In the "Execute" dialog, select the "rails console" entry point as you + can see in the screenshot: -If you need to retrieve information from the rails server, you can place -for example ``pp`` (pretty print) in front of your rails command. This -leads to an output in your terminal. \ No newline at end of file + .. figure:: /images/install/docker-compose/portainer/portainer-execute-command.png + :alt: + :width: 70% \ No newline at end of file From 0c2cb43db2ab7aa4868e8a3f9ec2742bfeebc668 Mon Sep 17 00:00:00 2001 From: Ralf Schmid Date: Wed, 5 Mar 2025 11:50:13 +0100 Subject: [PATCH 11/18] Replaced screenshot again, edited content --- .../portainer-additional-paths.png | Bin 22464 -> 20407 bytes install/docker-compose.rst | 49 +++--- .../docker-compose-scenarios.rst | 144 +++++++++--------- 3 files changed, 97 insertions(+), 96 deletions(-) diff --git a/images/install/docker-compose/additional-scenarios/portainer-additional-paths.png b/images/install/docker-compose/additional-scenarios/portainer-additional-paths.png index ffa6258309650dac3aaaabb6583f7cbb4461f3fb..d58a144742d2ff579f0f42734940c2fa73c92fa7 100644 GIT binary patch literal 20407 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�%xAWYCA`{UI>h1(vMYC?K^$YuBE3(sxc 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 literal 22464 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 Xi`g#>$BTD$bML7tYADpnnT7oik5yKm diff --git a/install/docker-compose.rst b/install/docker-compose.rst index dd6bab9a..727cde07 100644 --- a/install/docker-compose.rst +++ b/install/docker-compose.rst @@ -47,7 +47,7 @@ Step 2: Build From Repository - **Compose path**: ``docker-compose.yml`` (default) If you want to customize the stack, read on in - :ref:`this section ` below. + :ref:`the customization section ` below. Zammad runs on port ``8080`` by default. If you want to use another port, you can set it via the variable ``NGINX_EXPOSE_PORT``. @@ -79,12 +79,11 @@ Step 1: Clone the GitHub Repo `the releases page `_. Step 2: Adjust Environment as Needed - In some cases our default environment is not what a docker-compose user is - looking for. See :doc:`/install/docker-compose/environment` for details on - which settings can be configured. - - If you want to customize the stack, read on in - :ref:`this section ` below. + In some cases, our default environment is not what a docker-compose user is + looking for. You can customize the stack using pre-defined scenarios and + adjust environment variables. Jump to the + :ref:`customization section ` below to find more + information. Zammad runs on port ``8080`` by default. If you want to use another port, you can set it via the variable ``NGINX_EXPOSE_PORT``. @@ -143,7 +142,24 @@ should be done via one of the following methods: .. tabs:: - .. tab:: Docker Compose / console + .. tab:: Via Portainer GUI + + In your Portainer GUI, go to the container view and select the running + rails container from your Zammad stack. Click on the **Exec Console** + icon in the "Quick Actions" column. + + .. figure:: /images/install/docker-compose/portainer/portainer-exec-console.png + :alt: + :width: 70% + + In the "Execute" dialog, select the "rails console" entry point as you + can see in the screenshot: + + .. figure:: /images/install/docker-compose/portainer/portainer-execute-command.png + :alt: + :width: 70% + + .. tab:: Via console Directly execute a specific command: @@ -166,20 +182,3 @@ should be done via one of the following methods: If you need to retrieve information from the rails server, you can place for example ``pp`` (pretty print) in front of your rails command. This leads to an output in your terminal. - - .. tab:: Portainer - - In your Portainer GUI, go to the container view and select the running - rails container from your Zammad stack. Click on the **Exec Console** - icon in the "Quick Actions" column. - - .. figure:: /images/install/docker-compose/portainer/portainer-exec-console.png - :alt: - :width: 70% - - In the "Execute" dialog, select the "rails console" entry point as you - can see in the screenshot: - - .. figure:: /images/install/docker-compose/portainer/portainer-execute-command.png - :alt: - :width: 70% \ No newline at end of file diff --git a/install/docker-compose/docker-compose-scenarios.rst b/install/docker-compose/docker-compose-scenarios.rst index 47266bd1..4e4211e0 100644 --- a/install/docker-compose/docker-compose-scenarios.rst +++ b/install/docker-compose/docker-compose-scenarios.rst @@ -8,28 +8,28 @@ If the "vanilla" Zammad stack doesn't cover your use-case, you can use one of the pre-defined scenarios. We don't recommend to change the compose files locally because upstream changes for the stack aren't reflected automatically then. This is why you should either use Portainer's repository build method or -clone the repository and update it regularly. +clone the repository and update it regularly, when using docker compose. The following scenarios are supported: - Making the stack available via HTTPS - - Add a Cloudflare tunnel service to the stack(add-cloudflare-tunnel.yml) - - dd a Nginx Proxy Manager (NPM) to the stack (add-nginx-proxy-manager.yml) - - Add an external docker network to Nginx (add-external-network-to-nginx.yml) + - Add a Cloudflare tunnel service to the stack + - Add a Nginx Proxy Manager (NPM) to the stack + - Add an external docker network to Nginx - Using external services - - Disable Elasticsearch service (disable-elasticsearch-service.yml) + - Disable Elasticsearch service - Making services externally available - - Add an external docker network to Elasticsearch (add-external-network-to-elasticsearch.yml) - - Add an host port to Elasticsearch (add-hostport-to-elasticsearch.yml) + - Add an external docker network to Elasticsearch + - Add an host port to Elasticsearch - Additional scenarios - - Disable the backup service (disable-backup-service.yml) + - Disable the backup service You can find the files in the `Zammad-Docker-Compose repository `_. @@ -61,49 +61,87 @@ the cloned repository folder instead: .. code-block:: sh - docker compose -f docker-compose.yml -f /scenarios/{scenario you want to use}.yml up -d + docker compose -f docker-compose.yml -f scenarios/{scenario you want to use}.yml up -d Replace the part in ``{}`` brackets with the file name of one of the scenario files. You can even combine the scenarios by adding additional files according to the example above. -Scenario Details ----------------- + +Making the Stack Available via HTTPS +------------------------------------ + +If you set up Zammad for production use, it needs to be secured by using an +HTTPS connection. Because this can be achieved in different ways, we added 3 +different scenarios. Add Cloudflare Tunnel ^^^^^^^^^^^^^^^^^^^^^ -Relevant file: ``scenarios/add-cloudflare-tunnel.yml`` +If you want to publish Zammad in a very easy way and without taking +care about e.g. SSL certificates, you can use a +`Cloudflare `_ tunnel. -Why? - If you want to publish Zammad in a very easy way and without taking - care about e.g. SSL certificates, you can use a - `Cloudflare `_ tunnel. +- Use the scenario file ``scenarios/add-cloudflare-tunnel.yml`` for deployment +- Add a sub-domain to an already existing domain in your Cloudflare dashboard +- Forward it to your Zammad Nginx instance with port ``8080`` +- Create a tunnel. This is where you get your token for the next step +- Provide your Cloudflare token by using the environment variable + ``CLOUDFLARE_TUNNEL_TOKEN`` -How? - - Use the relevant scenario file - - Add a sub-domain to an already existing domain - - Forward it to your Zammad Nginx instance with port ``8080`` - - Create a tunnel. This is where you get your token for the next step - - Provide your Cloudflare token by using the environment variable - ``CLOUDFLARE_TUNNEL_TOKEN`` +Add Nginx Proxy Manager +^^^^^^^^^^^^^^^^^^^^^^^ + +A very common setup of publishing web services is to use a reverse proxy, which +handles the SSL termination. One common tool is the Nginx Proxy Manager (NPM), +which can be configured via UI quite simple. If you don't have a reverse +proxy already, this might be a useful scenario for you. If you already have a +running reverse proxy, head over to the next section. + +- Use the scenario file ``scenarios/add-nginx-proxy-manager.yml`` for deployment +- Provide your FQDN for Zammad by using the environment variable ``ZAMMAD_FQDN`` +- Configure your DNS. The chosen Zammad FQDN should point to the IP address of + the NPM host +- Configure a new proxy host in your NPM and follow the steps to get an SSL + certificate Add External Docker Network to Nginx +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you already have a reverse proxy which takes care about the SSL termination, +this scenario is helpful. It adds an external docker network to Zammad's +included Nginx service to be able to access it from a separated reverse proxy. + +- Use the scenario file ``scenarios/add-external-network-to-nginx.yml`` for deployment +- Provide the name of your external network by using the environment + variable ``ZAMMAD_NGINX_EXTERNAL_NETWORK`` + +Using External Services +----------------------- + +Disable Elasticsearch Service ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Relevant file: ``scenarios/add-external-network-to-nginx.yml`` +Do you have an Elasticsearch instance already running and want to use it for +Zammad too? Then you can disable the Elasticsearch service in the Zammad stack +to save resources. -Why? - If you need to connect your Zammad stack to another network on your - docker compose / Portainer instance where your NPM is running. +- Use the scenario file ``scenarios/disable-elasticsearch-service.yml`` for + deployment +- Use the following environment variables to provide information about the + connection to your existing Elasticsearch instance: -How? - - Use the relevant scenario file - - Provide the name of your external network by using the environment - variable ``ZAMMAD_NGINX_EXTERNAL_NETWORK`` + - ``ELASTICSEARCH_SCHEMA`` + - ``ELASTICSEARCH_HOST`` + - ``ELASTICSEARCH_PORT`` + - ``ELASTICSEARCH_USER`` + - ``ELASTICSEARCH_PASS`` + +Making Services Externally Available +------------------------------------ Add External Docker Network to Elasticsearch -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Relevant file: ``scenarios/add-external-network-to-elasticsearch.yml`` @@ -116,23 +154,6 @@ How? - Provide the name of your external network by using the environment variable ``ZAMMAD_ELASTICSEARCH_EXTERNAL_NETWORK`` - -Add Nginx Proxy Manager -^^^^^^^^^^^^^^^^^^^^^^^ - -Relevant file: ``scenarios/add-nginx-proxy-manager.yml`` - -Why? - If you don't have a reverse proxy already, you can directly deploy it with - the Zammad stack. - -How? - - Use the relevant scenario file - - Provide your FQDN for Zammad by using the environment variable ``ZAMMAD_FQDN`` - - Configure your DNS. The chosen Zammad FQDN should point to the IP address of the NPM host. - - Configure a new proxy host in your NPM and follow their steps to get an SSL certificate. - - Add Host Port to Elasticsearch ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -146,6 +167,9 @@ How? - Use the relevant scenario file - Your ES service is now accessible under port ``9200`` +Additional Scenarios +-------------------- + Disable Backup Service ^^^^^^^^^^^^^^^^^^^^^^ @@ -158,28 +182,6 @@ Why? How? Just use the relevant scenario file. - -Disable Elasticsearch Service -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Relevant file: ``scenarios/disable-elasticsearch-service.yml`` - -Why? - If you have an Elasticsearch instance already and want to use it for Zammad - too, you can disable the Elasticsearch service in the stack to save - resources. - -How? - - Use the relevant scenario file - - Use the environment following environment variables to provide information - about your external ES: - - - ``ELASTICSEARCH_SCHEMA`` - - ``ELASTICSEARCH_HOST`` - - ``ELASTICSEARCH_PORT`` - - ``ELASTICSEARCH_USER`` - - ``ELASTICSEARCH_PASS`` - Other use cases ^^^^^^^^^^^^^^^ From 37b8afa7b703ad9f6e757ccb340a338c710dd46e Mon Sep 17 00:00:00 2001 From: Ralf Schmid Date: Wed, 5 Mar 2025 12:26:48 +0100 Subject: [PATCH 12/18] Additional content; re-added docker env variables to 'Customizing the Zammad stack' --- install/docker-compose.rst | 3 + .../docker-compose-scenarios.rst | 64 ++++++++++--------- 2 files changed, 36 insertions(+), 31 deletions(-) diff --git a/install/docker-compose.rst b/install/docker-compose.rst index 727cde07..d779b497 100644 --- a/install/docker-compose.rst +++ b/install/docker-compose.rst @@ -125,6 +125,9 @@ you already have these services running. Please see the :doc:`Docker compose scenarios section `. +To adjust the stack and settings, use +:doc:`docker specific environment variables `. + .. toctree:: :hidden: :maxdepth: 1 diff --git a/install/docker-compose/docker-compose-scenarios.rst b/install/docker-compose/docker-compose-scenarios.rst index 4e4211e0..a54f05ff 100644 --- a/install/docker-compose/docker-compose-scenarios.rst +++ b/install/docker-compose/docker-compose-scenarios.rst @@ -140,32 +140,34 @@ to save resources. Making Services Externally Available ------------------------------------ +These scenarios are meant to connect from external services to Zammad +services and vice versa. Depending on where your external service is hosted, +use one of the following scenarios. + + Add External Docker Network to Elasticsearch ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Relevant file: ``scenarios/add-external-network-to-elasticsearch.yml`` +A common use case for this is to use a reporting/visualization tool like Grafana +on the same host in another stack. Because such tools need to access the +Elasticsearch index, the network of the other stack has to be added to Zammad's +Elasticsearch Container. -Why? - If you need to connect your Zammad stack to another network on your - docker compose / Portainer instance where your Elasticsearch is running. - -How? - - Use the relevant scenario file - - Provide the name of your external network by using the environment - variable ``ZAMMAD_ELASTICSEARCH_EXTERNAL_NETWORK`` +- Use the scenario file ``scenarios/add-external-network-to-elasticsearch.yml`` + for deployment +- Provide the name of your external network by using the environment + variable ``ZAMMAD_ELASTICSEARCH_EXTERNAL_NETWORK`` Add Host Port to Elasticsearch ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Relevant file: ``scenarios/add-hostport-to-elasticsearch.yml`` +In case you want to expose the Elasticsearch service of the Zammad stack in the +network, you can assign a port to the container. This is useful if you need to +access the Elasticseach container from a different host. -Why? - If you want to expose the Elasticsearch service of this stack, e.g. to - access it from an external Grafana instance. - -How? - - Use the relevant scenario file - - Your ES service is now accessible under port ``9200`` +- Use the scenario file ``scenarios/add-hostport-to-elasticsearch.yml`` for + deployment +- Access your ES service under port ``9200`` Additional Scenarios -------------------- @@ -173,24 +175,24 @@ Additional Scenarios Disable Backup Service ^^^^^^^^^^^^^^^^^^^^^^ -Relevant file: ``scenarios/disable-backup-service.yml`` - -Why? - If you want to do the backups in a different way, you can disable the backup - service in the stack to save resources. +In case you want to handle backups in a different way, you can disable the +built in backup service in the stack to save resources. -How? - Just use the relevant scenario file. +You can do so by just using the scenario file +``scenarios/disable-backup-service.yml`` for deployment. -Other use cases +Other Use Cases ^^^^^^^^^^^^^^^ -- suggest a new scenario… +Your scenario is not covered? Feel free to suggest your use case. If we consider +it as an important scenario, we include it in the repository then. -- or customize locally: +Customize the Stack Locally +--------------------------- -Sometimes it's necessary to apply local changes to the Zammad docker stack, e.g. to -include additional services. If you plan to do so, we recommend that you do not change -the ``docker-compose.yml`` file, but instead create a local ``docker-compose.override.yml`` -that includes all your modifications. Docker-Compose will +Sometimes it's necessary to apply local changes to the Zammad docker stack, +e.g. to include additional services. If you plan to do so, we recommend that +you do not change the ``docker-compose.yml`` file, but instead create a local +``docker-compose.override.yml`` that includes all your modifications. +Docker compose will `automatically load this file and merge its changes into your stack `_. From 03d602de6895e978faff75d716f23eb6b79818ee Mon Sep 17 00:00:00 2001 From: Martin Gruner Date: Wed, 5 Mar 2025 13:35:17 +0100 Subject: [PATCH 13/18] wording --- install/docker-compose.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/docker-compose.rst b/install/docker-compose.rst index d779b497..7aa8782e 100644 --- a/install/docker-compose.rst +++ b/install/docker-compose.rst @@ -104,7 +104,7 @@ Exposing the Stack via HTTPS ---------------------------- To publish a Zammad stack on the internet, it needs be secured via the HTTPS -protocol. With the Zammad stack, you can: +protocol. To achieve that without modifying the Zammad stack, you can: - Use a reverse proxy like Nginx Proxy Manager (NPM). It has a GUI that provides an easy `Letsencrypt `_ integration. From 09b548a8ab83f8bb23f9bc37f3fcda5c309b7e15 Mon Sep 17 00:00:00 2001 From: Martin Gruner Date: Wed, 5 Mar 2025 13:55:22 +0100 Subject: [PATCH 14/18] wording, styling --- .../docker-compose-scenarios.rst | 56 ++++++++----------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/install/docker-compose/docker-compose-scenarios.rst b/install/docker-compose/docker-compose-scenarios.rst index a54f05ff..814cd88c 100644 --- a/install/docker-compose/docker-compose-scenarios.rst +++ b/install/docker-compose/docker-compose-scenarios.rst @@ -6,29 +6,22 @@ Overview If the "vanilla" Zammad stack doesn't cover your use-case, you can use one of the pre-defined scenarios. We don't recommend to change the compose files -locally because upstream changes for the stack aren't reflected automatically +locally, because it will be hard to keep track of upstream changes for the stack then. This is why you should either use Portainer's repository build method or clone the repository and update it regularly, when using docker compose. -The following scenarios are supported: - -- Making the stack available via HTTPS +The following scenarios are supported and explained further below: +Making the stack available via HTTPS - Add a Cloudflare tunnel service to the stack - Add a Nginx Proxy Manager (NPM) to the stack - Add an external docker network to Nginx - -- Using external services - +Using external services - Disable Elasticsearch service - -- Making services externally available - +Making services externally available - Add an external docker network to Elasticsearch - Add an host port to Elasticsearch - -- Additional scenarios - +Additional scenarios - Disable the backup service You can find the files in the @@ -72,29 +65,27 @@ Making the Stack Available via HTTPS ------------------------------------ If you set up Zammad for production use, it needs to be secured by using an -HTTPS connection. Because this can be achieved in different ways, we added 3 -different scenarios. +HTTPS connection. There are different scenarios for achieving this: Add Cloudflare Tunnel ^^^^^^^^^^^^^^^^^^^^^ -If you want to publish Zammad in a very easy way and without taking -care about e.g. SSL certificates, you can use a +If you want to publish Zammad in a very convenient way, you can use a `Cloudflare `_ tunnel. - Use the scenario file ``scenarios/add-cloudflare-tunnel.yml`` for deployment - Add a sub-domain to an already existing domain in your Cloudflare dashboard -- Forward it to your Zammad Nginx instance with port ``8080`` -- Create a tunnel. This is where you get your token for the next step -- Provide your Cloudflare token by using the environment variable - ``CLOUDFLARE_TUNNEL_TOKEN`` +- Create a tunnel for this subdomain and configure it to forward traffic + to your zammad-nginx service with ``http://zammad-nginx:8080`` +- Provide your Cloudflare tunnel token to the Zammad stack by using the + environment variable ``CLOUDFLARE_TUNNEL_TOKEN`` Add Nginx Proxy Manager ^^^^^^^^^^^^^^^^^^^^^^^ A very common setup of publishing web services is to use a reverse proxy, which handles the SSL termination. One common tool is the Nginx Proxy Manager (NPM), -which can be configured via UI quite simple. If you don't have a reverse +which can be configured via UI quite simply. If you don't have a reverse proxy already, this might be a useful scenario for you. If you already have a running reverse proxy, head over to the next section. @@ -110,7 +101,8 @@ Add External Docker Network to Nginx If you already have a reverse proxy which takes care about the SSL termination, this scenario is helpful. It adds an external docker network to Zammad's -included Nginx service to be able to access it from a separated reverse proxy. +included Nginx service to be able to access it from a reverse proxy that is not part +of the Zammad stack's network. - Use the scenario file ``scenarios/add-external-network-to-nginx.yml`` for deployment - Provide the name of your external network by using the environment @@ -123,11 +115,11 @@ Disable Elasticsearch Service ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do you have an Elasticsearch instance already running and want to use it for -Zammad too? Then you can disable the Elasticsearch service in the Zammad stack +Zammad, too? Then you can disable the Elasticsearch service in the Zammad stack to save resources. - Use the scenario file ``scenarios/disable-elasticsearch-service.yml`` for - deployment + deployment - this will turn off the built-in service for Elasticsearch - Use the following environment variables to provide information about the connection to your existing Elasticsearch instance: @@ -140,9 +132,9 @@ to save resources. Making Services Externally Available ------------------------------------ -These scenarios are meant to connect from external services to Zammad -services and vice versa. Depending on where your external service is hosted, -use one of the following scenarios. +These scenarios are meant to connect from external applications to Zammad +services. Depending on where your external service is hosted, you can use one +of the following scenarios. Add External Docker Network to Elasticsearch @@ -151,7 +143,7 @@ Add External Docker Network to Elasticsearch A common use case for this is to use a reporting/visualization tool like Grafana on the same host in another stack. Because such tools need to access the Elasticsearch index, the network of the other stack has to be added to Zammad's -Elasticsearch Container. +Elasticsearch container. - Use the scenario file ``scenarios/add-external-network-to-elasticsearch.yml`` for deployment @@ -162,7 +154,7 @@ Add Host Port to Elasticsearch ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In case you want to expose the Elasticsearch service of the Zammad stack in the -network, you can assign a port to the container. This is useful if you need to +network, you can assign a host port to the container. This is useful if you need to access the Elasticseach container from a different host. - Use the scenario file ``scenarios/add-hostport-to-elasticsearch.yml`` for @@ -184,8 +176,8 @@ You can do so by just using the scenario file Other Use Cases ^^^^^^^^^^^^^^^ -Your scenario is not covered? Feel free to suggest your use case. If we consider -it as an important scenario, we include it in the repository then. +Your scenario is not covered yet? Feel free to suggest your use case. +We plan to add more common use cases to the stack in future. Customize the Stack Locally --------------------------- From 89e4e893b1855645d8618c83656c89e9c3d799d8 Mon Sep 17 00:00:00 2001 From: Ralf Schmid Date: Wed, 5 Mar 2025 14:04:03 +0100 Subject: [PATCH 15/18] Moved Portainer and Docker Compose into tabs, changed section heading --- .../docker-compose-scenarios.rst | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/install/docker-compose/docker-compose-scenarios.rst b/install/docker-compose/docker-compose-scenarios.rst index 814cd88c..01e86c3f 100644 --- a/install/docker-compose/docker-compose-scenarios.rst +++ b/install/docker-compose/docker-compose-scenarios.rst @@ -27,38 +27,45 @@ Additional scenarios You can find the files in the `Zammad-Docker-Compose repository `_. -Usage with Portainer --------------------- +General Usage +------------- + +.. tabs:: + + .. tab:: + + Portainer + + Follow the + :doc:`general deployment guide <../docker-compose>` + and apply the following changes. -Follow the -:doc:`general deployment guide <../docker-compose>` -and apply the following changes. + Below the "Compose path" field, click on the **Add file** button. This opens + the "Additional paths" section where you can specify the scenario you want to + use. Add ``scenarios/{scenario you want to use}.yml`` and replace the last + part in ``{}`` brackets with the name of one of the scenario files. You can + even combine the scenarios by adding additional paths. -Below the "Compose path" field, click on the **Add file** button. This opens -the "Additional paths" section where you can specify the scenario you want to -use. Add ``scenarios/{scenario you want to use}.yml`` and replace the last -part in ``{}`` brackets with the name of one of the scenario files. You can -even combine the scenarios by adding additional paths. + .. figure:: /images/install/docker-compose/additional-scenarios/portainer-additional-paths.png + :alt: Screenshot shows where to add additional paths in Portainer + :scale: 70% -.. figure:: /images/install/docker-compose/additional-scenarios/portainer-additional-paths.png - :alt: Screenshot shows where to add additional paths in Portainer - :scale: 70% + .. tab:: -Usage with Docker Compose -------------------------- + Docker Compose -Follow the first 2 steps of the -:doc:`general deployment guide <../docker-compose>`. To start the stack with -one or more additional scenarios, use the following command for step 3 in -the cloned repository folder instead: + Follow the first 2 steps of the + :doc:`general deployment guide <../docker-compose>`. To start the stack with + one or more additional scenarios, use the following command for step 3 in + the cloned repository folder instead: -.. code-block:: sh + .. code-block:: sh - docker compose -f docker-compose.yml -f scenarios/{scenario you want to use}.yml up -d + docker compose -f docker-compose.yml -f scenarios/{scenario you want to use}.yml up -d -Replace the part in ``{}`` brackets with the file name of one of the scenario -files. You can even combine the scenarios by adding additional files according -to the example above. + Replace the part in ``{}`` brackets with the file name of one of the scenario + files. You can even combine the scenarios by adding additional files according + to the example above. Making the Stack Available via HTTPS From 46f0730573ae77e877d1eb286f1957004c9d0374 Mon Sep 17 00:00:00 2001 From: Ralf Schmid Date: Wed, 5 Mar 2025 14:12:27 +0100 Subject: [PATCH 16/18] Linked scenarios --- .../docker-compose-scenarios.rst | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/install/docker-compose/docker-compose-scenarios.rst b/install/docker-compose/docker-compose-scenarios.rst index 01e86c3f..5d596960 100644 --- a/install/docker-compose/docker-compose-scenarios.rst +++ b/install/docker-compose/docker-compose-scenarios.rst @@ -12,16 +12,23 @@ clone the repository and update it regularly, when using docker compose. The following scenarios are supported and explained further below: -Making the stack available via HTTPS +- :ref:`Making the stack available via HTTPS ` + - Add a Cloudflare tunnel service to the stack - Add a Nginx Proxy Manager (NPM) to the stack - Add an external docker network to Nginx -Using external services + +- :ref:`Using external services ` + - Disable Elasticsearch service -Making services externally available + +- :ref:`Making services externally available ` + - Add an external docker network to Elasticsearch - Add an host port to Elasticsearch -Additional scenarios + +- :ref:`Additional scenarios ` + - Disable the backup service You can find the files in the @@ -67,6 +74,7 @@ General Usage files. You can even combine the scenarios by adding additional files according to the example above. +.. _stack-https: Making the Stack Available via HTTPS ------------------------------------ @@ -115,6 +123,8 @@ of the Zammad stack's network. - Provide the name of your external network by using the environment variable ``ZAMMAD_NGINX_EXTERNAL_NETWORK`` +.. _external-services: + Using External Services ----------------------- @@ -136,6 +146,8 @@ to save resources. - ``ELASTICSEARCH_USER`` - ``ELASTICSEARCH_PASS`` +.. _external-availability: + Making Services Externally Available ------------------------------------ @@ -168,6 +180,8 @@ access the Elasticseach container from a different host. deployment - Access your ES service under port ``9200`` +.. _additional-scenarios: + Additional Scenarios -------------------- From fd371cb8c732bdf52446ae714640954c1b995766 Mon Sep 17 00:00:00 2001 From: Ralf Schmid Date: Wed, 5 Mar 2025 14:32:20 +0100 Subject: [PATCH 17/18] Added warning and note about ES security --- install/docker-compose/docker-compose-scenarios.rst | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/install/docker-compose/docker-compose-scenarios.rst b/install/docker-compose/docker-compose-scenarios.rst index 5d596960..c53ad391 100644 --- a/install/docker-compose/docker-compose-scenarios.rst +++ b/install/docker-compose/docker-compose-scenarios.rst @@ -155,6 +155,10 @@ These scenarios are meant to connect from external applications to Zammad services. Depending on where your external service is hosted, you can use one of the following scenarios. +.. danger:: When exposing Elasticsearch outside the stack, make sure + to set the variable ``ELASTICSEARCH_PASS`` to a custom value first! + Otherwise this is a big security issue because the Elasticsearch index + contains most of Zammad's data. Add External Docker Network to Elasticsearch ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -169,16 +173,20 @@ Elasticsearch container. - Provide the name of your external network by using the environment variable ``ZAMMAD_ELASTICSEARCH_EXTERNAL_NETWORK`` +.. hint:: If you want to use TLS, you have to connect to Elasticsearch via + reverse proxy. + Add Host Port to Elasticsearch ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In case you want to expose the Elasticsearch service of the Zammad stack in the network, you can assign a host port to the container. This is useful if you need to -access the Elasticseach container from a different host. +access the Elasticsearch container from a different host. - Use the scenario file ``scenarios/add-hostport-to-elasticsearch.yml`` for deployment -- Access your ES service under port ``9200`` +- The default port for Elasticsearch is ``9200``. Change it to another + port by using the environment variable ``ELASTICSEARCH_EXPOSE_HTTP_PORT`` .. _additional-scenarios: From 367bf27f436dfbbd557128ceec9ee6d0c6e85387 Mon Sep 17 00:00:00 2001 From: Ralf Schmid Date: Wed, 5 Mar 2025 14:35:10 +0100 Subject: [PATCH 18/18] Moved hint box --- install/docker-compose/docker-compose-scenarios.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/docker-compose/docker-compose-scenarios.rst b/install/docker-compose/docker-compose-scenarios.rst index c53ad391..de537ed8 100644 --- a/install/docker-compose/docker-compose-scenarios.rst +++ b/install/docker-compose/docker-compose-scenarios.rst @@ -160,6 +160,9 @@ of the following scenarios. Otherwise this is a big security issue because the Elasticsearch index contains most of Zammad's data. +.. hint:: If you want to use TLS, you have to connect to Elasticsearch via + reverse proxy. + Add External Docker Network to Elasticsearch ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -173,9 +176,6 @@ Elasticsearch container. - Provide the name of your external network by using the environment variable ``ZAMMAD_ELASTICSEARCH_EXTERNAL_NETWORK`` -.. hint:: If you want to use TLS, you have to connect to Elasticsearch via - reverse proxy. - Add Host Port to Elasticsearch ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^