Add homeassistant.yaml + stack-deploy.sh hint for secret not found errors
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
@@ -16,9 +16,11 @@ if [ -f "$ENVFILE" ]; then
|
|||||||
echo " Vars: $VARS"
|
echo " Vars: $VARS"
|
||||||
envsubst "$VARS" < "$YAML" \
|
envsubst "$VARS" < "$YAML" \
|
||||||
| python3 $PY strip \
|
| 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
|
else
|
||||||
echo " No env file"
|
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
|
fi
|
||||||
echo "==> Done: $STACK"
|
echo "==> Done: $STACK"
|
||||||
|
|||||||
Executable
+395
@@ -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
|
||||||
Reference in New Issue
Block a user