Table of Contents

Customizing Your Customer Portal

Mitchell Paul-Soumis Updated by Mitchell Paul-Soumis

Read Time: 7 mins

Disclaimer: Sonar provides a pre-built customer portal, however, we understand that you may have a desire to alter or customize it to suit your business needs. Because of this, we provide information within this article on how you can go about doing so, if required, and provide access to the Sonar Customer Portal code repository so that you can fork or clone it to modify the underlying code.

However, we are unable to test the changes you make and can't predict what will happen when someone customizes the code to suit their needs. For this reason, our Support team is unable to provide assistance for portals that have been forked or customized, nor for the process of forking or customizing the portal; the party who changes the underlying code we provide assumes responsibility to support and maintain their code and will need to perform testing to ensure it's working as expected. If you do choose to customize the portal, be sure to document the steps taken and the changes made so that you can have a plan in place to remove the customizations before contacting Sonar Support.

While Sonar provides a pre-built Customer Portal that can be tied to your instance and used to provide more control to your customers, we want to avoid limiting your creativity, branding, or controlling how your customers access their information. The Sonar Customer Portal code repository is available on, and you're welcome to fork or clone this repository to modify the underlying code to suit your needs.

Don't modify the files inside the existing Docker Container without redirecting the GitHub link, as updates will overwrite all changes during an update

Before you get started

As you explore this document and customize your Customer Portal, you'll need to make sure that changes to your docker-compose.yaml take effect. If you've already run the Customer Portal container before making any changes, you'll need to run the following commands:

  1. Take the docker container down and remove any leftover elements
docker-compose down --remove-orphans
  1. Bring the docker container back up with the new "docker-compose.yml" file we've just created
docker-compose up --build -d

Cloning the Repository

Note that the customer portal will no longer run on Ubuntu 16.X, and will have to be upgraded to a newer distro. You can find instructions here | Upgrading your Ubuntu OS - Customer Portal Upgrades

For cloning the repository to make minor changes, you can follow the guide below:

  1. git clone the portal onto a droplet
droplet# git clone
  1. Modify the Docker Compose file:
droplet# nano ./customer_portal/docker-compose.yml
  1. Change image name in Docker Compose file from

image: "sonarsoftware/customerportal:stable"

to a unique name. In this example, we'll be changing it to "image: customized:stable"

  1. Remove the lines containing "watchtower"
Currently, this occupies line 40-45, however, it's important to note these line numbers may change as updates are made to the portal.

40 watchtower:

41 image: v2tec/watchtower

42 restart: always

43 volumes:

44 - /var/run/docker.sock:/var/run/docker.sock

45 command: sonar-customerportal

  1. Save the modified "docker-compose.yml"

Customization Example: Remove the ability to delete a payment method

  1. Enter the source file to the specific location housing billing parameters:
droplet#nano ./customer_portal/resources/views/pages/billing/index.blade.php
  1. Remove lines 321 - 326 & 391 - 396 (inclusive)
  2. Save "Index.blade.php"

Customization Example: Disable the Auto-Pay toggle

Because the EU and Australia mandate that explicit consent be given by the customer to have Auto-Pay enabled, this customization should NOT be performed if you have customers in those locations
  1. Enter the source file to the specific location housing billing parameters:
droplet#nano ./customer_portal/resources/views/pages/billing/index.blade.php
  1.  Remove lines 308 - 320, which contains the Auto-pay toggle code:
1 @if($paymentMethod->auto == 1)
2 {!! Form::open(['action' => ["BillingController@toggleAutoPay",$paymentMethod->id],'id' => 'deletePaymentMethodForm', 'method' => 'patch']) !!}
3 <button class="dropdown-item btn btn-sm btn-danger" onClick="submit(); this.disabled=true;this.innerHTML='<i class="fe fe-loader mt-2 mr-2 "></i> {{utrans("billing.disabling")}}'">
4 <i class="fe fe-minus-circle mr-2"></i> {{utrans("billing.disableAuto")}}
5 </button>
6 {!! Form::close() !!}
7 @else
8 {!! Form::open(['action' => ["BillingController@toggleAutoPay",$paymentMethod->id],'id' => 'deletePaymentMethodForm', 'method' => 'patch']) !!}
9 <button class="dropdown-item btn btn-sm btn-primary" onClick="submit(); this.disabled=true;this.innerHTML='<i class="fe fe-loader mt-2 mr-2"></i> {{utrans("billing.enabling")}}'">
10 <i class="fe fe-check-circle mr-2"></i> {{utrans("billing.enableAuto")}}
11 </button>
12 {!! Form::close() !!}
13 @endif
  1. Save "Index.blade.php"
  2. Modify Auto-pay on new credit card payments by entering the file which controls the logic for adding new cards:\
droplet#nano ./customer_portal/resources/views/pages/billing/add_card.blade.php
  1. Replace the following lines:
<div class="col mt-1">
{!! Form::checkbox("auto",1,false,['id' => 'auto', 'class' => 'custom-control-input']) !!}
<label class="custom-control-label" for="auto"></label>


<input type="hidden" id="auto" class="custom-control-input" name="auto" value="1">
Using this method, a user could disable this by entering the developer tools and setting "value=0"
  1. Because the above lines remove the toggle on the "Add Credit Card" page, we also want to remove the visible tooltip that contains the "Automatically charge this card for all future invoices" text:
<div class="col mt-1">
<small class="text-muted">

Customization Example: Using alternative SSL certificates

Sonar provides Let's Encrypt certificates for the portal domain you provide, and will automatically renew the certificate before its expiry, however, if you'd like to supply your own certificate, follow the steps below
  1. After your installation has completed, stop Certbot from running:
    docker-compose stop certbot
  2. Modify the Docker compose file:
    droplet# nano ./customer_portal/docker-compose.yml
  3. Comment out the entire section containing Certbot instructions. It should appear similar to the below:
      # certbot:
    # image: certbot/certbot
    # restart: always
    # entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
    # volumes:
    # - ./data/certbot/conf:/etc/letsencrypt
    # - ./data/certbot/www:/var/www/certbot
  4. Navigate to the storage location for your SSL certificates generated by Certbot:
    cd /data/certbot/conf/live/<CUSTOMERPORTAL HOST NAME>
  5. Replace the fullkey.pem and privkey.pem files with your certificates
  6. Restart the Nginx server within the Customer Portal:
    docker-compose exec app sv restart nginx

Your docker-compose.yml file should look something like this:

version: 'X.x'
context: .
dockerfile: Dockerfile
image: sonarsoftware/customerportal:stable
container_name: sonar-customerportal
restart: always
tty: true
- "80:80"
- "443:443"
- ./deploy/conf/nginx/sonar-customerportal.template:/etc/nginx/conf.d/sonar-customerportal.template
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
- ./public/assets/img/logo.png:/var/www/html/public/assets/img/logo.png
- ./public/assets/img/cover.png:/var/www/html/public/assets/img/cover.png
- storage:/var/www/html/storage
- .env
- redis

image: redis:5.0.4-alpine
restart: always

# certbot:
# image: certbot/certbot
# restart: always
# entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
# volumes:
# - ./data/certbot/conf:/etc/letsencrypt
# - ./data/certbot/www:/var/www/certbot

image: v2tec/watchtower
restart: always
- /var/run/docker.sock:/var/run/docker.sock
command: sonar-customerportal

driver: local

What about Portal Updates?

After you update your Sonar portal to the newest version, customizations will be cleared. While you could manually upload the custom files back into the upgraded portal, a more common method to reintroduce these customizations would be through synchronizing a fork. Below is the GitHub recommended approach to doing this:

The most up to date version of this information is available at

Syncing a fork

Sync a fork of a repository to keep it up-to-date with the upstream repository.

Before you can sync your fork with an upstream repository, you must configure a remote that points to the upstream repository in Git.

  1. Open Terminal.
  2. Change the current working directory to your local project.
  3. Fetch the branches and their respective commits from the upstream repository. Commits to master will be stored in a local branch, upstream/master.
    $ git fetch upstream
    > remote: Counting objects: 75, done.
    > remote: Compressing objects: 100% (53/53), done.
    > remote: Total 62 (delta 27), reused 44 (delta 9)
    > Unpacking objects: 100% (62/62), done.
    > From
    > * [new branch] master -> upstream/master
  4. Check out your fork's local master branch.
    $ git checkout master
    > Switched to branch 'master'
  5. Merge the changes from upstream/master into your local master branch. This brings your fork's master branch into sync with the upstream repository, without losing your local changes.
    $ git merge upstream/master
    > Updating a422352..5fdff0f
    > Fast-forward
    > README | 9 -------
    > | 7 ++++++
    > 2 files changed, 7 insertions(+), 9 deletions(-)
    > delete mode 100644 README
    > create mode 100644
    If your local branch didn't have any unique commits, Git will instead perform a "fast-forward":
    $ git merge upstream/master
    > Updating 34e91da..16c56ad
    > Fast-forward
    > | 5 +++--
    > 1 file changed, 3 insertions(+), 2 deletions(-)

How did we do?

Controlling Your Landing Page: Personal Preferences

Date/Time Picker: Overview