Skip to content

Latest commit

 

History

History

gate-opener-docker

Running the mqtt-gate-opener Docker Container

In order to control your gate opener from anywhere, you can run this Docker container (also available at https://hub.docker.com/repository/docker/flyingsaucrdude/mqtt-gate-opener-remote) on your favorite service. This README contains instructions for doing so on Google Cloud Run.

0. Prerequisites

This tutorial assumes you already have an MQTT broker running somewhere. (It can be the same Raspberry Pi you're using to control the gate opener, but it doesn't have to be. As long as the gate opener Raspberry Pi can talk to the MQTT server, you should be fine.)

It also assumes that you can access that MQTT broker from the Internet. If you need help setting that up, you can check out my tutorial here on how to setup mosquitto with a dynamic DNS domain name from DuckDNS, username/password authentication, access controls, and TLS using a certificate from Let's Encrypt.

Finally, it assumes you have a Google account, and you've installed the Google Cloud SDK on your machine following the instructions here.

1. Setup a new project

First, set a project name variable that we can reuse:

export PROJECT_NAME=pick-some-name

Then create the project and set up the repo:

gcloud auth login
gcloud projects create $PROJECT_NAME --set-as-default
gcloud artifacts repositories create --location=us-west1 --repository-format=docker gate-opener-repo
gcloud auth configure-docker us-west1-docker.pkg.dev

If it asks you to enable the Artifact Registry, do so and then retry the last two commands. Then continue with

2. Configure the docker container

Now we need to set the following environment variables which will be used inside the container:

  • MQTT_SERVER_HOSTNAME — (Required) The hostname of your MQTT broker
  • MQTT_SERVER_PORT — (Optional) The port of your MQTT broker. Defaults to 8883.
  • MQTT_SERVER_USERNAME — (Optional) The username to use to log in to the MQTT broker. If not given, the MQTT client won't use a username/password.
  • MQTT_SERVER_PASSWORD — (Optional) The password to use to log in to the MQTT broker. If not given, the MQTT client won't use a username/password.
  • MQTT_USE_TLS — (Optional) Whether or not to use an encrypted TLS connection to connect to the MQTT broker, including verifying that it has a valid certificate. Defaults to true. Set to false to disable encryption.
  • MQTT_COMMAND_TOPIC — (Optional) The topic to use to trigger the gate opener. Defaults to gate-opener/open.
  • MQTT_RESPONSE_TOPIC — (Optional) The topic to listen on to receive confirmation messages from the gate opener. Defaults to gate-opener/opened.
  • ACCESS_TOKENS_LIST — (Required) A json list of access tokens to use to access the service on the web. These tokens are the only thing protecting your gate opener from being accessed by anyone, so they should be long and random so that they can't be guessed or brute-forced, e.g. ['token1-I2JJVsEV5LCfbDqMMM1iL5rCh3VaNiqKNN2RQZrkZv7BjV7MShEmwxFXsx1210J6', 'token2-H3udRjyhuXKOUi2OU8E6PGpST5S78Fc79lDeftVurht6QKIbyqxZHsftIp8NMvfE']

It's easiest to just edit these in a file and let Google Cloud Run read the file when we deploy the docker container in the next step. To do so, make a copy of environment_variables.yaml and save it as my_environment_variables.yaml in whichever directory you're working. Then open the file in your favorite editor, make changes to the environment variables to match your configuration, save, and close.

3. Deploy the docker image

Now do:

docker pull flyingsaucrdude/mqtt-gate-opener-remote 
docker tag flyingsaucrdude/mqtt-gate-opener-remote us-west1-docker.pkg.dev/$PROJECT_NAME/gate-opener-repo/gate-opener
docker push us-west1-docker.pkg.dev/$PROJECT_NAME/gate-opener-repo/gate-opener
gcloud run deploy gate-opener --allow-unauthenticated --min-instances=0 --max-instances=1 --image us-west1-docker.pkg.dev/$PROJECT_NAME/gate-opener-repo/gate-opener --env-vars-file=my_environment_variables.yaml

If it asks you to enable the Cloud Run API, do so.

4. Check that it works

Once you have your container running, you can access it over the web by visiting

https://HOSTNAME/ACCESS_TOKEN/

where HOSTNAME is the service URL of your docker container (which you can get by running gcloud run services describe gate-opener | grep "URL:") and ACCESS_TOKEN is one of the access tokens from the ACCESS_TOKENS_LIST.

As you can see, instead of requiring a username or password, the website's security depends on the uniqueness and length of the access tokens you choose. The downside is that you must use very long (I recommend at least 64 characters) and random (i.e. generated by your computer) tokens. You can generate such a token with the simple Python script (using the secrets module to ensure cryptographically strong tokens):

import secrets, string
''.join(secrets.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(64))

Although the resulting access URLs aren't memorable, they are persistent, bookmarkable, and shareable, so you can, e.g., give a unique access token/URL to each of your friends and family, and all they have to do is bookmark that URL to be able to come back and open your gate whenever they need to.

5. Updating the service

If you ever need to redeploy the service (e.g. if you add new access tokens or delete old ones), you can do so with:

gcloud run services update gate-opener --env-vars-file=my_environment_variables.yaml