Customisation¶
References¶
IOTstack customisation points¶
The menu supports a number of customisation points. It is up to you to decide whether to edit an override file or its corresponding primary file. The pros and cons of using override files are:
-
If you stick to override files then you are less likely to need to re-apply your customisations if the corresponding tracked file changes on GitHub. It will usually be safe to let the menu both "Renovate" and "Upgrade" in situ.
-
The override mechanism is highly effective for adding new settings or replacing existing settings, but slightly more problematic if your goal is to delete an existing setting.
-
You will usually want to preview the effect of your override files by running:
$ ./iotstack-menu.sh build $ docker compose config { «service»... }The biggest "issue" with the
configverb is that it re-orders everything and, where a clause can be expressed in either compact or expanded form, always shows the expanded form. It can take some getting used to.Note:
- IOTstackAliases has a
CONFIGalias for this.
- IOTstackAliases has a
structural¶
The structural files are:
~/IOTstack/services/
├── docker-compose-header.yml
├── docker-compose-trailer.yml
├── docker-compose.override-header.yml
└── docker-compose.override-trailer.yml
You can customise any of those files but, again, the recommendation is to aim for the override files.
example¶
docker-compose-header.yml defines two internal bridged networks (default and database):
---
networks:
default:
driver: bridge
ipam:
driver: default
database:
driver: bridge
internal: true
ipam:
driver: default
The above structure leaves the choice of IPv4 subnet ranges up to Docker. Suppose you want to use specific subnets. You can edit docker-compose.override-header.yml like this:
networks:
default:
ipam:
config:
- subnet: 172.30.0.0/22
database:
ipam:
config:
- subnet: 172.30.4.0/22
Notice how you have to provide Docker with sufficient "path context", such as:
networks.default.ipam
after which you can include the config clause. You do not, however, have to repeat either driver clause.
services¶
When you ask the menu to install a service, the result is:
- A sub-directory named for the service is created in
~/IOTstack/services; and - The service's sub-directory always contains
service.ymland may contain other files.
For example, if you install InfluxDB, you can expect to see the following:
~/IOTstack/services/
└── influxdb
└── service.yml
You can:
- customise
service.yml; or -
create an
override.ymlfile alongsideservice.ymlto hold your customisations:~/IOTstack/services/ └── influxdb ├── override.yml └── service.yml -
do both.
See the build process for an explanation of how these files are assembled to create your stack.
example¶
At the time of writing, the first few lines of the influxdb service definition look like this:
influxdb:
container_name: influxdb
image: "influxdb:1.11"
restart: unless-stopped
...
InfluxDB is pinned to version 1.11 because the good folks at InfluxData have never provided a general tag which says "get me the latest release of version 1".
Don't pull InfluxDB 2 by mistake
If you use the latest tag then you will get version 2 and everything will turn to custard.
Suppose you become aware that version 1.12 has been released (which it has) and you decide you want to upgrade. You can either edit the service.yml or you can create an override.yml with the following content:
influxdb:
image: "influxdb:1.12"
To rebuild your stack and check your work:
$ ./iotstack-menu.sh build
$ docker compose config influxdb | grep image
image: influxdb:1.12
That last line confirms that v1.12 will be instantiated when you start the container by running:
$ docker compose up -d influxdb
environment variables¶
Historically, "old" menu used environment files where this was the typical pattern:
env_file:
- ./services/«service»/«service».env
New menu mostly adopted inline variables in the service definition, expressed using "hyphen-style" syntax:
environment:
- TZ=${TZ:-Etc/UTC}
Over time, "old" menu mostly migrated to this same syntax. With the advent of iotstack-menu.sh, a new standard applies. Technically, it's called "yaml mappings" syntax but I'll call it "colon-style" syntax:
environment:
TZ: ${TZ:-Etc/UTC}
The reason why "colon-style" syntax has been adopted as a universal standard for IOTstack service definitions is because it is necessary if you want the override mechanism to work properly.
It's important to realise that both service.yml and override.yml must use "colon-style" syntax. You can't mix and match.
reference service definition¶
Assume a service definition contains the following:
example:
container_name: example
image: example/example
restart: unless-stopped
ports:
- "9987:9987"
environment:
TZ: ${TZ:-Etc/UTC}
DEBUG_MODE: true
MQTT_HOST: mosquitto:1883
volumes:
- ./volumes/example/data:/var/lib/data
adding a new variables¶
We can infer that mosquitto:1883 is intended to refer to a Mosquitto broker running in another non-host-mode container on the same machine. Suppose you've enabled authentication on your Mosquitto instance and, from reading this container's documentation, you know that you need to define MQTT_USER and MQTT_PASSWORD.
Using an override.yml file:
example:
environment:
MQTT_USER: fred
MQTT_PASSWORD: fred1997
changing the value of an existing variable¶
Now suppose you've moved your broker to another host. You need to override the existing value of MQTT_HOST. All you do is repeat that key with a different value:
example:
environment:
MQTT_USER: fred
MQTT_PASSWORD: fred1997
MQTT_HOST: mqtt.home.arpa:1883
3. removing an existing variable¶
You've realised that debug mode is hammering your logs. You've tried changing the value to false but that doesn't work. After research, you've realised that the mere presence of DEBUG_MODE enables that mode (the value is irrelevant). Now you need to remove that variable. You can use the !reset null key for that:
example:
environment:
MQTT_USER: fred
MQTT_PASSWORD: fred1997
MQTT_HOST: mqtt.home.arpa:1883
DEBUG_MODE: !reset null
4. remove all environment variables¶
If you need to replace all of the environment variables that are included in a service.yml, you can use the !override key. Note that you still need at least one environment variable in the list, even if it is a dummy.
example:
environment: !override
DUMMY: dummy
Environment Variables
You can pass any environment variables you like into a container. An environment variable will only have any effect if a process running within the container actually supports that variable.