Tag Archives: docker

Configuring an MQTT broker for Home Assistant

I recently purchased a ratgdo device to replace MyQ's kit for a local non-cloud dependent solution. ratgdo offers homekit, mqtt, and Control4, Nice/Elan, or Crestron integration. For this tutorial, I'm going to cover ratgdo and MQTT integration.

If you run Home Assistant as-is or are using their hardware, you can easily setup an MQTT broker by navigating to Add-Ons and installing the MQTT Broker, however in the past I have written articles on Home Assistant and Z-Wave JS as separate containers, so I wanted to follow the same concept by running the MQTT broker as a container as well.

Across the board, the consensus seems to be that most people are running Mosquitto as an MQTT broker, so here is how you can get that setup as a container.

  1. Download the docker image for Mosquitto
docker pull eclipse-mosquitto

2. Create directories for Mosquitto's config and data files. If desired, you can create one for logs as well, but I'm ok not persisting that.

mkdir /home/docker/mosquitto/
mkdir /home/docker/mosquitto/config
mkdir /home/docker/mosquitto/data

3. Create a configuration file for mosquitto. This file will configure what ports MQTT data should be listed on as well as its corresponding port for receiving data via WebSocket. In addition, we will define where data should be stored, and require authentication to be able to connect. For now, leave the password file, which contains the username/password combo for who can authenticate.

vi /home/docker/mosquitto/config/mosquitto.conf

Press i to enter insert mode and paste the following:

listener 1883 0.0.0.0
listener 9001 0.0.0.0
protocol websockets
persistence true
persistence_file mosquitto.db
persistence_location /mosquitto/data/
allow_anonymous false
#password_file /mosquitto/config/passwd

Type !wq to save and quit.

4. Start the mosquitto container. We'll map both the mqtt and websocket ports and volumes for config and data to persist.

docker run -d --restart=always --name="mosquitto-mqtt" -p 1883:1883 -p 9001:9001 -v /home/docker/mosquitto/config:/mosquitto/config -v /home/docker/mosquitto/data:/mosquitto/data eclipse-mosquitto

5. Launch shell on the container

docker exec -it -u 1883 mosquitto-mqtt sh

6. Use the mosquitto_passwd utility to generate an encrypted username and password. An ask for the password will prompt once you run the command. Type exit to return back to your local terminal.

mosquitto_passwd -c /mosquitto/config/passwd mqtt-user
exit

7. Modify your mosquitto.conf file.

vi /home/docker/mosquitto/config/mosquitto.conf

Uncomment the password file by removing the # sign and then type !wq to save and quit.

8. Restart the container so mosquitto will pickup the username/password

docker restart mosquitto-mqtt

At this point, your mqtt broker service should be up and ready! If you'd like to test connectivity and authentication, download a copy of MQTT MQTT Explorer | An all-round MQTT client that provides a structured topic overview (mqtt-explorer.com)

How to update Home Assistant Docker Container

Continuing from my previous guide on how to setup Home Assistant + Docker + Z-Wave + Raspberry Pi, this tutorial will show you how to update Home Assistant to the latest version. Updating Home Assistant to the latest version is critical to ensure you have the latest bug fixes, integrations, and security patches.

Note: during the update your devices will continue to work fine, but please note any automations or access to the application will not be available, so it's recommended to do this during a time that you know no automations will be running.

Validate your current version

Navigate to the Developer Tools section of Home Assistant. Here you can validate the latest version you currently have deployed.

Get the current name of your container and version

sudo docker ps

In running this command, note the NAME of your container as well as the IMAGE.

Stop and delete the container

Replace the name of the container in the command below with the value you had.

sudo docker stop home-assistant
sudo docker rm home-assistant

Update packages

Some versions of HA require newer versions of Python, Docker, etc. I may consider updating to latest package versions first.

sudo apt-get update
sudo apt-get upgrade

Pull the latest container from Docker Hub

Replace the value below with your IMAGE value you documented in the previous steps.

sudo docker pull ghcr.io/home-assistant/raspberrypi4-homeassi                                                                                                             stant:stable

Deploy the container

Make sure your replace the name and value of the image with the values in the previous step. In addition, ensure you specify the correct path to where you existing configuration files exist to have the container load your existing configurations.

sudo docker run -d --restart=always --name="home-assistant" -e "TZ=America/Chicago" --device=/dev/ttyACM0 -v /home/docker/home-assistant:/config --net=host ghcr.io/home-assistant/raspberrypi4-homeassistant:stable

Note: If you are now using the Z-Wave JS docker container, you will not want to attach the Z-Wave stick to the Home-Assistant container. In this case, run the following command:

sudo docker run -d --restart=always --name="home-assistant" -e "TZ=America/Chicago" -v /home/docker/home-assistant:/config --net=host ghcr.io/home-assistant/raspberrypi4-homeassistant:stable

Validate your version number

After a few minutes, navigate back to the Developers Tools page. Upon load, you should now be on the latest version of Home Assistant.

Notes:

You can find the latest, stable, and development builds out on docker hub here: https://hub.docker.com/u/homeassistant

For example, for raspberrypi4 builds, here you can validate the versions of all the different containers offered: https://hub.docker.com/r/homeassistant/raspberrypi4-homeassistant/tags

In newer versions of the docker container --init should not be specified in the docker run command. Specifying --init will result with the following error: "s6-overlay-suexec: fatal: can only run as pid 1". This was mentioned as a breaking change in: 2022-06-01 update: 2022.6: Gaining new insights! - Home Assistant (home-assistant.io)

Deploying Drupal on an Azure App Service Linux Docker Container

From a performance perspective, PHP applications running on Azure App Services tend to perform better on Linux than Windows.  While Azure provides a Drupal template in their Marketplace, it deploys to a regular Windows based App Service and installs version 8.3.3 (where as of the time of writing this article; 9/10/2018, the latest Drupal version is 8.6.1)

In this case, Microsoft has published a set of templates that provide flexibility to choose the Drupal version, deploy nginx, install PHP, and allow flexibility in installing any modules.  The templates are currently deployed and maintenace on GitHub, which can be found here: https://github.com/Azure/app-service-quickstart-docker-images/tree/master/drupal-nginx-fpm

So let's get started!

Download and install prerequisites:

  1. Download and install Git
  2. Download and install Docker
    1. Note: The above link is for Windows, here are the links to the other distributions for Docker: https://store.docker.com/search?offering=community&type=edition
    2. Note: On windows I recommend running the command git config core.autocrlf true to prevent issues with weird character returns.  Check out this awesome blog article by Tim Clem on why this is recommended: https://adaptivepatchwork.com/2012/03/01/mind-the-end-of-your-line/
  3. Download and install Visual Studio Code (free lightweight code editor for Windows, Linux, and Mac)

Note: I'm using a Windows 10 machine while writing this tutorial.  There will be some steps, like running Git Bash on Windows vs running Git natively on Linux.  Likely, you can just run Git from a regular terminal session and you'll be fine on the Linux/Mac side.

Clone the GitHub template

  1. Open up Git Bash
  2. Create a new directory for our project
    1. mkdir Drupal-Azure
    2. cd Drupal-Azure
  3. Clone the GitHub templat
    1. git clone https://github.com/Azure/app-service-quickstart-docker-images.git --config core.autocrlf=input
      1. Note: Unfortunately, we cannot just clone a specific directory easily, we have to download all the files.  This particular GitHub project contains several projects, so it'll be about a 50MB download as a heads up 
      2. Note: The --config core.autocrlf=input is used to prevent windows from using crlf vs lf's for line returns.  If you don't specify this, you might receive the following error if you tried running your docker container after being built:
        1. standard_init_linux.go:190: exec user process caused "no such file or directory"
  4. Navigate into the Drupal directory
    1. cd app-service-quickstart-docker-images/drupal-nginx-fpm/0.45

Modify the scripts to your desire

I personally prefer not to have PHPMyAdmin or MariaDB installed as I will leverage Azure MySQL PaaS services for the database.  In this case, I went ahead and modified the Dockerfile document accordingly.

Build the Docker container

Execute the following command to build your container:

docker build -t jackdrupalregistry.azurecr.io/azuredrupal:test .

Note: The . at the end is needed

Note: When building docker images, the repository name must be lowercase

Create Azure Container Registries

Select All Services -> Azure Container Registries.  Select Add and create a new container registry

Push the Docker container to your Azure Container Registry

  1. Navigate to  All Services -> Azure Container Registries -> Your Registry -> Access Keys
  2. Check Enable for Admin user
  3. Go back to Git Bash and execute the following commands
  4. Login to docker
    1. Execute the command:
      1. docker login jackdrupalregistry.azurecr.io -u yourusername -p yourpassword
  5. Push the image up to Azure Container Registry
    1. Execute the command:
      1. docker push jackdrupalregistry.azurecr.io/azuredrupal:test

Deploy the web app

Navigate to Create a resource -> Web App.  Select Docker as the OS type, select Configure container, and leverage the following settings:

  • Image Source: Azure Container Registry
  • Registry: jackdrupalregistry
  • Image: azuredrupal
  • Tag: 0.45

Navigate to All Services -> App Services -> Your App Service -> Application settings and set WEBSITES_ENABLE_APP_SERVICE_STORAGE to true, and click Save to help ensure data persists.  Essentially, anything you write to /home will persist.  Anything else will be reset when the container gets rebuilt.

Create a MySQL Database

Navigate to All Services -> App Services -> Your App Service -> Properties and write down the Outbound IP Addresses; we will use these later.

Select Create a Service -> Azure Database for MySQL -> Create -> create a blank database

Select Connection security and enter the Outbound IP Addresses from your App Service and click Save

Note: I haven't found a way to get Drupal to allow SSL Connections, which would certainly be a best practice.  In this case, on the same Connection security blade, go ahead and set Enforce SSL Connection to Disabled.  If someone knows how to do this, please put a comment below, so I can update this guide.

Go back to the Overview section and write down the Server admin login name and Server name; we will use these during the Drupal setup

Configure Drupal

At this point, go ahead and browse out to your App Service.  You should have all the necessary details to complete the installation setup.  Once completed, you should see the Welcome to Drupal Side splash page.

Notes:

Email:

Upon installation of Drupal you'll receive an error that Drupal cannot send email.  Azure Web Apps don't allow open relay, so you will need to use a 3rd party mail service like SendGrid or Mailchimp to relay emails.

Helpful docker commands:

docker images

docker run -it azuredrupal:test

docker ps -a

docker rm containeridea

docker rmi image

Other deployment strategies:

In addition to deploying through the portal, you could easily deploy via PowerShell, Azure CLI, or ARM template.  Here's an Azure CLI 2.0 example of how to deploy (note: the script below uses PowerShell variables for demonstration, please substitute those as needed):

$resourceGroupName = "Drupal-Test"
$planName = $resourceGroupName
$appName = $planName
$containerName = "appsvcorg/drupal-nginx-fpm:0.45"
$location = "West US"

az group create -l $location -n $resourceGroupName

az appservice plan create `
    -n $planName `
    -g $resourceGroupName `
    --sku S3 --is-linux 

az webapp create `
    --resource-group $resourceGroupName `
    --plan $planName `
    --name $appName `
    --deployment-container-image-name $containerName

az webapp config appsettings set `
    --resource-group $resourceGroupName `
    --name $appName `
    --settings WEBSITES_ENABLE_APP_SERVICE_STORAGE="true"

az webapp config appsettings set `
    --resource-group $resourceGroupName `
    --name $appName `
    --settings WEBSITES_CONTAINER_START_TIME_LIMIT="600"

# please modify DB settings according to current condition
az webapp config appsettings set `
        --resource-group $resourceGroupName `
        --name $appName `
        --settings DATABASE_HOST="drupaldb.mysql.database.azure.com" `
            DATABASE_NAME="drupaldb" `
            DATABASE_USERNAME="user@drupaldb" `
            DATABASE_PASSWORD="abcdefghijklmnopqrstuvwxyz"