rearranged for type deployments

This commit is contained in:
admin 2026-01-29 13:37:11 -07:00
parent 684886589a
commit 767bce946f
441 changed files with 153728 additions and 0 deletions

17
lxc1/core/ddns.yml Normal file
View file

@ -0,0 +1,17 @@
services:
ddns:
image: qmcgaw/ddns-updater
user: 0:0
container_name: ddns
restart: unless-stopped
ports:
- "8000:8000/tcp"
environment:
- TZ=America/Edmonton
- PERIOD=5m
- PUBLICIP_FETCHERS=http
- PUBLICIP_HTTP_PROVIDERS=all
- CONFIG={"settings":[{"provider":"desec","domain":"mapletree.email","host":"@","token":"${DESEC_TOKEN}","ip_version":"ipv4"}]}
volumes:
- /docker/core/ddns:/updater/data

30
lxc1/core/technitium.yml Normal file
View file

@ -0,0 +1,30 @@
services:
dns:
image: technitium/dns-server:latest
container_name: dns-${NODE_ID} # Becomes dns-1 or dns-2
restart: unless-stopped
ports:
- "53:53/udp"
- "53:53/tcp"
- "5381:5380/tcp"
environment:
- TZ=America/Edmonton
- DNS_SERVER_DOMAIN=dns${NODE_ID}.mapletree.email # dns1... or dns2...
- DNS_SERVER_ADMIN_PASSWORD=${DNS_ADMIN_PASSWORD}
volumes:
# Updated path to match your new 'infrastructure' folder structure
- /docker/core/dns/config:/etc/dns
networks:
- dns_external
labels:
- "traefik.enable=true"
- "traefik.docker.network=dns_external"
# Dynamic Router Name (dns1 vs dns2)
- "traefik.http.routers.dns${NODE_ID}.rule=Host(`dns${NODE_ID}.mapletree.email`)"
- "traefik.http.routers.dns${NODE_ID}.entrypoints=web,websecure"
- "traefik.http.routers.dns${NODE_ID}.tls.certresolver=myresolver"
- "traefik.http.services.dns${NODE_ID}.loadbalancer.server.port=5380"
networks:
dns_external:
external: true

47
lxc1/core/traefik.yml Normal file
View file

@ -0,0 +1,47 @@
services:
traefik:
image: traefik:latest
container_name: traefik
network_mode: host
extra_hosts:
- "host.docker.internal:host-gateway"
cpus: 1.0
mem_limit: "1024m"
mem_reservation: "128m"
restart: always
#ports:
# - "80:80" # HTTP
# - "443:443" # HTTPS
# - "888:8080" # Traefik Dashboard (optional, password-protect in production!)
command:
- "--api.dashboard=true"
- "--api.insecure=true" # Remove or secure in prod
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.useBindPortIP=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--providers.docker.network=${DOCKER_NETWORK_LIST}"
- "--providers.file.directory=/etc/traefik/dynamic"
- "--providers.file.watch=true"
##DNS resolver
- "--certificatesresolvers.myresolver.acme.dnschallenge=true"
- "--certificatesresolvers.myresolver.acme.dnschallenge.provider=desec"
- "--certificatesresolvers.myresolver.acme.dnschallenge.delaybeforecheck=90"
- --certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53
- "--certificatesresolvers.myresolver.acme.email=admin@mapletree.email"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
##HTTP resolver
- --certificatesresolvers.le_http.acme.httpchallenge=true
- --certificatesresolvers.le_http.acme.httpchallenge.entrypoint=web
- --certificatesresolvers.le_http.acme.email=admin@mapletree.email
- --certificatesresolvers.le_http.acme.storage=/letsencrypt/acme.json
environment:
# Pass the variables through
- DESEC_TOKEN=${DESEC_TOKEN}
- DESEC_DOMAIN=${DESEC_DOMAIN}
# (Any other Traefik env vars you need)
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "/docker/core/traefik/letsencrypt:/letsencrypt"
- "${REPO_ROOT}/traefik/dynamic:/etc/traefik/dynamic"

View file

@ -0,0 +1,32 @@
http:
routers:
# JELLYFIN ROUTER
jellyfin:
rule: "Host(`media.mapletree.email`)"
service: jellyfin-service
entryPoints:
- websecure
tls:
certResolver: myresolver
stash:
rule: "Host(`stash.mapletree.email`)"
service: stash-service
entryPoints:
- websecure
tls:
certResolver: myresolver
services:
# JELLYFIN SERVICE (The Destination)
jellyfin-service:
loadBalancer:
servers:
# The IP address of pve2-lxc2
- url: "http://172.16.201.202:8096"
passHostHeader: true
stash-service:
loadBalancer:
servers:
# The IP address of pve2-lxc2
- url: "http://172.16.201.202:9999"
passHostHeader: true

View file

@ -0,0 +1,16 @@
http:
routers:
overseerr:
rule: "Host(`request.mapletree.email`)"
service: overseerr-service
entryPoints:
- websecure
tls:
certResolver: myresolver
services:
overseerr-service:
loadBalancer:
servers:
- url: "http://172.16.201.202:8096"
passHostHeader: true

View file

@ -0,0 +1,22 @@
http:
routers:
smf-web:
rule: "Host(`archive.westernsubaruclub.ca`)"
service: smf-service
entryPoints:
- websecure
tls:
certResolver: le_http
services:
smf-service:
loadBalancer:
servers:
- url: "http://172.16.201.202:80"
passHostHeader: true
middlewares:
https-redirect:
redirectScheme:
scheme: https
permanent: true

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<key id="2347b2f0-4b8d-4667-b5e1-28f5f6756619" version="1">
<creationDate>2025-12-02T13:14:50.0007113Z</creationDate>
<activationDate>2025-12-02T13:14:49.9981668Z</activationDate>
<expirationDate>2026-03-02T13:14:49.9981668Z</expirationDate>
<descriptor deserializerType="Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
<descriptor>
<encryption algorithm="AES_256_CBC" />
<validation algorithm="HMACSHA256" />
<masterKey p4:requiresEncryption="true" xmlns:p4="http://schemas.asp.net/2015/03/dataProtection">
<!-- Warning: the key below is in an unencrypted form. -->
<value>6FYfLJ67E4xM9ZCxLRkSQdA7jLBWPuji1eUzVuAz/npxC12+ke9mAqCbcNN2uGpTdsHP323Es7cb9xJEDSJhuQ==</value>
</masterKey>
</descriptor>
</descriptor>
</key>

View file

@ -0,0 +1 @@
171

View file

@ -0,0 +1,5 @@
ef3825b896f5471abac53854cd506a89
This file is used to track the number of unique installs.
The first line in the file is used as an ID, which is sent to the server when checking for updates.
If the first line is blank, this installation will not be part of the usage statistics.

View file

@ -0,0 +1,4 @@
ef3825b896f5471abac53854cd506a89
This file is used to assign a unique ID to the machine, and used to identify the machine in reports.
The first line in the file is used as an ID, but can be changed with --machine-id for a single or multiple runs.

View file

@ -0,0 +1,78 @@
{
"CreatedByVersion": "2.2.0.1",
"Schedule": {
"ID": 1,
"Tags": [
"ID=1"
],
"Time": "2025-12-15T08:00:00Z",
"Repeat": "1D",
"LastRun": "0001-01-01T07:33:00Z",
"Rule": "AllowedWeekDays=Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday",
"AllowedDays": [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
]
},
"Backup": {
"ID": "1",
"ExternalID": null,
"Name": "docker and sys",
"Description": "docker files and configs \u002B timeshift",
"Tags": [],
"TargetURL": "file:///backups/",
"DBPath": "/data/Duplicati/SOJMUESMTL.sqlite",
"Sources": [
"/source/db/",
"/source/docker/",
"/source/local_configs/",
"/source/timeshift/"
],
"Settings": [
{
"Filter": "",
"Name": "encryption-module",
"Value": "aes",
"Argument": null
},
{
"Filter": "",
"Name": "passphrase",
"Value": "apts22$$",
"Argument": null
},
{
"Filter": "",
"Name": "compression-module",
"Value": "zip",
"Argument": null
},
{
"Filter": "",
"Name": "dblock-size",
"Value": "500MB",
"Argument": null
},
{
"Filter": "",
"Name": "retention-policy",
"Value": "1W:1D,4W:1W,12M:1M",
"Argument": null
}
],
"Filters": [],
"Metadata": {},
"IsTemporary": false
},
"DisplayNames": {
"/source/db/": "db",
"/source/docker/": "docker",
"/source/local_configs/": "local_configs",
"/source/timeshift/": "timeshift"
}
}

View file

@ -0,0 +1,22 @@
services:
duplicati:
image: duplicati/duplicati
container_name: duplicati
environment:
- PUID=1000
- PGID=1000
- TZ=America/Edmonton
- SETTINGS_ENCRYPTION_KEY=qVcy9W7jQc61PcYf7OdJLS2faN+ArbSrzSpk7Zj2chk=
volumes:
- /docker:/source/docker:ro
#- /db1:/source/db:ro
#- /mnt/namer2/timeshift:/source/timeshift:ro
#- /mnt/local_configs:/source/local_configs:ro
#- /mnt/backup/duplicati:/backups
- /docker/duplicati/config:/config
- /docker/duplicati/data:/data
ports:
- 8200:8200
restart: unless-stopped

View file

@ -0,0 +1,83 @@
services:
# 1. The Database
guac-db:
image: postgres:15-alpine
container_name: guac-db
user: root
cpus: 2.0
mem_limit: "4096m"
mem_reservation: "1024m"
restart: unless-stopped
environment:
POSTGRESQL_USERNAME: guacamole_user
POSTGRESQL_PASSWORD: apts22$$
POSTGRESQL_DB: guacamole_db
volumes:
- /docker/guacamole/init:/docker-entrypoint-initdb.d:ro # Loads schema on first boot
- /docker/guacamole/db:/var/lib/postgresql/data
networks:
- guac_internal
# 2. The "Proxy Daemon" (Translates RDP/SSH to HTML5)
guacd:
image: guacamole/guacd
container_name: guacd
cpus: 1.0
mem_limit: "1024m"
mem_reservation: "256m"
restart: unless-stopped
networks:
- guac_internal
- guac_ssh
# 3. The Web Interface
guacamole:
image: guacamole/guacamole
container_name: guacamole
restart: unless-stopped
user: root
cpus: 2.0
mem_limit: "3072m" # 3 GB
mem_reservation: "1024m"
depends_on:
- guac-db
- guacd
environment:
GUACD_HOSTNAME: guacd
POSTGRESQL_HOSTNAME: guac-db
POSTGRESQL_DATABASE: guacamole_db
POSTGRESQL_USERNAME: guacamole_user
POSTGRESQL_PASSWORD: apts22$$
CATALINA_OPTS: "-Djava.security.egd=file:/dev/./urandom -Xms1g -Xmx2g"
networks:
- guac_internal
- guac_external # Connects to Traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.guac.rule=Host(`ssh.mapletree.email`)"
- "traefik.http.routers.guac.entrypoints=websecure"
- "traefik.http.routers.guac.tls=true"
- "traefik.http.services.guac.loadbalancer.server.port=8080"
- "traefik.http.routers.guac.tls.certresolver=myresolver"
- "traefik.docker.network=guac_external"
# Middleware 1: Redirect
- "traefik.http.middlewares.guac-redirect.redirectregex.regex=^https://([^/]+)/?$$"
- "traefik.http.middlewares.guac-redirect.redirectregex.replacement=https://$${1}/guacamole/"
# Middleware 2: Disable Buffering (Stability Fix)
- "traefik.http.middlewares.guac-buffer.buffering.maxResponseBodyBytes=0"
- "traefik.http.middlewares.guac-buffer.buffering.maxRequestBodyBytes=0"
- "traefik.http.middlewares.guac-buffer.buffering.memRequestBodyBytes=0"
- "traefik.http.middlewares.guac-buffer.buffering.memResponseBodyBytes=0"
- "traefik.http.middlewares.guac-buffer.buffering.retryExpression=IsNetworkError() && Attempts() <= 2"
# Apply Both
- "traefik.http.routers.guac.middlewares=guac-redirect,guac-buffer"
networks:
guac_internal:
internal: true
guac_external:
external: true
guac_ssh:
external: true

View file

@ -0,0 +1,793 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Connection group types
--
CREATE TYPE guacamole_connection_group_type AS ENUM(
'ORGANIZATIONAL',
'BALANCING'
);
--
-- Entity types
--
CREATE TYPE guacamole_entity_type AS ENUM(
'USER',
'USER_GROUP'
);
--
-- Object permission types
--
CREATE TYPE guacamole_object_permission_type AS ENUM(
'READ',
'UPDATE',
'DELETE',
'ADMINISTER'
);
--
-- System permission types
--
CREATE TYPE guacamole_system_permission_type AS ENUM(
'CREATE_CONNECTION',
'CREATE_CONNECTION_GROUP',
'CREATE_SHARING_PROFILE',
'CREATE_USER',
'CREATE_USER_GROUP',
'AUDIT',
'ADMINISTER'
);
--
-- Guacamole proxy (guacd) encryption methods
--
CREATE TYPE guacamole_proxy_encryption_method AS ENUM(
'NONE',
'SSL'
);
--
-- Table of connection groups. Each connection group has a name.
--
CREATE TABLE guacamole_connection_group (
connection_group_id serial NOT NULL,
parent_id integer,
connection_group_name varchar(128) NOT NULL,
type guacamole_connection_group_type
NOT NULL DEFAULT 'ORGANIZATIONAL',
-- Concurrency limits
max_connections integer,
max_connections_per_user integer,
enable_session_affinity boolean NOT NULL DEFAULT FALSE,
PRIMARY KEY (connection_group_id),
CONSTRAINT connection_group_name_parent
UNIQUE (connection_group_name, parent_id),
CONSTRAINT guacamole_connection_group_ibfk_1
FOREIGN KEY (parent_id)
REFERENCES guacamole_connection_group (connection_group_id)
ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_group_parent_id
ON guacamole_connection_group(parent_id);
--
-- Table of connections. Each connection has a name, protocol, and
-- associated set of parameters.
-- A connection may belong to a connection group.
--
CREATE TABLE guacamole_connection (
connection_id serial NOT NULL,
connection_name varchar(128) NOT NULL,
parent_id integer,
protocol varchar(32) NOT NULL,
-- Concurrency limits
max_connections integer,
max_connections_per_user integer,
-- Connection Weight
connection_weight integer,
failover_only boolean NOT NULL DEFAULT FALSE,
-- Guacamole proxy (guacd) overrides
proxy_port integer,
proxy_hostname varchar(512),
proxy_encryption_method guacamole_proxy_encryption_method,
PRIMARY KEY (connection_id),
CONSTRAINT connection_name_parent
UNIQUE (connection_name, parent_id),
CONSTRAINT guacamole_connection_ibfk_1
FOREIGN KEY (parent_id)
REFERENCES guacamole_connection_group (connection_group_id)
ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_parent_id
ON guacamole_connection(parent_id);
--
-- Table of base entities which may each be either a user or user group. Other
-- tables which represent qualities shared by both users and groups will point
-- to guacamole_entity, while tables which represent qualities specific to
-- users or groups will point to guacamole_user or guacamole_user_group.
--
CREATE TABLE guacamole_entity (
entity_id serial NOT NULL,
name varchar(128) NOT NULL,
type guacamole_entity_type NOT NULL,
PRIMARY KEY (entity_id),
CONSTRAINT guacamole_entity_name_scope
UNIQUE (type, name)
);
--
-- Table of users. Each user has a unique username and a hashed password
-- with corresponding salt. Although the authentication system will always set
-- salted passwords, other systems may set unsalted passwords by simply not
-- providing the salt.
--
CREATE TABLE guacamole_user (
user_id serial NOT NULL,
entity_id integer NOT NULL,
-- Optionally-salted password
password_hash bytea NOT NULL,
password_salt bytea,
password_date timestamptz NOT NULL,
-- Account disabled/expired status
disabled boolean NOT NULL DEFAULT FALSE,
expired boolean NOT NULL DEFAULT FALSE,
-- Time-based access restriction
access_window_start time,
access_window_end time,
-- Date-based access restriction
valid_from date,
valid_until date,
-- Timezone used for all date/time comparisons and interpretation
timezone varchar(64),
-- Profile information
full_name varchar(256),
email_address varchar(256),
organization varchar(256),
organizational_role varchar(256),
PRIMARY KEY (user_id),
CONSTRAINT guacamole_user_single_entity
UNIQUE (entity_id),
CONSTRAINT guacamole_user_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE
);
--
-- Table of user groups. Each user group may have an arbitrary set of member
-- users and member groups, with those members inheriting the permissions
-- granted to that group.
--
CREATE TABLE guacamole_user_group (
user_group_id serial NOT NULL,
entity_id integer NOT NULL,
-- Group disabled status
disabled boolean NOT NULL DEFAULT FALSE,
PRIMARY KEY (user_group_id),
CONSTRAINT guacamole_user_group_single_entity
UNIQUE (entity_id),
CONSTRAINT guacamole_user_group_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE
);
--
-- Table of users which are members of given user groups.
--
CREATE TABLE guacamole_user_group_member (
user_group_id integer NOT NULL,
member_entity_id integer NOT NULL,
PRIMARY KEY (user_group_id, member_entity_id),
-- Parent must be a user group
CONSTRAINT guacamole_user_group_member_parent
FOREIGN KEY (user_group_id)
REFERENCES guacamole_user_group (user_group_id) ON DELETE CASCADE,
-- Member may be either a user or a user group (any entity)
CONSTRAINT guacamole_user_group_member_entity
FOREIGN KEY (member_entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
--
-- Table of sharing profiles. Each sharing profile has a name, associated set
-- of parameters, and a primary connection. The primary connection is the
-- connection that the sharing profile shares, and the parameters dictate the
-- restrictions/features which apply to the user joining the connection via the
-- sharing profile.
--
CREATE TABLE guacamole_sharing_profile (
sharing_profile_id serial NOT NULL,
sharing_profile_name varchar(128) NOT NULL,
primary_connection_id integer NOT NULL,
PRIMARY KEY (sharing_profile_id),
CONSTRAINT sharing_profile_name_primary
UNIQUE (sharing_profile_name, primary_connection_id),
CONSTRAINT guacamole_sharing_profile_ibfk_1
FOREIGN KEY (primary_connection_id)
REFERENCES guacamole_connection (connection_id)
ON DELETE CASCADE
);
CREATE INDEX guacamole_sharing_profile_primary_connection_id
ON guacamole_sharing_profile(primary_connection_id);
--
-- Table of connection parameters. Each parameter is simply a name/value pair
-- associated with a connection.
--
CREATE TABLE guacamole_connection_parameter (
connection_id integer NOT NULL,
parameter_name varchar(128) NOT NULL,
parameter_value varchar(4096) NOT NULL,
PRIMARY KEY (connection_id,parameter_name),
CONSTRAINT guacamole_connection_parameter_ibfk_1
FOREIGN KEY (connection_id)
REFERENCES guacamole_connection (connection_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_parameter_connection_id
ON guacamole_connection_parameter(connection_id);
--
-- Table of sharing profile parameters. Each parameter is simply
-- name/value pair associated with a sharing profile. These parameters dictate
-- the restrictions/features which apply to the user joining the associated
-- connection via the sharing profile.
--
CREATE TABLE guacamole_sharing_profile_parameter (
sharing_profile_id integer NOT NULL,
parameter_name varchar(128) NOT NULL,
parameter_value varchar(4096) NOT NULL,
PRIMARY KEY (sharing_profile_id, parameter_name),
CONSTRAINT guacamole_sharing_profile_parameter_ibfk_1
FOREIGN KEY (sharing_profile_id)
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_sharing_profile_parameter_sharing_profile_id
ON guacamole_sharing_profile_parameter(sharing_profile_id);
--
-- Table of arbitrary user attributes. Each attribute is simply a name/value
-- pair associated with a user. Arbitrary attributes are defined by other
-- extensions. Attributes defined by this extension will be mapped to
-- properly-typed columns of a specific table.
--
CREATE TABLE guacamole_user_attribute (
user_id integer NOT NULL,
attribute_name varchar(128) NOT NULL,
attribute_value varchar(4096) NOT NULL,
PRIMARY KEY (user_id, attribute_name),
CONSTRAINT guacamole_user_attribute_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_user_attribute_user_id
ON guacamole_user_attribute(user_id);
--
-- Table of arbitrary user group attributes. Each attribute is simply a
-- name/value pair associated with a user group. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_user_group_attribute (
user_group_id integer NOT NULL,
attribute_name varchar(128) NOT NULL,
attribute_value varchar(4096) NOT NULL,
PRIMARY KEY (user_group_id, attribute_name),
CONSTRAINT guacamole_user_group_attribute_ibfk_1
FOREIGN KEY (user_group_id)
REFERENCES guacamole_user_group (user_group_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_user_group_attribute_user_group_id
ON guacamole_user_group_attribute(user_group_id);
--
-- Table of arbitrary connection attributes. Each attribute is simply a
-- name/value pair associated with a connection. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_connection_attribute (
connection_id integer NOT NULL,
attribute_name varchar(128) NOT NULL,
attribute_value varchar(4096) NOT NULL,
PRIMARY KEY (connection_id, attribute_name),
CONSTRAINT guacamole_connection_attribute_ibfk_1
FOREIGN KEY (connection_id)
REFERENCES guacamole_connection (connection_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_attribute_connection_id
ON guacamole_connection_attribute(connection_id);
--
-- Table of arbitrary connection group attributes. Each attribute is simply a
-- name/value pair associated with a connection group. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_connection_group_attribute (
connection_group_id integer NOT NULL,
attribute_name varchar(128) NOT NULL,
attribute_value varchar(4096) NOT NULL,
PRIMARY KEY (connection_group_id, attribute_name),
CONSTRAINT guacamole_connection_group_attribute_ibfk_1
FOREIGN KEY (connection_group_id)
REFERENCES guacamole_connection_group (connection_group_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_group_attribute_connection_group_id
ON guacamole_connection_group_attribute(connection_group_id);
--
-- Table of arbitrary sharing profile attributes. Each attribute is simply a
-- name/value pair associated with a sharing profile. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_sharing_profile_attribute (
sharing_profile_id integer NOT NULL,
attribute_name varchar(128) NOT NULL,
attribute_value varchar(4096) NOT NULL,
PRIMARY KEY (sharing_profile_id, attribute_name),
CONSTRAINT guacamole_sharing_profile_attribute_ibfk_1
FOREIGN KEY (sharing_profile_id)
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_sharing_profile_attribute_sharing_profile_id
ON guacamole_sharing_profile_attribute(sharing_profile_id);
--
-- Table of connection permissions. Each connection permission grants a user or
-- user group specific access to a connection.
--
CREATE TABLE guacamole_connection_permission (
entity_id integer NOT NULL,
connection_id integer NOT NULL,
permission guacamole_object_permission_type NOT NULL,
PRIMARY KEY (entity_id, connection_id, permission),
CONSTRAINT guacamole_connection_permission_ibfk_1
FOREIGN KEY (connection_id)
REFERENCES guacamole_connection (connection_id) ON DELETE CASCADE,
CONSTRAINT guacamole_connection_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_permission_connection_id
ON guacamole_connection_permission(connection_id);
CREATE INDEX guacamole_connection_permission_entity_id
ON guacamole_connection_permission(entity_id);
--
-- Table of connection group permissions. Each group permission grants a user
-- or user group specific access to a connection group.
--
CREATE TABLE guacamole_connection_group_permission (
entity_id integer NOT NULL,
connection_group_id integer NOT NULL,
permission guacamole_object_permission_type NOT NULL,
PRIMARY KEY (entity_id, connection_group_id, permission),
CONSTRAINT guacamole_connection_group_permission_ibfk_1
FOREIGN KEY (connection_group_id)
REFERENCES guacamole_connection_group (connection_group_id) ON DELETE CASCADE,
CONSTRAINT guacamole_connection_group_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_group_permission_connection_group_id
ON guacamole_connection_group_permission(connection_group_id);
CREATE INDEX guacamole_connection_group_permission_entity_id
ON guacamole_connection_group_permission(entity_id);
--
-- Table of sharing profile permissions. Each sharing profile permission grants
-- a user or user group specific access to a sharing profile.
--
CREATE TABLE guacamole_sharing_profile_permission (
entity_id integer NOT NULL,
sharing_profile_id integer NOT NULL,
permission guacamole_object_permission_type NOT NULL,
PRIMARY KEY (entity_id, sharing_profile_id, permission),
CONSTRAINT guacamole_sharing_profile_permission_ibfk_1
FOREIGN KEY (sharing_profile_id)
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE CASCADE,
CONSTRAINT guacamole_sharing_profile_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_sharing_profile_permission_sharing_profile_id
ON guacamole_sharing_profile_permission(sharing_profile_id);
CREATE INDEX guacamole_sharing_profile_permission_entity_id
ON guacamole_sharing_profile_permission(entity_id);
--
-- Table of system permissions. Each system permission grants a user or user
-- group a system-level privilege of some kind.
--
CREATE TABLE guacamole_system_permission (
entity_id integer NOT NULL,
permission guacamole_system_permission_type NOT NULL,
PRIMARY KEY (entity_id, permission),
CONSTRAINT guacamole_system_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_system_permission_entity_id
ON guacamole_system_permission(entity_id);
--
-- Table of user permissions. Each user permission grants a user or user group
-- access to another user (the "affected" user) for a specific type of
-- operation.
--
CREATE TABLE guacamole_user_permission (
entity_id integer NOT NULL,
affected_user_id integer NOT NULL,
permission guacamole_object_permission_type NOT NULL,
PRIMARY KEY (entity_id, affected_user_id, permission),
CONSTRAINT guacamole_user_permission_ibfk_1
FOREIGN KEY (affected_user_id)
REFERENCES guacamole_user (user_id) ON DELETE CASCADE,
CONSTRAINT guacamole_user_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_user_permission_affected_user_id
ON guacamole_user_permission(affected_user_id);
CREATE INDEX guacamole_user_permission_entity_id
ON guacamole_user_permission(entity_id);
--
-- Table of user group permissions. Each user group permission grants a user
-- or user group access to a another user group (the "affected" user group) for
-- a specific type of operation.
--
CREATE TABLE guacamole_user_group_permission (
entity_id integer NOT NULL,
affected_user_group_id integer NOT NULL,
permission guacamole_object_permission_type NOT NULL,
PRIMARY KEY (entity_id, affected_user_group_id, permission),
CONSTRAINT guacamole_user_group_permission_affected_user_group
FOREIGN KEY (affected_user_group_id)
REFERENCES guacamole_user_group (user_group_id) ON DELETE CASCADE,
CONSTRAINT guacamole_user_group_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_user_group_permission_affected_user_group_id
ON guacamole_user_group_permission(affected_user_group_id);
CREATE INDEX guacamole_user_group_permission_entity_id
ON guacamole_user_group_permission(entity_id);
--
-- Table of connection history records. Each record defines a specific user's
-- session, including the connection used, the start time, and the end time
-- (if any).
--
CREATE TABLE guacamole_connection_history (
history_id serial NOT NULL,
user_id integer DEFAULT NULL,
username varchar(128) NOT NULL,
remote_host varchar(256) DEFAULT NULL,
connection_id integer DEFAULT NULL,
connection_name varchar(128) NOT NULL,
sharing_profile_id integer DEFAULT NULL,
sharing_profile_name varchar(128) DEFAULT NULL,
start_date timestamptz NOT NULL,
end_date timestamptz DEFAULT NULL,
PRIMARY KEY (history_id),
CONSTRAINT guacamole_connection_history_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE SET NULL,
CONSTRAINT guacamole_connection_history_ibfk_2
FOREIGN KEY (connection_id)
REFERENCES guacamole_connection (connection_id) ON DELETE SET NULL,
CONSTRAINT guacamole_connection_history_ibfk_3
FOREIGN KEY (sharing_profile_id)
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE SET NULL
);
CREATE INDEX guacamole_connection_history_user_id
ON guacamole_connection_history(user_id);
CREATE INDEX guacamole_connection_history_connection_id
ON guacamole_connection_history(connection_id);
CREATE INDEX guacamole_connection_history_sharing_profile_id
ON guacamole_connection_history(sharing_profile_id);
CREATE INDEX guacamole_connection_history_start_date
ON guacamole_connection_history(start_date);
CREATE INDEX guacamole_connection_history_end_date
ON guacamole_connection_history(end_date);
CREATE INDEX guacamole_connection_history_connection_id_start_date
ON guacamole_connection_history(connection_id, start_date);
--
-- User login/logout history
--
CREATE TABLE guacamole_user_history (
history_id serial NOT NULL,
user_id integer DEFAULT NULL,
username varchar(128) NOT NULL,
remote_host varchar(256) DEFAULT NULL,
start_date timestamptz NOT NULL,
end_date timestamptz DEFAULT NULL,
PRIMARY KEY (history_id),
CONSTRAINT guacamole_user_history_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE SET NULL
);
CREATE INDEX guacamole_user_history_user_id
ON guacamole_user_history(user_id);
CREATE INDEX guacamole_user_history_start_date
ON guacamole_user_history(start_date);
CREATE INDEX guacamole_user_history_end_date
ON guacamole_user_history(end_date);
CREATE INDEX guacamole_user_history_user_id_start_date
ON guacamole_user_history(user_id, start_date);
--
-- User password history
--
CREATE TABLE guacamole_user_password_history (
password_history_id serial NOT NULL,
user_id integer NOT NULL,
-- Salted password
password_hash bytea NOT NULL,
password_salt bytea,
password_date timestamptz NOT NULL,
PRIMARY KEY (password_history_id),
CONSTRAINT guacamole_user_password_history_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_user_password_history_user_id
ON guacamole_user_password_history(user_id);
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
-- Create default user "guacadmin" with password "guacadmin"
INSERT INTO guacamole_entity (name, type) VALUES ('guacadmin', 'USER');
INSERT INTO guacamole_user (entity_id, password_hash, password_salt, password_date)
SELECT
entity_id,
decode('CA458A7D494E3BE824F5E1E175A1556C0F8EEF2C2D7DF3633BEC4A29C4411960', 'hex'), -- 'guacadmin'
decode('FE24ADC5E11E2B25288D1704ABE67A79E342ECC26064CE69C5B3177795A82264', 'hex'),
CURRENT_TIMESTAMP
FROM guacamole_entity WHERE name = 'guacadmin' AND guacamole_entity.type = 'USER';
-- Grant this user all system permissions
INSERT INTO guacamole_system_permission (entity_id, permission)
SELECT entity_id, permission::guacamole_system_permission_type
FROM (
VALUES
('guacadmin', 'CREATE_CONNECTION'),
('guacadmin', 'CREATE_CONNECTION_GROUP'),
('guacadmin', 'CREATE_SHARING_PROFILE'),
('guacadmin', 'CREATE_USER'),
('guacadmin', 'CREATE_USER_GROUP'),
('guacadmin', 'ADMINISTER')
) permissions (username, permission)
JOIN guacamole_entity ON permissions.username = guacamole_entity.name AND guacamole_entity.type = 'USER';
-- Grant admin permission to read/update/administer self
INSERT INTO guacamole_user_permission (entity_id, affected_user_id, permission)
SELECT guacamole_entity.entity_id, guacamole_user.user_id, permission::guacamole_object_permission_type
FROM (
VALUES
('guacadmin', 'guacadmin', 'READ'),
('guacadmin', 'guacadmin', 'UPDATE'),
('guacadmin', 'guacadmin', 'ADMINISTER')
) permissions (username, affected_username, permission)
JOIN guacamole_entity ON permissions.username = guacamole_entity.name AND guacamole_entity.type = 'USER'
JOIN guacamole_entity affected ON permissions.affected_username = affected.name AND guacamole_entity.type = 'USER'
JOIN guacamole_user ON guacamole_user.entity_id = affected.entity_id;

View file

@ -0,0 +1,2 @@
---
# sample kubernetes config

View file

@ -0,0 +1,20 @@
- Infrastructure:
- Technitium DNS:
icon: technitium-dns-server.png
href: https://dns.mapletree.email
description: Authoritative DNS
widget:
type: technitium
# Uses the Internal IP because we joined dns_internal
url: http://172.35.0.101:5380
token: "14df92da88e9a588ecad6ebd72a47dca1e5d71067553d68413b31e7c6b684acd"
- Traefik:
icon: traefik.png
href: https://traefik.mapletree.email
description: Edge Router
widget:
type: traefik
# Traefik usually lives on the host or a specific proxy network.
# If Traefik is NOT on dns_internal, you might need to use the Host IP here.
url: http://172.16.201.21:8080

View file

@ -0,0 +1,7 @@
---
# For configuration options and examples, please see:
# https://gethomepage.dev/configs/settings/
providers:
openweathermap: openweathermapapikey
weatherapi: weatherapiapikey

View file

@ -0,0 +1,27 @@
services:
homepage:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
restart: unless-stopped
volumes:
- /docker/homepage/config:/app/config
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- homepage_internal # For local stack comms
- homepage_external # For Traefik Ingress
- dns_dns_internal # For talking to Technitium API (Cross-stack)
labels:
- "traefik.enable=true"
- "traefik.docker.network=homepage_external"
- "traefik.http.routers.homepage.rule=Host(`home.mapletree.email`)"
- "traefik.http.routers.homepage.entrypoints=web,websecure"
- "traefik.http.routers.homepage.tls.certresolver=myresolver"
- "traefik.http.services.homepage.loadbalancer.server.port=3000"
networks:
homepage_internal:
driver: bridge
homepage_external:
external: true
dns_dns_internal:
external: true # Join the existing DNS backend network

View file

@ -0,0 +1,2 @@
#!/bin/sh
curl -f http://localhost:9120/ > /dev/null 2>&1

View file

@ -0,0 +1,39 @@
global_defs {
router_id 50
script_user root
enable_script_security
}
vrrp_script chk_traefik {
# CONTAINER PATH (Inside the mount)
script "/usr/bin/curl -f http://localhost:8080/"
interval 2
weight -5
fall 2
rise 1
}
vrrp_instance VI_1 {
state {{STATE}}
interface eth0
virtual_router_id 50
priority {{PRIORITY}}
advert_int 1
unicast_peer {
{{PEER}}
}
authentication {
auth_type PASS
auth_pass {{PASSWORD}}
}
virtual_ipaddress {
{{VIP}}
}
track_script {
chk_traefik
}
}

View file

@ -0,0 +1,22 @@
services:
keepalived:
image: osixia/keepalived:latest
container_name: keepalived
restart: unless-stopped
network_mode: host
cap_add:
- NET_ADMIN
- NET_BROADCAST
- NET_RAW
volumes:
# 1. Mount the Check Script Folder
- /docker/keepalived/checks:/checks
# 2. Mount the Config File (The Nuclear Option)
- /docker/keepalived/config:/usr/local/etc/keepalived
#environment:
# We still need this to tell the container where to look
#- KEEPALIVED_CONFIG=/config/keepalived.conf
# We can remove all the other KEEPALIVED_* variables now!
# (They are handled inside the file)

View file

@ -0,0 +1 @@
{"uuid":"f4e4e2ea-a357-4393-b495-1e600c222ee4"}

View file

@ -0,0 +1,79 @@
{
"_comment": "Created at 2026-01-26 15:30:14Z, not sent because reporting is disabled.",
"version": "v2.7.0",
"commit": "0d5eb3343a50b800634cc08ace608bb6f3a3f74b",
"branch": "unknown",
"dirty": true,
"package": "docker",
"debug": false,
"build_environment": {
"-buildmode": "exe",
"-compiler": "gc",
"-trimpath": "true",
"CGO_ENABLED": "0",
"GOAMD64": "v1",
"GOARCH": "amd64",
"GOOS": "linux",
"go.runtime": "go1.25.4",
"go.version": "go1.25.4",
"vcs": "git",
"vcs.modified": "true",
"vcs.revision": "0d5eb3343a50b800634cc08ace608bb6f3a3f74b",
"vcs.time": "2025-11-10T17:18:24Z"
},
"os": "linux",
"arch": "amd64",
"postgresql_version": "PostgreSQL 17.6 (Debian 17.6-2.pgdg12+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14+deb12u1) 12.2.0, 64-bit",
"documentdb_version": "0.107.0 gitref: HEAD sha:e63835403d buildId:0",
"uuid": "f4e4e2ea-a357-4393-b495-1e600c222ee4",
"uptime": 10132943000413,
"command_metrics": {
"OP_MSG": {
"createIndexes": {
"unknown": {
"ok": 57
}
},
"delete": {
"unknown": {
"ok": 16
}
},
"find": {
"unknown": {
"ok": 56606
}
},
"hello": {
"unknown": {
"ok": 1013
}
},
"insert": {
"unknown": {
"ok": 2123
}
},
"isMaster": {
"unknown": {
"ok": 11
}
},
"ping": {
"unknown": {
"ok": 169
}
},
"saslContinue": {
"unknown": {
"ok": 10
}
},
"update": {
"unknown": {
"ok": 332
}
}
}
}
}

View file

@ -0,0 +1,56 @@
services:
gitea-postgres:
image: docker.io/library/postgres:15
environment:
- POSTGRES_USER=${GITEA_DB_USERNAME}
- POSTGRES_PASSWORD=${GITEA_DB_PASSWORD}
- POSTGRES_DB=gitea
volumes:
- /docker/management/gitea-postgres/postgres:/var/lib/postgresql/data
container_name: gitea-postgres
labels:
- "komodo.skip=true"
restart: unless-stopped
ports:
- "5433:5432"
networks:
- gitea_internal
gitea:
image: gitea/gitea:latest
container_name: gitea
ports:
# - "3002:3000"
- "222:22"
networks:
- gitea_internal
volumes:
- /docker/management/gitea:/data
- /docker/management/gitea-postgres:/var/lib/gitea
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /docker:/docker
environment:
- TZ=America/Edmonton
- ROOT_URL=${GITEA_ROOT_URL}
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=gitea-postgres:5432
- GITEA__database__NAME=gitea
- GITEA__database__USER=${GITEA_DB_USERNAME}
- GITEA__database__PASSWD=${GITEA_DB_PASSWORD}
- GITEA__actions__ENABLED=true
restart: unless-stopped
depends_on:
- gitea-postgres
labels:
- "traefik.enable=true"
- "traefik.http.routers.gitea.rule=Host(`git.mapletree.email`)"
- "traefik.http.routers.gitea.entrypoints=websecure"
- "traefik.http.routers.gitea.tls=true"
- "traefik.http.routers.gitea.tls.certresolver=myresolver"
- "traefik.docker.network=gitea_internal"
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
networks:
gitea_internal:
driver: bridge

View file

@ -0,0 +1,53 @@
services:
komodo:
image: ghcr.io/moghtech/komodo-core:latest
container_name: komodo
cpus: 2.0
mem_limit: "2048m"
mem_reservation: "512m"
env_file:
- /docker/management/.env
ports:
- "9120:9120"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /root/.ssh:/home/komodo/.ssh:ro
- /docker/management/komodo/config:/config
- /docker/management/komodo/backups:/backups
- /docker/management/komodo/core-etc:/etc/komodo
- /docker/management/komodo/var:/var/lib/komodo
- /docker/management/komodo/repo-cache:/repo-cache
- /docker:/docker
environment:
KOMODO_DATABASE_ADDRESS: ferretdb:27017
KOMODO_DATABASE_USERNAME: ${KOMODO_DB_USERNAME}
KOMODO_DATABASE_PASSWORD: ${KOMODO_DB_PASSWORD}
depends_on:
- komodo-mongo
restart: unless-stopped
labels:
- "komodo.skip=true"
- KOMODO_DATABASE_URI=mongodb://172.16.201.206:27017,172.16.201.106:27017/komodo?replicaSet=rs0
- KOMODO_DATABASE_ADDRESS=
networks:
- komodo_external
- management_internal
komodo-mongo:
image: mongo:7.0
container_name: komodo-mongo
restart: always
network_mode: host
command: ["--replSet", "rs0", "--bind_ip_all", "--port", "27017"]
volumes:
- /docker/management/mongodb:/data/db
networks:
komodo_external:
external: true
management_internal:
internal: true

View file

@ -0,0 +1,73 @@
providers:
- name: gitea
type: git
url: ssh://git@172.16.201.21:222
username: admin
ssh_key_path: /home/komodo/.ssh/id_ed25519
stacks:
- name: management
provider: gitea
repo: admin/management
branch: main
compose_file: docker-compose.yml
- name: servarr
provider: gitea
repo: admin/servarr
branch: main
compose_file: docker-compose.yml
- name: media-services
provider: gitea
repo: admin/media-services
branch: main
compose_file: docker-compose.yml
- name: qbittorrent
provider: gitea
repo: admin/qbittorrent
branch: main
compose_file: docker-compose.yml
- name: monitoring
provider: gitea
repo: admin/monitoring
branch: main
compose_file: docker-compose.yml
- name: homeassistant
provider: gitea
repo: admin/homeassistant
branch: main
compose_file: docker-compose.yml
- name: manyfold
provider: gitea
repo: admin/manyfold
branch: main
compose_file: docker-compose.yml
- name: smf
provider: gitea
repo: admin/smf
branch: main
compose_file: docker-compose.yml
- name: sqlitebrowser
provider: gitea
repo: admin/sqlitebrowser
branch: main
compose_file: docker-compose.yml
- name: syncthing
provider: gitea
repo: admin/syncthing
branch: main
compose_file: docker-compose.yml
- name: traefik
provider: gitea
repo: admin/traefik
branch: main
compose_file: docker-compose.yml

View file

@ -0,0 +1,33 @@
services:
wud:
image: fmartinou/whats-up-docker:latest
container_name: wud
user: "1000:994"
cpus: 1.0
mem_limit: "1024m"
mem_reservation: "256m"
ports:
- "3001:3000"
networks:
- management_internal
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /docker/management/wud/etc:/etc/wud
- /docker/management/wud/var:/var/lib/wud
- /docker/management/wud-db:/var/lib/wud/db
environment:
- WUD_AUTOUPDATE=false
- TZ=America/Edmonton
- WUD_WATCHER_LOCAL_WATCHBYDEFAULT=true
- WUD_WATCHER_LOCAL_SOCKET=/var/run/docker.sock
- WUD_REGISTRIES_LSCR_ENABLED=true
- WUD_REGISTRY_LSCR_USERNAME=jkilloran82
- WUD_REGISTRY_LSCR_TOKEN=${GITHUB_PAT_TOKEN}
- WUD_TRIGGER_SMTP_EMAIL_FROM=wud@mapletree.email
- WUD_TRIGGER_SMTP_EMAIL_TO=jkilloran@doppio.ca
- WUD_TRIGGER_SMTP_EMAIL_HOST=10.19.19.3
- WUD_TRIGGER_SMTP_EMAIL_PORT=25
- WUD_TRIGGER_SMTP_EMAIL_TLS_ENABLED=false
- WUD_TRIGGER_SMTP_EMAIL_TLS_VERIFY=false
restart: unless-stopped

View file

@ -0,0 +1,11 @@
services:
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
ports:
- "9093:9093"
volumes:
- /docker/monitoring/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
- /docker/monitoring/alertmanager-db:/alertmanager
user: "1000:1000"
restart: unless-stopped

View file

@ -0,0 +1,11 @@
global:
smtp_smarthost: '10.19.19.3:587'
smtp_from: 'alertmanager@mapletree.email'
route:
receiver: 'email'
receivers:
- name: 'email'
email_configs:
- to: 'jkilloran@doppio.ca'

View file

@ -0,0 +1,31 @@
services:
cadvisor:
image: ghcr.io/google/cadvisor:latest
container_name: cadvisor
ports:
- "8082:8080" # remapped to avoid conflict
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker:/var/lib/docker:ro
command:
- --docker_only
- --store_container_labels=true
environment:
- TZ=America/Edmonton
restart: unless-stopped
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "2999:3000"
volumes:
- /docker/monitoring/grafana:/etc/grafana
- /docker/monitoring/grafana-db:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=changeme
user: "1000:1000"
restart: unless-stopped

View file

@ -0,0 +1,14 @@
services:
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "2999:3000"
volumes:
- /docker/monitoring/grafana:/etc/grafana
- /docker/monitoring/grafana-db:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=changeme
user: "1000:1000"
restart: unless-stopped

View file

@ -0,0 +1,75 @@
{
"id": null,
"title": "Host & Docker Monitoring",
"tags": ["system", "docker"],
"timezone": "browser",
"schemaVersion": 36,
"version": 1,
"panels": [
{
"type": "graph",
"title": "Host CPU Usage",
"datasource": "Prometheus",
"targets": [
{
"expr": "100 - (avg by(instance)(rate(node_cpu_seconds_total{mode=\"idle\"}[5m])) * 100)",
"legendFormat": "CPU Usage"
}
],
"lines": true,
"fill": 1
},
{
"type": "graph",
"title": "Host Memory Usage",
"datasource": "Prometheus",
"targets": [
{
"expr": "(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100",
"legendFormat": "Memory Usage"
}
],
"lines": true,
"fill": 1
},
{
"type": "graph",
"title": "Host Disk Usage",
"datasource": "Prometheus",
"targets": [
{
"expr": "100 - (node_filesystem_avail_bytes{fstype!=\"tmpfs\"} / node_filesystem_size_bytes{fstype!=\"tmpfs\"} * 100)",
"legendFormat": "{{mountpoint}}"
}
],
"lines": true,
"fill": 1
},
{
"type": "graph",
"title": "Container CPU Usage",
"datasource": "Prometheus",
"targets": [
{
"expr": "rate(container_cpu_usage_seconds_total[5m])",
"legendFormat": "{{container_label_com_docker_swarm_service_name}}"
}
],
"lines": true,
"fill": 1
},
{
"type": "graph",
"title": "Container Memory Usage",
"datasource": "Prometheus",
"targets": [
{
"expr": "container_memory_usage_bytes",
"legendFormat": "{{container_label_com_docker_swarm_service_name}}"
}
],
"lines": true,
"fill": 1
}
]
}

View file

View file

@ -0,0 +1,7 @@
services:
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
pid: host
network_mode: host
restart: unless-stopped

View file

@ -0,0 +1,12 @@
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- /docker/monitoring/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- /docker/monitoring/prometheus/alert_rules.yml:/etc/prometheus/alert_rules.yml:ro
- /docker/monitoring/prometheus-db:/prometheus
user: "1000:1000"
restart: unless-stopped

View file

@ -0,0 +1,42 @@
groups:
- name: system.rules
interval: 30s
rules:
- alert: HighCPUUsage
expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
for: 2m
labels:
severity: warning
annotations:
summary: "High CPU usage on {{ $labels.instance }}"
description: "CPU usage > 90% for 2 minutes."
- alert: HighMemoryUsage
expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 85
for: 2m
labels:
severity: warning
annotations:
summary: "High memory usage on {{ $labels.instance }}"
description: "Memory usage > 85% for 2 minutes."
- alert: LowDiskSpace
expr: (node_filesystem_avail_bytes{fstype!="tmpfs"} / node_filesystem_size_bytes{fstype!="tmpfs"}) * 100 < 15
for: 5m
labels:
severity: critical
annotations:
summary: "Low disk space on {{ $labels.instance }} {{ $labels.mountpoint }}"
description: "Disk space < 15% available for 5 minutes."
- name: docker.rules
interval: 30s
rules:
- alert: ContainerRestartingFrequently
expr: rate(container_restart_count[10m]) > 3
for: 5m
labels:
severity: warning
annotations:
summary: "Container restarting frequently: {{ $labels.container_label_com_docker_swarm_service_name }}"
description: "Container restarted more than 3 times in 10 minutes."

View file

@ -0,0 +1,27 @@
global:
scrape_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
rule_files:
- /etc/prometheus/alert_rules.yml
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['172.16.201.21:9100']
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080'] # container port still 8080
- job_name: 'blocky'
static_configs:
- targets: ['blocky-host1:9090']
- job_name: 'technitium'
static_configs:
- targets: ['172.16.201.21:8081']

View file

@ -0,0 +1,24 @@
services:
smtp-relay:
image: loganmarchione/docker-postfixrelay:latest
container_name: smtp_relay
restart: always
ports:
- "25:25"
environment:
# 1. THE UPSTREAM SMARTHOST (Where mail goes)
- RELAY_HOST=smtp-relay.brevo.com
- RELAY_PORT=587
# 2. INTERNAL SECURITY (Who can send)
# Allow your entire subnet (e.g., 192.168.1.0/24) to send without auth
- MYNETWORKS=172.16.201.0/24 10.19.19.0/24 192.168.19.0/24
# 3. IDENTIFICATION
# The hostname this relay announces itself as
- SYSTEM_TIMEZONE=America/Edmonton
- MESSAGE_SIZE_LIMIT=10240000
volumes:
# Optional: Persist the mail queue so you don't lose alerts if the container restarts
- /docker/smtp-relay/queue:/var/spool/postfix

View file

@ -0,0 +1 @@
[]

View file

@ -0,0 +1,33 @@
default_config:
bluetooth: false
http:
use_x_forwarded_for: true
trusted_proxies:
- 172.16.201.21
- 127.0.0.1
- 192.168.208.0/24
- 192.168.32.0/24
- 192.168.16.0/24
- 192.168.0.0/24
- 172.27.0.0/24
frontend:
themes: !include_dir_merge_named themes
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
mqtt:
host: 172.16.201.21
port: 1883
notify:
- name: maplemail
platform: smtp
server: 10.19.19.3
port: 25
sender: camera@mapletree.email
recipient: jkilloran@doppio.ca
encryption: none

View file

View file

View file

View file

@ -0,0 +1,4 @@
# Use this file to store secrets like usernames and passwords.
# Learn more at https://www.home-assistant.io/docs/configuration/secrets/
some_password: welcome

26
lxc2/homeassistant/frigate.yml Executable file
View file

@ -0,0 +1,26 @@
services:
frigate:
image: ghcr.io/blakeblackshear/frigate:stable
container_name: frigate
restart: unless-stopped
privileged: true
shm_size: 512m
volumes:
- /etc/localtime:/etc/localtime:ro
- /docker/homeassistant/frigate:/config
- /mnt/local_configs/frigate/cache:/tmp/cache
- /pool/securitycameras:/media
ports:
- "5000:5000"
- "1935:1935"
runtime: nvidia
environment:
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=all
- FRIGATE_SQLITE_PATH=/config/frigate.db
- FRIGATE_SQLITE_JOURNAL_MODE=DELETE
- PUID=1000
- PGID=1000
cpus: "2.0"
mem_limit: "6144m"
mem_reservation: "2048m"

View file

@ -0,0 +1,17 @@
services:
homeassistant:
container_name: homeassistant
image: "lscr.io/linuxserver/homeassistant:latest"
network_mode: host
volumes:
- /docker/homeassistant/homeassistant:/config
- /etc/localtime:/etc/localtime:ro
- /run/dbus:/run/dbus:ro
- /var/run/dbus:/var/run/dbus:ro
restart: unless-stopped
privileged: true
environment:
- MATTER_SERVER_URL=http://172.16.201.21:5580
- DOCKER_MODS=linuxserver/mods:homeassistant-hacs
entrypoint: ["/init"]
#entrypoint: ["/bin/sh", "-c", "/update_kwikset.sh && exec /entrypoint.sh"]

View file

@ -0,0 +1 @@
{"pid": 178, "version": 1, "ha_version": "2025.12.5", "start_ts": 1768761128.445899}

View file

@ -0,0 +1,27 @@
- id: frigate_alert_any_detection
alias: Frigate Multi-Camera Motion Alert via MQTT
description: Send push + email when selected cameras detect motion
triggers:
- topic: frigate/events
trigger: mqtt
conditions:
- condition: template
value_template: '{{ trigger.payload_json[''type''] == ''new'' }}'
actions:
- variables:
camera: '{{ trigger.payload_json[''camera''] }}'
snapshot_url: '{{ trigger.payload_json[''snapshot''] }}'
- data:
title: Frigate Alert
message: Motion detected on {{ camera }}
data:
image: '{{ snapshot_url }}'
action: notify.mobile_app_pixel_10_pro
- data:
title: Frigate Alert
message: Motion detected on {{ camera }}
data:
images:
- '{{ snapshot_url }}'
action: notify.maplemail
mode: single

View file

@ -0,0 +1,26 @@
- id: '1764940364873'
alias: Frigate Any Detection Alert (Email)
description: Send an email when Frigate detects anything
triggers:
- event_type: frigate_event
event_data:
type: end
trigger: event
actions:
- device_id: a695c9ad16dafaf40dca4bf7de3d3002
domain: mobile_app
type: notify
message: Motion Detection
data:
title: Frigate Alert - {{ trigger.event['after']['label'] }} detected
message: 'Camera {{ trigger.event[''after''][''camera''] }} detected a {{ trigger.event[''after''][''label'']
}}
'
data:
image: /api/frigate/notifications/{{ trigger.event['after']['id'] }}/snapshot.jpg
- action: notify.notify
metadata: {}
data:
message: motion detected
mode: single

View file

@ -0,0 +1 @@
{"slug": "bb71d2bd", "version": 2, "name": "pre-docker-export", "date": "2025-10-15T16:46:33.893051+00:00", "type": "partial", "supervisor_version": "2025.10.0", "extra": {"instance_id": "6a372b8180c14e36a3116d2f24c0d04e", "with_automatic_settings": false, "supervisor.backup_request_date": "2025-10-15T10:46:33.891171-06:00"}, "folders": ["media", "share", "ssl"], "repositories": ["https://github.com/music-assistant/home-assistant-addon", "https://github.com/wez/govee2mqtt", "https://github.com/esphome/home-assistant-addon", "https://github.com/hassio-addons/repository"], "addons": [{"slug": "core_matter_server", "name": "Matter Server", "version": "8.1.1", "size": 0.0}, {"slug": "core_mosquitto", "name": "Mosquitto broker", "version": "6.5.2", "size": 0.0}, {"slug": "b9845f46_govee2mqtt", "name": "Govee to MQTT Bridge", "version": "2025.04.13-17d43d72", "size": 0.0}, {"slug": "core_letsencrypt", "name": "Let's Encrypt", "version": "5.4.9", "size": 0.0}], "docker": {"registries": {}, "enable_ipv6": null, "mtu": null}, "protected": false, "crypto": "aes128", "compressed": true, "homeassistant": {"version": "2025.10.2", "exclude_database": false, "size": 0.0}}

View file

@ -0,0 +1,33 @@
default_config:
http:
use_x_forwarded_for: true
trusted_proxies:
- 172.16.201.21
- 127.0.0.1
- 192.168.208.0/24
- 192.168.32.0/24
- 192.168.16.0/24
- 192.168.0.0/24
- 172.27.0.0/24
frontend:
themes: !include_dir_merge_named themes
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
#mqtt:
# host: 172.16.201.21
# port: 1883
notify:
- name: maplemail
platform: smtp
server: 10.19.19.3
port: 25
sender: camera@mapletree.email
recipient: jkilloran@doppio.ca
encryption: none

View file

@ -0,0 +1,190 @@
2026-01-18 06:35:02.277 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration hacs which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2026-01-18 06:35:02.278 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration frigate which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2026-01-18 06:35:02.278 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration kwikset which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2026-01-18 06:35:02.780 WARNING (Recorder) [homeassistant.components.recorder.util] The system could not validate that the sqlite3 database at //config/home-assistant_v2.db was shutdown cleanly
2026-01-18 06:35:02.801 WARNING (Recorder) [homeassistant.components.recorder.util] Ended unfinished session (id=69 from 2026-01-17 16:29:37.893205)
2026-01-18 06:35:02.938 WARNING (MainThread) [dbus_fast.message_bus] could not shut down socket
Traceback (most recent call last):
File "/usr/local/lib/python3.13/site-packages/dbus_fast/aio/message_bus.py", line 252, in on_hello
raise err
File "src/dbus_fast/aio/message_reader.py", line 25, in dbus_fast.aio.message_reader._message_reader
File "src/dbus_fast/_private/unmarshaller.py", line 870, in dbus_fast._private.unmarshaller.Unmarshaller._unmarshall
File "src/dbus_fast/_private/unmarshaller.py", line 734, in dbus_fast._private.unmarshaller.Unmarshaller._read_header
File "src/dbus_fast/_private/unmarshaller.py", line 457, in dbus_fast._private.unmarshaller.Unmarshaller._read_to_pos
File "src/dbus_fast/_private/unmarshaller.py", line 416, in dbus_fast._private.unmarshaller.Unmarshaller._read_sock_without_fds
File "src/dbus_fast/_private/unmarshaller.py", line 411, in dbus_fast._private.unmarshaller.Unmarshaller._read_sock_without_fds
ConnectionResetError: [Errno 104] Connection reset by peer
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "src/dbus_fast/message_bus.py", line 532, in dbus_fast.message_bus.BaseMessageBus.disconnect
OSError: [Errno 9] Bad file descriptor
2026-01-18 06:35:02.949 WARNING (MainThread) [dbus_fast.message_bus] could not shut down socket
Traceback (most recent call last):
File "/usr/local/lib/python3.13/site-packages/dbus_fast/aio/message_bus.py", line 252, in on_hello
raise err
File "src/dbus_fast/aio/message_reader.py", line 25, in dbus_fast.aio.message_reader._message_reader
File "src/dbus_fast/_private/unmarshaller.py", line 870, in dbus_fast._private.unmarshaller.Unmarshaller._unmarshall
File "src/dbus_fast/_private/unmarshaller.py", line 734, in dbus_fast._private.unmarshaller.Unmarshaller._read_header
File "src/dbus_fast/_private/unmarshaller.py", line 457, in dbus_fast._private.unmarshaller.Unmarshaller._read_to_pos
File "src/dbus_fast/_private/unmarshaller.py", line 418, in dbus_fast._private.unmarshaller.Unmarshaller._read_sock_without_fds
EOFError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "src/dbus_fast/message_bus.py", line 532, in dbus_fast.message_bus.BaseMessageBus.disconnect
OSError: [Errno 9] Bad file descriptor
2026-01-18 06:35:02.950 WARNING (MainThread) [dbus_fast.message_bus] could not shut down socket
Traceback (most recent call last):
File "/usr/local/lib/python3.13/site-packages/bluetooth_adapters/dbus.py", line 113, in _get_dbus_managed_objects
await bus.connect()
File "/usr/local/lib/python3.13/site-packages/dbus_fast/aio/message_bus.py", line 269, in connect
return await future
^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/dbus_fast/aio/message_bus.py", line 252, in on_hello
raise err
File "src/dbus_fast/aio/message_reader.py", line 25, in dbus_fast.aio.message_reader._message_reader
File "src/dbus_fast/_private/unmarshaller.py", line 870, in dbus_fast._private.unmarshaller.Unmarshaller._unmarshall
File "src/dbus_fast/_private/unmarshaller.py", line 734, in dbus_fast._private.unmarshaller.Unmarshaller._read_header
File "src/dbus_fast/_private/unmarshaller.py", line 457, in dbus_fast._private.unmarshaller.Unmarshaller._read_to_pos
File "src/dbus_fast/_private/unmarshaller.py", line 418, in dbus_fast._private.unmarshaller.Unmarshaller._read_sock_without_fds
EOFError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "src/dbus_fast/message_bus.py", line 532, in dbus_fast.message_bus.BaseMessageBus.disconnect
OSError: [Errno 9] Bad file descriptor
2026-01-18 06:35:02.951 ERROR (MainThread) [homeassistant.setup] Error during setup of component bluetooth:
Traceback (most recent call last):
File "/usr/local/lib/python3.13/site-packages/homeassistant/setup.py", line 425, in _async_setup_component
result = await task
^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/homeassistant/components/bluetooth/__init__.py", line 244, in async_setup
await manager.async_setup()
File "/usr/local/lib/python3.13/site-packages/homeassistant/components/bluetooth/manager.py", line 181, in async_setup
await super().async_setup()
File "src/habluetooth/manager.py", line 353, in async_setup
File "src/habluetooth/manager.py", line 294, in _async_refresh_adapters
File "/usr/local/lib/python3.13/site-packages/bluetooth_adapters/systems/linux.py", line 42, in refresh
await asyncio.gather(*futures)
File "/usr/local/lib/python3.13/site-packages/bluetooth_adapters/dbus.py", line 41, in load
self._packed_managed_objects = await _get_dbus_managed_objects()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/bluetooth_adapters/dbus.py", line 113, in _get_dbus_managed_objects
await bus.connect()
File "/usr/local/lib/python3.13/site-packages/dbus_fast/aio/message_bus.py", line 269, in connect
return await future
^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/dbus_fast/aio/message_bus.py", line 252, in on_hello
raise err
File "src/dbus_fast/aio/message_reader.py", line 25, in dbus_fast.aio.message_reader._message_reader
File "src/dbus_fast/_private/unmarshaller.py", line 870, in dbus_fast._private.unmarshaller.Unmarshaller._unmarshall
File "src/dbus_fast/_private/unmarshaller.py", line 734, in dbus_fast._private.unmarshaller.Unmarshaller._read_header
File "src/dbus_fast/_private/unmarshaller.py", line 457, in dbus_fast._private.unmarshaller.Unmarshaller._read_to_pos
File "src/dbus_fast/_private/unmarshaller.py", line 418, in dbus_fast._private.unmarshaller.Unmarshaller._read_sock_without_fds
EOFError
2026-01-18 06:35:04.923 ERROR (MainThread) [homeassistant.setup] Unable to set up dependencies of 'default_config'. Setup failed for dependencies: ['bluetooth']
2026-01-18 06:35:04.923 ERROR (MainThread) [homeassistant.setup] Setup failed for 'default_config': Could not setup dependencies: bluetooth
2026-01-18 06:45:02.875 ERROR (MainThread) [async_upnp_client.ssdp] Received error: [Errno 99] Address not available, transport: <_SelectorDatagramTransport fd=33 read=polling write=<idle, bufsize=0>>, socket: <asyncio.TransportSocket fd=33, family=10, type=2, proto=0, laddr=('::', 53125, 0, 0)>
2026-01-18 08:00:56.483 ERROR (MainThread) [pysmartthings] Connection error occurred while subscribing to events
Traceback (most recent call last):
File "/usr/local/lib/python3.13/site-packages/pysmartthings/smartthings.py", line 592, in subscribe
await self._internal_subscribe(session, subscription_url)
File "/usr/local/lib/python3.13/site-packages/pysmartthings/smartthings.py", line 504, in _internal_subscribe
async for event in event_source:
...<49 lines>...
break
File "/usr/local/lib/python3.13/site-packages/aiohttp_sse_client2/client.py", line 157, in __anext__
async for line_in_bytes in self._response.content:
...<21 lines>...
self._process_field(line, '')
File "/usr/local/lib/python3.13/site-packages/aiohttp/streams.py", line 52, in __anext__
rv = await self.read_func()
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/aiohttp/streams.py", line 360, in readline
return await self.readuntil()
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/aiohttp/streams.py", line 394, in readuntil
await self._wait("readuntil")
File "/usr/local/lib/python3.13/site-packages/aiohttp/streams.py", line 355, in _wait
await waiter
aiohttp.client_exceptions.SocketTimeoutError: Timeout on reading data from socket
2026-01-18 08:05:38.187 ERROR (MainThread) [async_upnp_client.ssdp] Received error: [Errno 99] Address not available, transport: <_SelectorDatagramTransport fd=33 read=polling write=<idle, bufsize=0>>, socket: <asyncio.TransportSocket fd=33, family=10, type=2, proto=0, laddr=('::', 53125, 0, 0)>
2026-01-18 08:35:38.189 ERROR (MainThread) [async_upnp_client.ssdp] Received error: [Errno 99] Address not available, transport: <_SelectorDatagramTransport fd=33 read=polling write=<idle, bufsize=0>>, socket: <asyncio.TransportSocket fd=33, family=10, type=2, proto=0, laddr=('::', 53125, 0, 0)>
2026-01-18 08:45:38.190 ERROR (MainThread) [async_upnp_client.ssdp] Received error: [Errno 99] Address not available, transport: <_SelectorDatagramTransport fd=33 read=polling write=<idle, bufsize=0>>, socket: <asyncio.TransportSocket fd=33, family=10, type=2, proto=0, laddr=('::', 53125, 0, 0)>
2026-01-18 09:15:38.192 ERROR (MainThread) [async_upnp_client.ssdp] Received error: [Errno 99] Address not available, transport: <_SelectorDatagramTransport fd=33 read=polling write=<idle, bufsize=0>>, socket: <asyncio.TransportSocket fd=33, family=10, type=2, proto=0, laddr=('::', 53125, 0, 0)>
2026-01-18 09:25:38.193 ERROR (MainThread) [async_upnp_client.ssdp] Received error: [Errno 99] Address not available, transport: <_SelectorDatagramTransport fd=33 read=polling write=<idle, bufsize=0>>, socket: <asyncio.TransportSocket fd=33, family=10, type=2, proto=0, laddr=('::', 53125, 0, 0)>
2026-01-18 09:55:38.194 ERROR (MainThread) [async_upnp_client.ssdp] Received error: [Errno 99] Address not available, transport: <_SelectorDatagramTransport fd=33 read=polling write=<idle, bufsize=0>>, socket: <asyncio.TransportSocket fd=33, family=10, type=2, proto=0, laddr=('::', 53125, 0, 0)>
2026-01-18 10:05:38.196 ERROR (MainThread) [async_upnp_client.ssdp] Received error: [Errno 99] Address not available, transport: <_SelectorDatagramTransport fd=33 read=polling write=<idle, bufsize=0>>, socket: <asyncio.TransportSocket fd=33, family=10, type=2, proto=0, laddr=('::', 53125, 0, 0)>
2026-01-18 10:40:13.156 ERROR (MainThread) [pysmartthings] Connection error occurred while subscribing to events
Traceback (most recent call last):
File "/usr/local/lib/python3.13/site-packages/pysmartthings/smartthings.py", line 592, in subscribe
await self._internal_subscribe(session, subscription_url)
File "/usr/local/lib/python3.13/site-packages/pysmartthings/smartthings.py", line 504, in _internal_subscribe
async for event in event_source:
...<49 lines>...
break
File "/usr/local/lib/python3.13/site-packages/aiohttp_sse_client2/client.py", line 157, in __anext__
async for line_in_bytes in self._response.content:
...<21 lines>...
self._process_field(line, '')
File "/usr/local/lib/python3.13/site-packages/aiohttp/streams.py", line 52, in __anext__
rv = await self.read_func()
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/aiohttp/streams.py", line 360, in readline
return await self.readuntil()
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/aiohttp/streams.py", line 394, in readuntil
await self._wait("readuntil")
File "/usr/local/lib/python3.13/site-packages/aiohttp/streams.py", line 355, in _wait
await waiter
aiohttp.client_exceptions.SocketTimeoutError: Timeout on reading data from socket
2026-01-18 10:58:00.467 ERROR (MainThread) [pysmartthings] Connection error occurred while subscribing to events
Traceback (most recent call last):
File "/usr/local/lib/python3.13/site-packages/pysmartthings/smartthings.py", line 592, in subscribe
await self._internal_subscribe(session, subscription_url)
File "/usr/local/lib/python3.13/site-packages/pysmartthings/smartthings.py", line 504, in _internal_subscribe
async for event in event_source:
...<49 lines>...
break
File "/usr/local/lib/python3.13/site-packages/aiohttp_sse_client2/client.py", line 157, in __anext__
async for line_in_bytes in self._response.content:
...<21 lines>...
self._process_field(line, '')
File "/usr/local/lib/python3.13/site-packages/aiohttp/streams.py", line 52, in __anext__
rv = await self.read_func()
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/aiohttp/streams.py", line 360, in readline
return await self.readuntil()
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/aiohttp/streams.py", line 394, in readuntil
await self._wait("readuntil")
File "/usr/local/lib/python3.13/site-packages/aiohttp/streams.py", line 355, in _wait
await waiter
aiohttp.client_exceptions.SocketTimeoutError: Timeout on reading data from socket
2026-01-18 10:59:53.718 ERROR (MainThread) [async_upnp_client.ssdp] Received error: [Errno 99] Address not available, transport: <_SelectorDatagramTransport fd=33 read=polling write=<idle, bufsize=0>>, socket: <asyncio.TransportSocket fd=33, family=10, type=2, proto=0, laddr=('::', 53125, 0, 0)>
2026-01-18 11:09:53.718 ERROR (MainThread) [async_upnp_client.ssdp] Received error: [Errno 99] Address not available, transport: <_SelectorDatagramTransport fd=33 read=polling write=<idle, bufsize=0>>, socket: <asyncio.TransportSocket fd=33, family=10, type=2, proto=0, laddr=('::', 53125, 0, 0)>
2026-01-18 11:10:30.138 WARNING (MainThread) [homeassistant.components.mqtt.client] Error returned from MQTT server: The connection was lost.
2026-01-18 11:10:30.691 ERROR (MainThread) [custom_components.frigate] Unexpected error fetching frigate data
Traceback (most recent call last):
File "/usr/local/lib/python3.13/site-packages/homeassistant/helpers/update_coordinator.py", line 419, in _async_refresh
self.data = await self._async_update_data()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/frigate/__init__.py", line 485, in _async_update_data
stats = await self._api.async_get_stats()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/frigate/api.py", line 67, in async_get_stats
await self.api_wrapper("get", str(URL(self._host) / "api/stats")),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/frigate/api.py", line 421, in api_wrapper
response = await func(
^^^^^^^^^^^
...<5 lines>...
)
^
File "/usr/local/lib/python3.13/site-packages/aiohttp/client.py", line 529, in _request
raise RuntimeError("Session is closed")
RuntimeError: Session is closed

View file

View file

View file

@ -0,0 +1,4 @@
# Use this file to store secrets like usernames and passwords.
# Learn more at https://www.home-assistant.io/docs/configuration/secrets/
some_password: welcome

View file

@ -0,0 +1,3 @@
#!/bin/sh
cd /config/custom_components/kwikset-ha || exit 1
git pull || echo "kwikset-ha update failed"

10
lxc2/homeassistant/matter.yml Executable file
View file

@ -0,0 +1,10 @@
services:
matter-server:
image: ghcr.io/home-assistant-libs/python-matter-server:stable
container_name: matter-server
restart: unless-stopped
network_mode: host
volumes:
- /docker/homeassistant/matter:/data
environment:
- MATTER_SERVER_PORT=5580

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,31 @@
{
"sdk-config": {
"g/lkgt": "FSYAgKi8LBg=",
"g/gcc": "NXmcCw==",
"g/gdc": "qEIsBw==",
"ExampleOpCredsCAKey1": "BCD/kzm3BJx5Gl6W2yy0cu20DVcv/qXF1ca+9d7BtW3BL9auDHfiwiYRLEN1sNf2FPwUwz340iVevn8rCPaEXdKVQyE31fcKrtDuWaS4XPZKQa/26EKAqU3/0wc/98cPyw==",
"ExampleOpCredsICAKey1": "BAMqn6opVT44+28JgMRrAI4/mKQ9LMQeECJWaQJdpmmbhbM58lzie9bBZKFxwW1ji2YEpv9WkXkq/Nz+8Y55a/WBMKI/9sLAhB7csiiMAh22L+IqiLcnWGPVtqv8vIMk2Q==",
"ExampleCARootCert1": "MIIBlzCCATygAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYKKwYBBAGConwBBAwQMDAwMDAwMDAwMDAwMDAwMTAeFw0yMTAxMDEwMDAwMDBaFw0zMDEyMzAwMDAwMDBaMCIxIDAeBgorBgEEAYKifAEEDBAwMDAwMDAwMDAwMDAwMDAxMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIP+TObcEnHkaXpbbLLRy7bQNVy/+pcXVxr713sG1bcEv1q4Md+LCJhEsQ3Ww1/YU/BTDPfjSJV6+fysI9oRd0qNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNV0IhBmGyz+hNDLGAsS/tkZygKtMB8GA1UdIwQYMBaAFNV0IhBmGyz+hNDLGAsS/tkZygKtMAoGCCqGSM49BAMCA0kAMEYCIQDYY2jZzjxPWzasPuntZvGvNJF+oVuz5NM664NiNhzt3QIhAIpN+4x6HXnys0rppzfPbFlGx++Xvu/2V7v2S4QU48Ve",
"ExampleCAIntermediateCert1": "MIIBlzCCATygAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYKKwYBBAGConwBBAwQMDAwMDAwMDAwMDAwMDAwMTAeFw0yMTAxMDEwMDAwMDBaFw0zMDEyMzAwMDAwMDBaMCIxIDAeBgorBgEEAYKifAEDDBAwMDAwMDAwMDAwMDAwMDAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAyqfqilVPjj7bwmAxGsAjj+YpD0sxB4QIlZpAl2maZuFsznyXOJ71sFkoXHBbWOLZgSm/1aReSr83P7xjnlr9aNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFCz7LweU4FqoAXOD5urp44+cEizyMB8GA1UdIwQYMBaAFNV0IhBmGyz+hNDLGAsS/tkZygKtMAoGCCqGSM49BAMCA0kAMEYCIQCEzHZH5tzYAU73EntqjwyJztblu4rqziq38IYSVIZeAQIhAPr7wmyeFTTvMKebqPr1tq/6LhYakHxD7rsxrj3swpGR",
"f/1/m": "FSUA8f8sAQAY",
"f/1/n": "FTABAQEkAgE3AyQTAhgmBIAigScmBYAlTTo3BiQVASYRabYBABgkBwEkCAEwCUEECiSLIuJzC8Z91oIjoAfj4q7V4Iepgm022xjOvHs0D9cd2jP1B3odCOjtZRPFSuRukFZF7snIUbkugs5sJrzEYjcKNQEoARgkAgE2AwQCBAEYMAQU72mSIRQ9qsMwVCiNZRqh4zK6284wBRQs+y8HlOBaqAFzg+bq6eOPnBIs8hgwC0D68nGYO8CT1GuJ77ScpZ+Bqk79c9E6M6w1wwA0wobdMotamqAWPXB4U39f4hNid6y9fAg/UEI3ml2wsalJ8trgGA==",
"f/1/i": "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQTAhgkBwEkCAEwCUEEAyqfqilVPjj7bwmAxGsAjj+YpD0sxB4QIlZpAl2maZuFsznyXOJ71sFkoXHBbWOLZgSm/1aReSr83P7xjnlr9TcKNQEpARgkAmAwBBQs+y8HlOBaqAFzg+bq6eOPnBIs8jAFFNV0IhBmGyz+hNDLGAsS/tkZygKtGDALQITMdkfm3NgBTvcSe2qPDInO1uW7iurOKrfwhhJUhl4B+vvCbJ4VNO8wp5uo+vW2r/ouFhqQfEPuuzGuPezCkZEY",
"f/1/r": "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQUARgkBwEkCAEwCUEEIP+TObcEnHkaXpbbLLRy7bQNVy/+pcXVxr713sG1bcEv1q4Md+LCJhEsQ3Ww1/YU/BTDPfjSJV6+fysI9oRd0jcKNQEpARgkAmAwBBTVdCIQZhss/oTQyxgLEv7ZGcoCrTAFFNV0IhBmGyz+hNDLGAsS/tkZygKtGDALQNhjaNnOPE9bNqw+6e1m8a80kX6hW7Pk0zrrg2I2HO3dik37jHodefKzSumnN89sWUbH75e+7/ZXu/ZLhBTjxV4Y",
"g/fidx": "FSQAAjYBBAEYGA==",
"f/1/k/0": "FSQBACQCATYDFSQEACUF710wBhBIIa++wisn2Dab58xHSgWLGBUkBAAkBQAwBhAAAAAAAAAAAAAAAAAAAAAAGBUkBAAkBQAwBhAAAAAAAAAAAAAAAAAAAAAAGBglB///GA==",
"g/gfl": "FSQBASQCARg=",
"f/1/g": "FSQBACQCACQDACQEACQFACQGASQHABg=",
"g/icdfl": "FgQBGA==",
"g/sri": "Fhg="
},
"repl-config": {
"caList": {
"1": [
{
"fabricId": 1,
"vendorId": 65521
}
]
}
}
}

View file

@ -0,0 +1,5 @@
[DEFAULT]
configuration-version=1
location-capability=2
regulatory-location=0

View file

@ -0,0 +1,5 @@
[DEFAULT]
boot-reason=0
reboot-count=29
total-operational-hours=1888

View file

@ -0,0 +1,5 @@
[DEFAULT]
product-id=32769
unique-id=D03238922E0A0367
vendor-id=65521

View file

@ -0,0 +1 @@
1

Some files were not shown because too many files have changed in this diff Show more