Full Docker Compose Stack on Home Server (teddyCloud, Home Assistant, Traefik, Pi-Hole)

tl;dr:

I want to run teddyCloud (among other services) on my home server - where :80 and :443 are already occupied. So I assigned my server a second ip, only used for teddyCloud.

Detailed Problem:

I followed the RevvoX wiki and Teddycloud ESP32 newbie to setup the Toniebox and the teddyCloud on a fresh Raspberry Pi. And after some minor issues that already drove me mental the Toniebox suddenly showed up in the teddyCloud :slight_smile:
But I did not wanted to run a Raspberry Pi only for teddyCloud, as I already have a more than capable x64 home server here - with Traefik and Let’s Encrypt certs and everything.

Failed Attempts

So my first attempt was: Simply add teddyCloud as with TLS passthrough. Well, well, well Treafik allows TLS passthrough on certain domains only with HostSNI (SNI=Server Name Indication) - and the Toniebox does not support SNI -_- I could run teddyCloud on :443 but then the port is blocked for Traefik (and all subdomain routing) - or I use Traefik Router HostSNI(`*`) (disables SNI) but that disables all other subdomains and Traefik routes everything to teddyCloud which is basically the same problem as before just with extra steps…

My next attempt was chaining HAProxy before Treafik to filter TCP instead of HTTP. I hoped TLS stays untouched here which did not work for me. Shortly before I became completely insane I gave up on this attempt (and also because I feared the routing will became too complex to maintain).

My Solution

I assigned a second IP: default was 192.168.0.10 and I assigned a second IP, only for teddyCloud 192.168.0.11. This allows to bind :80 and :443 of teddyCloud to the second IP and let Traefik handle all other subdomains as usual.
So I added the second ip on my Ubuntu via Netplan (/etc/netplan/...) and added the subdomain teddycloud.mydomain.de to 192.168.0.11 (note the second, teddyCloud ip) to Pi-Hole DNS.

Configs and Docker Compose stacks

:warning: Disclaimer I did not pay too much attention to security, as my server is not accessible from outside my home network.

pi-hole/custom.list:

# Home Server - IPv4:
192.168.0.10 mydomain.de
192.168.0.10 www.mydomain.de
192.168.0.10 pihole.mydomain.de
192.168.0.10 traefik.mydomain.de
# . . .

# TeddyCloud (alternative server for Toniebox)
192.168.0.11 teddycloud.mydomain.de
192.168.0.11 prod.de.tbs.toys
192.168.0.11 rtnl.bxcl.de

teddycloud/docker-compose.yml:

version: '3'
services:
  teddycloud:
    container_name: teddycloud
    hostname: teddycloud
    image: ghcr.io/toniebox-reverse-engineering/teddycloud:latest
    networks:
      - default
      - mqttnet
    ports:
      # bind to second ip address
      - 192.168.0.11:80:80  # optional
      - 192.168.0.11:443:443  # Port is needed for the connection for the box
    volumes:
      - certs:/teddycloud/certs
      - config:/teddycloud/config
      - content:/teddycloud/data/content
      - library:/teddycloud/data/library
      - firmware:/teddycloud/data/firmware
    restart: unless-stopped

volumes:
  certs:
  config:
  content:
  library:
  firmware:

networks:
  mqttnet:  # Gives access to MQTT broker on hostname: `mosquitto:1883`
    external: true
    name: mqttnet

traefik/docker-compose.yml:

services:

  traefik:
    image: "traefik:latest"
    container_name: "traefik"
    restart: unless-stopped
    ports:
      - 192.168.0.10:80:80  # optional
      - 192.168.0.10:443:443  # Port is needed for the connection for the box
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      #- . . . 
    networks:
      - traefik_net
    labels:
      - "traefik.enable=true"
      #- . . . 

networks:
  traefik_net:
    external: true
    name: traefikproxynet

home-assistant/docker-compose.yml

services:
  homeassistant:
    #container_name: homeassistant
    image: "ghcr.io/home-assistant/home-assistant:stable"
    container_name: home-assistant
    volumes:
      - ...
    restart: unless-stopped
    #privileged: true
    network_mode: host
    #devices:
    #  - ...

  #zwave-js-ui:
  #  ...
  
  # Mosquitto MQTT broker
  mosquitto:
    image: eclipse-mosquitto:latest
    container_name: mosquitto
    networks:
      - mqttnet
    ports:
      - "1883:1883"
      #- "9001:9001" # WebSocket listener, optional
    volumes:
      - ./mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf
      - ./mosquitto/passwords.txt:/mosquitto/config/passwords.txt
      - mosquitto-data:/mosquitto/data
      - mosquitto-log:/mosquitto/log
    restart: unless-stopped


networks:
  zwave:  # Provide access to Z-Wave server / devices to other services
  mqttnet:  # Allow access to MQTT broker to other services (-> teddyCloud)
    external: true
    name: mqttnet
  traefik_net:
    external: true
    name: traefikproxynet


volumes:
  mosquitto-data:
  mosquitto-log:
2 Likes