In the previous post in the series I described the process of externalizing you HA (Home Assistant) using my custom addon. Make sure to check that out if you haven’t already. This time I’ll share the details of the add-on development process.

First steps

When building the add-on my first steps obviously went towards the existing online resources. The first thing I’ve found was the extensive tutorial on, but there seems to be an easier hands-on approach. Instead of following the tutorial we’ll use the official template from

Anatomy of an addon

Each addon in HA is basically a docker container that can have an access to some of the HA resources. Installing an addon means running a docker container. This means that to build an addon we need to create a repository, build a Dockerfile and publish the built file.


From the HA point of view, to add a custom addon you need to add a repository. This directly relates to a git repository like this one

The structure of the repository is simple, you put a repository.yaml like this one:

name: Home Assistant add-on repository by majk-p
url: ''
maintainer: Michał Pawlik <>

And then each addon you create gets it’s own sub-directory in the repository. The complete directory structure looks like this:

├── repository.yaml
└── reverse-ssh-tunnel
    ├── build.yaml
    ├── config.yaml
    ├── Dockerfile
    ├── icon.png
    └── translations
        └── en.yaml


The simplest addon we can make consists of:

  • A bunch of markdown files like, and
  • Dockerfile describing how to build the addon
  • for the main logic
  • config.yaml describing the addon metadata, required permissions and configuration schema. The detailed guide on how to configure the plugin can be found in
  • build.yaml mainly for a list of base images to build from
  • translations/en.yaml (and similar for other languages) for configuration parameters description


Docker images for addons are based on base image. To be able to build against different architectures, a typical addon Dockerfile would start with


When designing a docker image you usually assume there is just one process running in the container. It’s not always true for the addons, so the base image comes with the process supervisor S6 using s6-overlay. If you just want your main script, make sure to go with init: false in the config file. Then make sure to run your script as the CMD.

The complete dockerfile might look like this:

USER root

    set -x \ 
    && apk add --no-cache \
        openssh \
        # add whatever dependencies you need

RUN chmod a+x /

CMD ["/"]

Now that the dockerfile is ready, let’s discuss the contents of the main script. In this place you might want to interact with the Home assistant to write logs, read config etc. The base image comes with built in utility called bashio. This is your interface for HA. To make sure it works in your script start it with the following shebang: #!/usr/bin/with-contenv bashio

This is how your might look like when interacting with the api.

#!/usr/bin/with-contenv bashio "Reverse tunnel initializing."

username=$(bashio::config 'username')
host=$(bashio::config '') "Reverse tunnel configured for $username@$host"

Please refer to for more detailed usage instructions.


If your plugin config has advanced: true, you need to enable advanced mode in your user profile.

To enable the plugin navigate to Settings -> Add-ons. Then on the bottom right select add-on store. Now on the top right launch three dot menu press repositories and paste in your git repository link. Make sure the link points to the repository root.

If everything is set up properly, your repository should now be visible and you’ll be able to configure your addon. In case something goes wrong, make sure to have a look into Settings -> System -> Logs and select Supervisor on the top right, the error message is usually helpful enough to sort out the problem.