Deploy Chatwoot on Vultr Kubernetes Engine using Helm Charts

Introduction

Chatwoot is an open-source customer engagement platform designed to improve business processes. You can integrate the application with multiple communication channels such as email, website live chat, and social media applications to manage all customer communications in a single dashboard.

This guide explains how to deploy Chatwoot on a Vultr Kubernetes Engine (VKE) cluster using Helm Charts. To extend the Chatwoot functionalities, you will integrate Vultr Object Storage, a Vultr Managed Database for PostgreSQL, and a Vultr Managed Database for Redis to run the application in your cluster.

Prerequisites

Before you begin:

  • Deploy a Vultr Kubernetes Engine (VKE) Optimized Cloud Compute cluster with at least 3 nodes
  • Deploy a Vultr Managed Database for PostgreSQL to store Chatwoot database values
  • Deploy a Vultr Managed Database for Redis
  • Deploy a Vultr Object Storage instance to store critical Chatwoot data
  • Deploy a Vultr Ubuntu server to use as the management instance
  • Access the server using SSHas a non-root user with sudo privileges
  • Install and Configure Kubectl to access your VKE cluster
  • Install the Helm package manager:CONSOLECopy$ sudo snap install helm –classic
  • Install the PostgreSQL psql client tool to access the database:CONSOLECopy$ apt install postgresql-client

Set Up the Chatwoot Database

  1. Log in to your Vultr Managed Database for PostgreSQL. Replace vultradminpostgres-334h.vultrdb.com, and 5432 with your actual database details.CONSOLECopy$ psql -h postgres-334h.vultrdb.com -p 5432 -U vultradmin You can find your Vultr Database for PostgreSQL details in the connection details section on your cluster control panel.Get PostgreSQL URL
  2. Create a new Chatwoot database.SQLCopydefaultdb=> CREATE DATABASE chatwoot;
  3. Create a new database user. For example exampleuser with a strong password.SQLCopydefaultdb=> CREATE USER exampleuser WITH PASSWORD ‘strong-password’;
  4. Grant the user full privileges to the Chatwoot database.SQLCopydefaultdb=> GRANT ALL PRIVILEGES ON DATABASE chatwoot TO exampleuser;
  5. Exit the PostgreSQL database console.SQLCopydefaultdb=> \q

Set Up the VKE Cluster

To deploy Chatwoot to your cluster, install the Nginx Ingress controller to handle incoming requests, and Cert-Manager to handle the certificate issuance process to your configured domain name. Set up the project directory, download the default Chatwoot configuration file, and install all necessary packages to your cluster as described in the steps below.

  1. Create a new chatwoot-app directory.CONSOLECopy$ mkdir chatwoot-app
  2. Switch to the directory.CONSOLECopy$ cd chatwoot-app
  3. Download the default Chatwoot Helm configuration values file.CONSOLECopy$ wget https://raw.githubusercontent.com/chatwoot/charts/main/charts/chatwoot/values.yaml The values.yaml file contains default configurations and environment variables you should modify before deploying Chatwoot in a cluster.
  4. Using Helm, add the Chatwoot repository to your server.CONSOLECopy$ helm repo add chatwoot https://chatwoot.github.io/charts
  5. Add the Nginx Ingress Controller repository.CONSOLECopy$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
  6. Add the Cert-Manager repository.CONSOLECopy$ helm repo add jetstack https://charts.jetstack.io
  7. Update your Helm Repositories to fetch the latest Chart information.CONSOLECopy$ helm repo update
  8. Install the Nginx Ingress Controller to your cluster.CONSOLECopy$ helm install ingress-nginx ingress-nginx/ingress-nginx
  9. Install Cert-Manager to handle the SSL certificate operations.CONSOLECopy$ helm install cert-manager jetstack/cert-manager –namespace cert-manager –create-namespace –set installCRDs=true
  10. When successful, view the cluster services and verify the Load Balancer external IP address assigned to your Ingress Controller.CONSOLECopy$ kubectl get services ingress-nginx-controller Output:NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller LoadBalancer 10.96.132.148 192.168.10.1 80:30827/TCP,443:30274/TCP 6m9sIf the external IP is in <pending> state, wait for at least 3 minutes and view the cluster services again.
  11. Access your domain DNS records and create a new A record that points to your load balancer external IP address.

Modify the Chatwoot Configuration Values

  1. Using the OpenSSL utility, generate a random secret key.CONSOLECopy$ openssl rand -hex 32 Copy the random key generated in your output like the one below:632830c6d5a23e46d73bdc362dd05d34c85d969b4ab0f5f675e8ea6d7dfaa335
  2. Using a text editor such as Nano, open the values.yaml file.CONSOLECopy$ nano values.yaml
  3. Find the SECRET_KEY_BASE declaration in the env section.YAMLCopySECRET_KEY_BASE: replace_with_your_super_duper_secret_key_base Replace the default value with the string key you generated earlier. For example:YAMLCopySECRET_KEY_BASE: 632830c6d5a23e46d73bdc362dd05d34c85d969b4ab0f5f675e8ea6d7dfaa335 Save and close the file.

Configure Vultr Object Storage

Follow the steps in this section to add Vultr Block Storage to your Chatwoot configuration to store chat attachments within the application.

  1. Edit the values.yaml file.CONSOLECopy$ nano values.yaml
  2. Find the ACTIVE_STORAGE_SERVICE declaration in the env: section, and change the value from local to s3_compatible.YAMLCopyACTIVE_STORAGE_SERVICE: s3_compatible
  3. Scroll to the end of the file, and add the following declarations.Replace the example values with your actual Vultr Object Storage details:YAMLCopySTORAGE_BUCKET_NAME: chatwoot-prod STORAGE_ACCESS_KEY_ID: vultr-object-storage-access-key STORAGE_SECRET_ACCESS_KEY: vultr-object-storage-secret-key STORAGE_REGION: ewr1 STORAGE_ENDPOINT: https://ewr1.vultrobjects.com Save and close the file.Below is what each of the above YAML declarations represent:
    • STORAGE_BUCKET_NAME: Your Vultr Object Storage bucket name
    • STORAGE_ACCESS_KEY_ID: Your Vultr Object Storage Access Key
    • STORAGE_SECRET_ACCESS_KEY: The Vultr Object Storage Secret Key
    • STORAGE_REGION: Defines your Vultr Object Storage deployment region. ewr1 represents the Vultr New Jersey region. You can identify your Object Storage region depending on your host URL. For example, the ewr1 region uses ewr1.vultrobjects.com
    • STORAGE_ENDPOINT: Sets your Vultr Object Storage Hostname with secure access over HTTPS
    You can find your Vultr Object Storage details in your instance Overview tab.Vultr Object Storage Credentials

Set Up the Vultr Managed Database for PostgreSQL Connection

  1. Edit the values.yaml file.CONSOLECopy$ nano values.yaml
  2. Find the following postgresql section:YAMLCopypostgresql: enabled: true nameOverride: chatwoot-postgresql auth: username: postgres postgresPassword: postgres database: chatwoot_production # when existingSecret is defined auth.password, auth.PostgressPassword # is ignored. # existingSecret: secret-name # secretKeys: # adminPasswordKey: postgres-password # replicationPasswordKey: replication-password # The following variables are only used when internal PG is disabled # postgresqlHost: postgres # postgresqlPort: 5432
  3. Set the enabled value to false, and replace the default values with your actual Vultr Managed Database for PostgreSQL details similar to the ones below:YAMLCopypostgresql: enabled: false nameOverride: chatwoot-postgresql auth: username: exampleuser postgresPassword: strong-password database: chatwoot # when existingSecret is defined auth.password, auth.PostgressPassword # is ignored. # existingSecret: secret-name # secretKeys: # adminPasswordKey: postgres-password # replicationPasswordKey: replication-password # The following variables are only used when internal PG is disabled postgresqlHost: postgres-334h.vultrdb.com postgresqlPort: 5432 Save and close the file.Below is what the PostgreSQL section declarations represent:
    • enabled: Sets the database type Chatwoot should use. When set to false, Chatwoot uses your Vultr Managed Database for PostgreSQL instead of deploying a cluster PostgreSQL pod
    • username: Defines your PostgreSQL database username
    • postgresPassword: Defines the PostgreSQL user password to use for connecting to the database
    • database: Sets the PostgreSQL Chatwoot database
    • postgresqlHost: Sets the Vultr Managed Database for PostgreSQL host URL to connect the Chatwoot database
    • postgresqlPort: Sets your PostgreSQL database port to connect using the database host URL
    You can find your Vultr Managed Database for PostgreSQL details in your cluster control panel connection details tab.PostgreSQL Connection Details

Enable the Vultr Managed Database for Redis Connection to handle Queues and Cache Storage

  1. Edit the values.yaml file.CONSOLECopy$ nano values.yaml
  2. Find the following redis section.YAMLCopyredis: enabled: true nameOverride: chatwoot-redis auth: password: redis # when defined the password field is ignored # existingSecret: secret-name # existingSecretPasswordKey: “” # The following variables are only used when internal Redis is disabled # host: redis # Just omit the password field if your redis cluster doesn’t use password # password: redis # port: 6379 master: persistence: enabled: true # If change pvc size redis.master.persistence.size: 20Gi replica: replicaCount: 1
  3. Set the enabled: value to false, and replace the default values with your actual Vultr Managed Database for Redis details.YAMLCopyredis: enabled: false nameOverride: chatwoot-redis auth: password: redis # The following variables are only used when internal Redis is disabled host: [VULTR_REDIS_HOSTNAME] # Just omit the password field if your redis cluster doesn’t use password password: [VULTR_REDIS_PASSWORD] port: [VULTR_REDIS_PORT] master: persistence: enabled: true replica: replicaCount: 1 Below is what the database values represent:
    • enabled: Sets the Chatwoot Redis database server location. When set to false, Chatwoot uses the Vultr Managed Database values and disables the internal cluster Redis pods
    • host: Defines your Vultr Managed Database for Redis host URL.
    • password: Sets your Vultr Managed Database for Redis password. Iignore the password declaration in the auth section because it’s only used with the cluster Redis installation.
    • port: Sets your Vultr Managed Database for Redis port to connect to the database host.
    You can find your Vultr Managed Database for Redis host URL, port, and password in the Connection Details section within your cluster control panel Overview tab.Redis connection details
  4. Scroll to the env section and set the REDIS_TLS value to true.YAMLCopyREDIS_TLS: true Save and close the file.

Add Nginx Ingress Configurations to the Chatwoot Helm Configuration File

To correctly route and forward incoming external traffic to your Chatwoot application, modify the services and ingress sections as described in the steps below.

  1. Edit the values.yaml.CONSOLECopy$ nano values.yaml
  2. Find the following services parameter.YAMLCopyservices: name: chatwoot internalPort: 3000 targetPort: 3000 type: LoadBalancer annotations: {} Change the type declaration value from LoadBalancer to ClusterIP:YAMLCopytype: ClusterIP The modified services section should look like the one below:YAMLCopyservices: name: chatwoot internalPort: 3000 targetPort: 3000 type: ClusterIP annotations: {}
  3. Find the following ingress section.YAMLCopyingress: enabled: false # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress # ingressClassName: nginx annotations: {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: “true” hosts: – host: “” paths: – path: / pathType: Prefix backend: service: name: chatwoot port: number: 3000 tls: [] # – secretName: chart-example-tls # hosts: # – chart-example.local Change the enabled value from false to true.YAMLCopyenabled: true Remove the # comment value on the ingressClassName declaration to activate the Nginx Ingress Controller.YAMLCopyingressClassName: nginx Within the annotations section, uncomment the kubernetes.io/ingress.class annotationYAMLCopyannotations: kubernetes.io/ingress.class: nginx Scroll to the hosts section and replace the host value with your Chatwoot domain name. Replace chatwoot.example.com with your actual domain name that points to the Ingress Controller Load Balancer External IP Address.YAMLCopyhosts: – host: chatwoot.example.com paths: – path: / pathType: Prefix backend: service: name: chatwoot port: number: 3000 Save and close the file.The modified ingress section should look like the one below:YAMLCopyingress: enabled: true # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress ingressClassName: nginx annotations: kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: “true” hosts: – host: chatwoot.example.com paths: – path: / pathType: Prefix backend: service: name: chatwoot port: number: 3000 tls: [] # – secretName: chart-example-tls # hosts: # – chart-example.local
  4. Using Helm, install Chatwoot with the values.yaml configurations to your Vultr Kubernetes Engine cluster.CONSOLECopy$ helm install chatwoot chatwoot/chatwoot -f values.yaml When successful, your output should look like the one below:NAME: chatwoot LAST DEPLOYED: Mon Oct 16 16:05:24 2023 NAMESPACE: default STATUS: deployed REVISION: 1 NOTES: Thank you for installing chatwoot. Your release is named chatwoot. To learn more about the release, try: $ helm status chatwoot $ helm get all chatwoot NOTE: It may take a few minutes for the LoadBalancer IP to be available. You can watch the status by running 'kubectl get svc -w chatwoot' export SERVICE_IP=$(kubectl get svc --namespace default chatwoot -o jsonpath='{.status.loadBalancer.ingress[0].ip}') echo http://$SERVICE_IP:3000
    • The deployment should take about 10 minutes to complete depending on your cluster node type.
    • If you receive the following deployment error:Error: INSTALLATION FAILED: failed post-install: timed out waiting for the condition
    Verify and make changes to your Vultr Managed Database for PostgreSQL details in the values.yaml file.
  5. View your cluster pods and verify that all Chatwoot pods are running.CONSOLECopy$ kubectl get pods Output:NAME READY STATUS RESTARTS AGE chatwoot-web-666b5bdb69-vp5bd 1/1 Running 0 2m55s chatwoot-worker-ffccccd4-4j8l4 1/1 Running 0 2m55s chatwoot-worker-ffccccd4-n6272 1/1 Running 0 2m55s ingress-nginx-controller-84bd4cb7ff-h8ght 1/1 Running 0 4m54sVerify that all pods are ready and running in your cluster to use your Chatwoot application.

Generate Let’s Encrypt SSL Certificates using Cert-Manager

  1. Create a new Let’s Encrypt issuer resource file. For example chatwoot-issuer to use as Let’s Encrypt Issuer.CONSOLECopy$ nano production-issuer.yaml
  2. Add the following configurations to the file. Replace admin@example.com with your actual email address.YAMLCopyapiVersion: cert-manager.io/v1 kind: Issuer metadata: name: chatwoot-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: admin@example.com privateKeySecretRef: name: chatwoot-prod solvers: – http01: ingress: class: nginx Save and close the file.
  3. Deploy the issuer to your cluster.CONSOLECopy$ kubectl apply -f production-issuer.yaml
  4. View the cluster issuers and verify that the new resource is available.CONSOLECopy$ kubectl get issuer Output:NAME READY AGE chatwoot-prod True 39s
  5. To use the new Certificate Issuer, edit your values.yaml file.CONSOLECopy$ nano values.yaml
  6. Find the ingress section and uncomment the tls declaration values.YAMLCopytls: – secretName: chart-example-tls hosts: – chart-example.local Replace the default values with your actual details. For example, replace chart-example.local with your actual Chatwoot domain name, and chart-example-tls with your desired secret name.YAMLCopytls: – secretName: chatwoot-cert-secret hosts: – chartwoot.example.com
  7. Add the cert-manager issuer annotation to your annotations section to use the new tls section values.YAMLCopycert-manager.io/issuer: letsencrypt-prod Save and close the file.Your modified Ingress section should look like the one below:YAMLCopyingress: enabled: true # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress ingressClassName: nginx annotations: kubernetes.io/ingress.class: nginx cert-manager.io/issuer: letsencrypt-prod # kubernetes.io/tls-acme: “true” hosts: – host: newchat.onlustech.com paths: – path: / pathType: Prefix backend: service: name: chatwoot port: number: 3000 tls: – secretName: chartwoot-cert-secret hosts: – chartwoot.example.com
  8. Upgrade the Chatwoot application with your new values.yaml configuration.CONSOLECopy$ helm upgrade chatwoot chatwoot/chatwoot -f values.yaml When succesful, your output should look like the one below:Release "chatwoot" has been upgraded. Happy Helming! NAME: chatwoot LAST DEPLOYED: Mon Oct 16 16:25:12 2023 NAMESPACE: default STATUS: deployed REVISION: 2 NOTES: Thank you for installing chatwoot. Your release is named chatwoot. To learn more about the release, try: $ helm status chatwoot $ helm get all chatwoot NOTE: It may take a few minutes for the LoadBalancer IP to be available. You can watch the status by running 'kubectl get svc -w chatwoot' export SERVICE_IP=$(kubectl get svc --namespace default chatwoot -o jsonpath='{.status.loadBalancer.ingress[0].ip}') echo http://$SERVICE_IP:3000
  9. Verify that all pods are running.CONSOLECopy$ kubectl get pods Output:NAME READY STATUS RESTARTS AGE pod/cert-manager-55657857dd-lp9dh 1/1 Running 0 6m1s pod/cert-manager-cainjector-7b5b5d4786-8wqnb 1/1 Running 0 6m1s pod/cert-manager-webhook-55fb5c9c88-d5wlq 1/1 Running 0 6m1s pod/chatwoot-web-666b5bdb69-vp5bd 1/1 Running 0 16m pod/chatwoot-worker-ffccccd4-4j8l4 1/1 Running 0 16m pod/chatwoot-worker-ffccccd4-n6272 1/1 Running 0 16m pod/ingress-nginx-controller-84bd4cb7ff-h8ght 1/1 Running 0 18m

Test: Access your Chatwoot Application

  1. Using a web browser such as Firefox, access your Chatwoot domain name.https://chatwoot.example.com
  2. Verify that the Chatwoot onboarding page displays in your browser.Chatwoot onboarding page
  3. Verify that your domain name uses a valid SSL certificate.Chatwoot valid cluster SSL certificate
  4. Fill in the NameCompany NameEmail and Password fields with your details. Then, click Finish Setup to save the new administrator details.The Chatwoot onboarding page
  5. Login to Chatwoot using your administrator email and password to access the application dashboard.Chatwoot application dashboard

Conclusion

You have deployed a Chatwoot instance to a Vultr Kubernetes Engine (VKE) cluster using Helm. In addition, you integrated a Vultr Managed Database for PostgreSQL, Vultr Object Storage and a Vultr Managed Database for Redis to extend the Chatwoot production environment functionalities.

Introduction Chatwoot is an open-source customer engagement platform designed to improve business processes. You can integrate the application with multiple communication channels such as email, website live chat, and social media applications to manage all customer communications in a single dashboard. This guide explains how to deploy Chatwoot on a…

Introduction Chatwoot is an open-source customer engagement platform designed to improve business processes. You can integrate the application with multiple communication channels such as email, website live chat, and social media applications to manage all customer communications in a single dashboard. This guide explains how to deploy Chatwoot on a…

Leave a Reply

Your email address will not be published. Required fields are marked *