From 2b259dec3b9632cc6f9dfb123d74776e254ba5e8 Mon Sep 17 00:00:00 2001 From: admin Date: Thu, 25 Jun 2026 16:53:23 -0700 Subject: [PATCH] Add homeassistant.yaml + stack-deploy.sh hint for secret not found errors --- deploy/stack-deploy.sh | 6 +- homeassistant.yaml | 395 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 399 insertions(+), 2 deletions(-) create mode 100755 homeassistant.yaml diff --git a/deploy/stack-deploy.sh b/deploy/stack-deploy.sh index 27a7ec5..e8e0bd0 100755 --- a/deploy/stack-deploy.sh +++ b/deploy/stack-deploy.sh @@ -16,9 +16,11 @@ if [ -f "$ENVFILE" ]; then echo " Vars: $VARS" envsubst "$VARS" < "$YAML" \ | python3 $PY strip \ - | docker stack deploy -c - "$STACK" + | docker stack deploy -c - "$STACK"\ + || { echo -e "\\n Hint: 'secret not found' means Woodpecker hasn't provisioned secrets yet for this stack."; echo -e " Trigger the pipeline first: https://woodpecker.bryanmail.net\\n"; exit 1; } else echo " No env file" - docker stack deploy -c "$YAML" "$STACK" + docker stack deploy -c "$YAML" "$STACK"\ + || { echo -e "\\n Hint: 'secret not found' means Woodpecker hasn't provisioned secrets yet for this stack."; echo -e " Trigger the pipeline first: https://woodpecker.bryanmail.net\\n"; exit 1; } fi echo "==> Done: $STACK" diff --git a/homeassistant.yaml b/homeassistant.yaml new file mode 100755 index 0000000..0f74e3e --- /dev/null +++ b/homeassistant.yaml @@ -0,0 +1,395 @@ +services: + homeassistant: + image: ghcr.io/home-assistant/home-assistant:stable + hostname: home +# security_opt: +# - no-new-privileges + networks: + - traefik_backend + - postgresql_db-backend +# dns_search: +# - traefik_backend + dns: + - 127.0.0.11 # Docker embedded DNS first +# - 192.168.4.30 # Your VIP as fallback (or your Pi-hole/router IP) + - 1.1.1.1 # Public fallback for external resolution +# network_mode: host + ports: + - 8123:8123 +# - target: 8123 +# published: 8123 +# protocol: tcp +# mode: host + volumes: + - /volume1/docker/Home Assistant/config:/config +# - /volume1/docker/Home Assistant/media:/media + - /volume1/docker/letsencrypt/certs:/ssl + - /var/run/docker.sock:/var/run/docker.sock + - /etc/localtime:/etc/localtime:ro +# privileged: true +# restart: always + healthcheck: + test: "bash -c 'printf \"GET / HTTP/1.1\n\n\" > /dev/tcp/127.0.0.1/8123; exit $$?;'" + interval: 90s + retries: 5 + start_period: 5s + timeout: 15s + deploy: +# endpoint_mode: vip +# placement: +# constraints: +# - node.hostname == docker-3 + labels: + - traefik.enable=true + - traefik.http.routers.hass.rule=Host(`home.bryanmail.net`) + - traefik.http.routers.hass.tls=true + - traefik.http.routers.hass.tls.certresolver=letsencrypt + - traefik.http.routers.hass.entrypoints=websecure + - traefik.http.services.hass.loadbalancer.server.port=8123 + - traefik.swarm.network=traefik_backend + - traefik.http.services.hass.loadbalancer.server.scheme=https + - traefik.http.routers.hass.middlewares=crowdsec@file +# - traefik.http.routers.wss.rule=Host(`ws.${HOST}`) +# - traefik.tcp.services.wss.loadbalancer.server.port=443 +# - traefik.http.routers.wss.entrypoints=websecure + - autoheal=true + resources: + limits: + cpus: '4' # Limit to 0.5 CPU core + memory: 4G + + frigate-nvr: + hostname: frigate +# privileged: true # this may not be necessary for all setups +# restart: always + image: ghcr.io/blakeblackshear/frigate:0.17.1 + cap_add: + - CAP_PERFMON + - SYS_ADMIN +## shm_size: "200mb" # update for your cameras based on calculation above +## devices: +# - /dev/bus/usb:/dev/bus/usb # Passes the USB Coral, needs to be modified for other versions +# - /dev/apex_0:/dev/apex_0 # Passes a PCIe Coral, follow driver instructions here https://coral.ai/docs/m2/get-started/#2a-on-linux +# - /dev/video11:/dev/video11 # For Raspberry Pi c4B + volumes: + - /etc/localtime:/etc/localtime:ro + - /volume1/docker/frigate/config:/config + - /volume1/docker/frigate/media:/media/frigate + - /volume1/docker/letsencrypt/certs/certs/nvr.bryanmail.net.crt:/etc/letsencrypt/live/frigate/fullchain.pem + - /volume1/docker/letsencrypt/certs/private/nvr.bryanmail.net.key:/etc/letsencrypt/live/frigate/privkey.pem + - /dev/dri/renderD128:/dev/dri/renderD128 # For intel hwaccel, needs to be updated for your hardware +# - /dev/dri:/dev/dri + - type: tmpfs ## Optional: #1GB of memory, reduces SSD/SD Card wear + target: /tmp/cache + tmpfs: + size: 500000000 + - type: tmpfs + target: /dev/shm + tmpfs: + size: 1500000000 +# ports: +# - target: 5000 +# published: 5000 +# protocol: tcp +# mode: host +# - "5000:5000" +# - "8971:8971" +# - "8554:8554" # RTSP feeds +# - "8555:8555/tcp" # WebRTC over tcp +# - "8555:8555/udp" # WebRTC over udp + environment: + FRIGATE_RTSP_PASSWORD: "${FRIGATE_RTSP_PASSWORD}" +# LIBVA_DRIVER_NAME: i965 +# OMP_NUM_THREADS: 10 + networks: + - traefik_backend + deploy: +# endpoint_mode: vip +# placement: +# constraints: +# - node.hostname == docker-3 + labels: + - traefik.enable=true + - traefik.http.routers.frigate-auth.rule=Host(`nvr.bryanmail.net`) + - traefik.http.routers.frigate-ip.rule=Host(`nvr.bryanmail.net`) && ClientIP(`10.0.0.0/8`) + - traefik.http.routers.frigate-auth.tls=true + - traefik.http.routers.frigate-ip.tls=true + - traefik.http.routers.frigate-auth.tls.certresolver=letsencrypt + - traefik.http.routers.frigate-ip.tls.certresolver=letsencrypt + - traefik.http.routers.frigate-auth.entrypoints=websecure + - traefik.http.routers.frigate-ip.entrypoints=websecure + - traefik.http.services.frigate.loadbalancer.server.port=5000 +# - traefik.http.routers.frigate-auth.middlewares=frigate-basicauth +# - traefik.http.middlewares.frigate-basicauth.basicauth.users=test:$$2a$$12$$1sIFlNKcNrEApe2IScpFwukd7l1j/uvfxk0GeuqIk0BBcO9Mk2F2u +# - traefik.http.services.frigate.loadbalancer.server.scheme=https + - traefik.swarm.network=traefik_backend + - traefik.http.routers.frigate-auth.middlewares=forwardAuth-authentik@file, crowdsec@file +# resources: +# limits: +# cpus: '4' +# memory: 6G + + MQTT: + command: + - "/usr/sbin/mosquitto" + - "-c" + - "/mosquitto/config/mosquitto.conf" + entrypoint: + - "/docker-entrypoint.sh" + image: "public.ecr.aws/docker/library/eclipse-mosquitto:latest" +# logging: +# driver: "db" +# options: {} +# ports: +# - "1883:1883/tcp" +# - "9001:9001/tcp" + stdin_open: true + tty: true +# healthcheck: +# test: "ash -c 'printf \"GET / HTTP/1.1\n\n\" > /dev/tcp/127.0.0.1/9001; exit $?;'" +# start_period: 90s +# timeout: 5s +# interval: 5s +# retries: 3 +# restart: always + hostname: mqtt + networks: + - traefik_backend + volumes: + - /volume1/docker/MQTT/config:/mosquitto/config + - /volume1/docker/MQTT/data:/mosquitto/data + - /volume1/docker/MQTT/log:/mosquitto/log + deploy: + endpoint_mode: dnsrr + labels: + - traefik.enable=true + - traefik.tcp.routers.mqtt.entrypoints=mqtt + - traefik.tcp.routers.mqtt.rule=HostSNI(`*`) +# - traefik.tcp.routers.postgres.tls=true + - traefik.tcp.services.mqtt.loadbalancer.server.port=1883 + - traefik.tcp.routers.mqtt.service=mqtt + - traefik.swarm.network=traefik_backend +# resources: +# limits: +# cpus: '0.001' +# memory: 128M + + Zigbee2MQTT: + command: + - "/sbin/tini" + - "--" + - "node" + - "index.js" + entrypoint: + - "docker-entrypoint.sh" + environment: + - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + - "NODE_ENV=production" + - "NODE_VERSION=14.18.1" + - "TZ=Pacific/Los_Angeles" + image: "ghcr.io/koenkk/zigbee2mqtt:latest" +# restart: always +# logging: +# driver: "db" +# options: {} + hostname: zb + networks: + - traefik_backend +# ports: +# - "8084:8080/tcp" + healthcheck: + test: "wget --no-verbose --tries=1 --header 'Host: zigbee2mqtt.koseduhemak.de' --spider http://localhost:8080 || exit 1" + start_period: 60s + interval: 5s + retries: 5 + timeout: 5s + +# healthcheck: +# test: "bash -c 'printf \"GET / HTTP/1.1\n\n\" > /dev/tcp/127.0.0.1/9001; exit $?;'" +# start_period: 90s +# timeout: 5s +# interval: 5s +# retries: 3 + stdin_open: true + tty: true + volumes: + - /volume1/docker/Zigbee2MQTT/data:/app/data + working_dir: "/app" + deploy: +# endpoint_mode: dnsrr #removed during frigate integration testing + labels: + - traefik.enable=true + - traefik.http.routers.zigbee.rule=Host(`zb.bryanmail.net`) + - traefik.http.routers.zigbee.tls=true + - traefik.http.routers.zigbee.tls.certresolver=letsencrypt + - traefik.http.routers.zigbee.entrypoints=websecure + - traefik.http.services.zigbee.loadbalancer.server.port=8080 + - traefik.swarm.network=traefik_backend + - traefik.http.routers.zigbee.middlewares=forwardAuth-authentik@file, crowdsec@file +# - traefik.http.routers.zigbee.middlewares=auth +# - traefik.http.middlewares.auth.basicauth.users=test:$$2a$$12$$1sIFlNKcNrEApe2IScpFwukd7l1j/uvfxk0GeuqIk0BBcO9Mk2F2u + resources: + limits: + cpus: '1' + memory: 512M + + ESPHome: + image: ghcr.io/esphome/esphome:latest + volumes: + - /volume1/docker/esphome/config:/config +# - /etc/localtime:/etc/localtime:ro +# restart: always +# privileged: true + hostname: esp + networks: + - traefik_backend +# healthcheck: +# test: "bash -c 'printf \"GET / HTTP/1.1\n\n\" > /dev/tcp/127.0.0.1/6052; exit $$?;'" +# interval: 90s +# retries: 5 +# start_period: 5s +# timeout: 15s + deploy: +# endpoint_mode: dnsrr #removed during frigate integration testing + labels: + - traefik.enable=true + - traefik.http.routers.esphome.rule=Host(`esp.bryanmail.net`) + - traefik.http.routers.esphome.tls=true + - traefik.http.routers.esphome.tls.certresolver=letsencrypt + - traefik.http.routers.esphome.entrypoints=websecure + - traefik.http.services.esphome.loadbalancer.server.port=6052 + - traefik.swarm.network=traefik_backend + - traefik.http.routers.esphome.middlewares=forwardAuth-authentik@file, crowdsec@file +# - traefik.http.routers.esphome.middlewares=auth +# - traefik.http.middlewares.auth.basicauth.users=test:$$2a$$12$$1sIFlNKcNrEApe2IScpFwukd7l1j/uvfxk0GeuqIk0BBcO9Mk2F2u + resources: + limits: + cpus: '10' + memory: 4G + +# wyze-bridge: +## restart: always +# image: mrlt8/wyze-bridge:latest +# hostname: cams +# volumes: +# - /volume1/docker/wyze-bridge/data:/data +# - /volume1/docker/wyze-bridge/config:/config +# - /volume1/docker/wyze-bridge/tokens:/tokens +# networks: +# - traefik_backend +## - host +# ports: +# - 1935:1935 # RTMP +# - 8554:8554 # RTSP +# - 8888:8888 # HLS +# - 8889:8889 #WebRTC +# - 8189:8189/udp # WebRTC/ICE +## - 5000:5000 # WEB-UI +# environment: +# # [OPTIONAL] (Can be set in the WebUI): +# # - WYZE_EMAIL= +# # - WYZE_PASSWORD= +# # - TOTP_KEY= +# # [OPTIONAL] IP Address of the host to enable WebRTC e.g.,: +# # - WB_IP=192.168.1.122 +# # [OPTIONAL] Wyze API credentials: +# # - API_ID= +# # - API_KEY= +# - WB_RTSP_URL=rtsp://cams.bryanmail.net:1234/ +# - WB_RTMP_URL=rtmp://cams.bryanmail.net:5678/ +# - WB_HLS_URL=http://cams.bryanmail.net:9090/ +# - WB_WEBRTC_URL=http://cams.bryanmail.net:9091/ +# - NET_MODE=LAN +# - MQTT_HOST=tasks.mqtt:1883 +# - MQTT_TOPIC=wyze-bridge +# - MQTT_DTOPIC=homeassistant +# - ENABLE_AUDIO=True +# - AUDIO_CODEC=AAC +# - FILTER_NAMES=Pan Cam, Baby Monitor +# - WB_AUTH=False +# deploy: +# endpoint_mode: dnsrr +# labels: +# - traefik.enable=true +# - traefik.http.routers.wb-auth.rule=Host(`cams.bryanmail.net`) +# - traefik.http.routers.wb-ip.rule=Host(`cams.bryanmail.net`) && ClientIP(`10.0.1.0/16`) +# - traefik.http.routers.wb-auth.tls=true +# - traefik.http.routers.wb-ip.tls=true +# - traefik.http.routers.wb-auth.tls.certresolver=letsencrypt +# - traefik.http.routers.wb-ip.tls.certresolver=letsencrypt +# - traefik.http.routers.wb-auth.entrypoints=websecure +# - traefik.http.routers.wb-ip.entrypoints=websecure +# - traefik.http.services.wb.loadbalancer.server.port=5000 +## - traefik.http.routers.wb-auth.middlewares=wb-basicauth +## - traefik.http.middlewares.wb-basicauth.basicauth.users=test:$$2a$$12$$1sIFlNKcNrEApe2IScpFwukd7l1j/uvfxk0GeuqIk0BBcO9Mk2F2u +## - traefik.http.services.wb.loadbalancer.server.scheme=https +# - traefik.swarm.network=traefik_backend +# - traefik.http.routers.wb-auth.middlewares=forwardAuth-authentik@file, crowdsec@file +## - traefik.enable=true +## - traefik.http.routers.wyze-bridge-auth.rule=Host(`cams.bryanmail.net`) +## - traefik.http.routers.wyze-bridge-ip.rule=Host(`cams.bryanmail.net`) && ClientIP(`10.0.1.0/16`) +## - traefik.http.routers.wyze-bridge-auth.tls=true +## - traefik.http.routers.wyze-bridge-ip.tls=true +## - traefik.http.routers.wyze-bridge-auth.tls.certresolver=letsencrypt +## - traefik.http.routers.wyze-bridge-ip.tls.certresolver=letsencrypt +## - traefik.http.routers.wyze-bridge-auth.entrypoints=websecure +## - traefik.http.routers.wyze-bridge-ip.entrypoints=websecure +## - traefik.http.services.wyze-bridge.loadbalancer.server.port=5000 +## - traefik.http.routers.wyze-bridge-auth.middlewares=frigate-basicauth +## - traefik.http.middlewares.wyze-bridge-basicauth.basicauth.users=test:$$2a$$12$$1sIFlNKcNrEApe2IScpFwukd7l1j/uvfxk0GeuqIk0BBcO9Mk2F2u +## - traefik.http.services.wyze-bridge.loadbalancer.server.scheme=https +## - traefik.swarm.network=traefik_backend +## - traefik.http.routers.wyze-bridge-auth.middlewares=forwardAuth-authentik@file +## resources: +## limits: +## cpus: '0.001' +## memory: 128M + +# homebridge: +# image: homebridge/homebridge:latest +# restart: always +# networks: +# - traefik_backend +# ports: +# - 8581:8581 +# volumes: +# - /volume1/docker/HomeBridge:/homebridge +# logging: +# driver: json-file +# options: +# max-size: "10mb" +# max-file: "1" +# deploy: +# resources: +# limits: +## cpus: '0.001' +# memory: 128M + +# openwakeword: +# hostname: openWakeWord +# image: dalehumby/openwakeword-rhasspy:latest +# volumes: +# - /volume1/docker/openWakeWord/config:/config +# environment: +# - TZ=America/Pacific +# restart: always +# networks: +# - traefik_backend +# ports: +# - 12202:12202/udp +# deploy: +# resources: +# limits: +## cpus: '0.001' +# memory: 1024M + +networks: + postgresql_db-backend: + external: true + traefik_backend: + external: true + traefik_frontend: + external: true + host: + name: host + external: true