I finally spent some time getting brewblox running on my unraid server, would like to share my experience/settings in case others wish to do the same, and ask if there are recommended changes to my setup for optimal use.
My primary goals are to control a glycol jacketed conical, monitor readings from a tilt, and send those readings to brewfather. Secondary goals would be to add on a heating solution (likely warm liquid) for my conical, controlling the glycol chiller itself, controlling the warm liquid reservoir, and potentially adding a second conical with all the same features of the first.
What I currently have setup is a simple inkbird controller which achieves about +/- 2 degrees of control. The glycol jacket has huge cooling ability, so by the time it’s reading setpoint it overshoots by a lot. I could tune the glycol temp, but that would not work if I have a 2nd conical with different cooling needs. Thus, one of my primary drivers for PID control.
I already have an unraid server running and wanted to make use of that if possible. Docker compose is available from community applications, which is the direction I went to setup brewblox. I added a ‘Brewblox’ stack and the following compose and env configurations.
Compose (based upon brewblox-ctl/brewblox_ctl/deployed/config/docker-compose.shared.yml at develop · BrewBlox/brewblox-ctl · GitHub):
# DO NOT EDIT: THIS FILE WILL BE RESET DURING UPDATES
#
# This file contains configuration for the shared Brewblox services
#
# If you need to make change to any of the shared services,
# you can do so in docker-compose.yml.
#
# For more information, see https://docs.docker.com/compose/extends/
version: "3.7"
services:
eventbus:
image: ghcr.io/brewblox/mosquitto:${BREWBLOX_RELEASE}
restart: unless-stopped
labels:
# MQTT
- traefik.tcp.routers.mqtt.entrypoints=mqtt
- traefik.tcp.routers.mqtt.rule=HostSNI(`*`)
- traefik.tcp.routers.mqtt.tls=false
- traefik.tcp.routers.mqtt.service=mqtt
- traefik.tcp.services.mqtt.loadBalancer.server.port=1883
# MQTTS with TLS termination by traefik
- traefik.tcp.routers.mqtts.entrypoints=mqtts
- traefik.tcp.routers.mqtts.rule=HostSNI(`*`)
- traefik.tcp.routers.mqtts.tls=true
- traefik.tcp.routers.mqtts.service=mqtts
- traefik.tcp.services.mqtts.loadBalancer.server.port=1884
# MQTT over websockets
- traefik.http.services.eventbus.loadbalancer.server.port=15675
volumes:
- type: bind
source: /mnt/user/appdata/mosquitto
target: /mosquitto/include
victoria:
image: victoriametrics/victoria-metrics:v1.88.0
restart: unless-stopped
labels:
- traefik.http.services.victoria.loadbalancer.server.port=8428
volumes:
- type: bind
source: /mnt/user/appdata/victoria
target: /victoria-metrics-data
command: >-
--retentionPeriod=100y
--influxMeasurementFieldSeparator=/
--http.pathPrefix=/victoria
--search.latencyOffset=10s
redis:
image: redis:6.0
restart: unless-stopped
labels:
- traefik.enable=false
volumes:
- type: bind
source: /mnt/user/appdata/redis
target: /data
command: --appendonly yes
history:
image: ghcr.io/brewblox/brewblox-history:${BREWBLOX_RELEASE}
restart: unless-stopped
volumes:
- type: bind
source: /etc/localtime
target: /etc/localtime
read_only: true
# Privileged to avoid a bug in libseccomp for Debian Buster hosts
# This flag should be removed when Debian Buster is no longer supported
# For an explanation: https://github.com/sdr-enthusiasts/Buster-Docker-Fixes
privileged: true
traefik:
image: traefik:2.9
restart: unless-stopped
labels:
- traefik.http.routers.api.rule=PathPrefix(`/api`) || PathPrefix(`/dashboard`)
- traefik.http.routers.api.service=api@internal
- traefik.http.middlewares.prefix-strip.stripprefixregex.regex=/[^/]+
volumes:
- type: bind
source: /mnt/user/appdata/traefik
target: /config
read_only: true
- type: bind
source: /var/run/docker.sock
target: /var/run/docker.sock
- type: bind
source: /etc/localtime
target: /etc/localtime
read_only: true
ports:
- "${BREWBLOX_PORT_HTTP:-80}:${BREWBLOX_PORT_HTTP:-80}"
- "${BREWBLOX_PORT_HTTPS:-443}:${BREWBLOX_PORT_HTTPS:-443}"
- "${BREWBLOX_PORT_MQTT:-1883}:${BREWBLOX_PORT_MQTT:-1883}"
- "${BREWBLOX_PORT_MQTTS:-8883}:${BREWBLOX_PORT_MQTTS:-8883}"
command: >-
--api.dashboard=true
--providers.docker=true
--providers.docker.constraints="LabelRegex(`com.docker.compose.project`, `${COMPOSE_PROJECT_NAME}`)"
--providers.docker.defaultrule="PathPrefix(`/{{ index .Labels \"com.docker.compose.service\" }}`)"
--providers.file.directory=/config
--entrypoints.web.address=:${BREWBLOX_PORT_HTTP}
--entrypoints.websecure.address=:${BREWBLOX_PORT_HTTPS}
--entrypoints.websecure.http.tls=true
--entrypoints.mqtt.address=:${BREWBLOX_PORT_MQTT}/tcp
--entrypoints.mqtts.address=:${BREWBLOX_PORT_MQTTS}/tcp
ui:
image: ghcr.io/brewblox/brewblox-ui:${BREWBLOX_RELEASE}
restart: unless-stopped
labels:
- traefik.http.routers.ui.rule=PathPrefix(`/ui`) || Path(`/`)
volumes:
- type: bind
source: /etc/localtime
target: /etc/localtime
read_only: true
Env (settings from brewblox-ctl/brewblox_ctl/const.py at develop · BrewBlox/brewblox-ctl · GitHub):
BREWBLOX_RELEASE = 'edge'
BREWBLOX_PORT_HTTP = 3780
BREWBLOX_PORT_HTTPS = 37443
BREWBLOX_PORT_MQTT = 1883
BREWBLOX_PORT_MQTTS = 8883
My only change to compose was updating relative directory location to /mnt/user/appdata/ for each app, as that is a common location for docker images to store their data. I had to create each directory in appdata before they would successfully launch. I also updated the HTTP/HTTPS ports as they are already in use for unraid. Besides that, everything seems to be working. I am hoping for some feedback if these changes make sense, and hopefully allow simply calling to update the stack as new releases become available. If not, I’m all ears to any recommended changes
I haven’t added any devices yet, but probably add a Spark Simulator to play around with, and ultimately get a Spark 4. Can adding devices be done from the web interface? I may be completely missing something obvious, but I can’t seem to find this configuration. I see in the documentation to use the ‘brewblox-ctl add-spark’ command, but I am unclear where I would do this running from docker compose.
Thanks in advance!