From 414cbded952e2a52b1b0b528e880614b86de72aa Mon Sep 17 00:00:00 2001 From: wserr Date: Sun, 6 Oct 2024 13:12:09 +0200 Subject: [PATCH 01/13] initial --- configurations/otel/collector-config.yaml | 19 +++++ configurations/traefik/traefik.1.7.10.toml | 99 +++++++++++++--------- home-server/.env | 21 +---- home-server/docker-compose.yml | 75 +++++++++------- home-server/envs/local.env | 16 ++++ home-server/envs/production.env | 18 ++++ home-server/{ => envs}/readme.md | 9 ++ home-server/install-docker.sh | 27 ++++++ 8 files changed, 196 insertions(+), 88 deletions(-) create mode 100644 configurations/otel/collector-config.yaml create mode 100644 home-server/envs/local.env create mode 100644 home-server/envs/production.env rename home-server/{ => envs}/readme.md (66%) create mode 100755 home-server/install-docker.sh diff --git a/configurations/otel/collector-config.yaml b/configurations/otel/collector-config.yaml new file mode 100644 index 0000000..3060b1a --- /dev/null +++ b/configurations/otel/collector-config.yaml @@ -0,0 +1,19 @@ +receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 + +exporters: + debug: + verbosity: detailed + +service: + extensions: [] + pipelines: + traces: + receivers: [otlp] + processors: [] + exporters: [debug] diff --git a/configurations/traefik/traefik.1.7.10.toml b/configurations/traefik/traefik.1.7.10.toml index fb9f202..efe886b 100644 --- a/configurations/traefik/traefik.1.7.10.toml +++ b/configurations/traefik/traefik.1.7.10.toml @@ -1,55 +1,74 @@ -defaultEntryPoints = ["http"] - [entryPoints] - [entryPoints.whoami] - address = ":8088" - [entryPoints.homeassistant] - address = ":8089" - [entryPoints.syncthing] - address = ":8090" - [entryPoints.grafana] - address = ":8091" - [entryPoints.influxdb] - address = ":8092" + [entryPoints.http] + address = ":80" + + [entryPoints.https] + address = ":443" + [entryPoints.https.tls] + [[entryPoints.https.tls.certificates]] + certFile = "/var/lib/certificates/cert.pem" + keyFile = "/var/lib/certificates/key.pem" [file] - [backends] [backends.whoami] [backends.whoami.servers.server1] - url = "http://localhost:2001" - [backends.homeassistant] - [backends.homeassistant.servers.server1] - url = "http://10.55.8.3:8123/" - [backends.syncthing] - [backends.syncthing.servers.server1] - url = "http://10.55.8.3:8384/" + url = "http://whoami:2001" + [backends.grafana] [backends.grafana.servers.server1] - url = "http://10.55.8.3:3000/" + url = "http://grafana:3000" + + [backends.syncthing] + [backends.syncthing.servers.server1] + url = "http://syncthing:8384" + + [backends.homeassistant] + [backends.homeassistant.servers.server1] + url = "http://homeassistant:8123" + [backends.influxdb] [backends.influxdb.servers.server1] - url = "http://10.55.8.3:8086/" + url = "http://influxdb:8086" [frontends] - [frontends.whoami] - entryPoints = ["whoami"] - backend = "whoami" + [frontends.whoami] + backend = "whoami" + [frontends.whoami.routes.path] + rule = "Path:/whoami;ReplacePathRegex: ^/whoami(.*) /$1" - [frontends.homeassistant] - entryPoints = ["homeassistant"] - backend = "homeassistant" + [frontends.grafana] + backend = "grafana" + [frontends.grafana.routes.path] + rule = "Path:/grafana;ReplacePathRegex: ^/grafana(.*) /$1" - [frontends.syncthing] - entryPoints = ["syncthing"] - backend = "syncthing" + [frontends.syncthing] + backend = "syncthing" + [frontends.syncthing.routes.path] + rule = "Path:/syncthing;ReplacePathRegex: ^/syncthing(.*) /$1" - [frontends.grafana] - entryPoints = ["grafana"] - backend = "grafana" - passHostHeader = true - - [frontends.influxdb] - entryPoints = ["influxdb"] - backend = "influxdb" - passHostHeader = true + [frontends.syncthing-referrer] + backend = "syncthing" + [frontends.syncthing-referrer.routes.referrer] + rule = "HeadersRegexp: Referer, /*.syncthing" + + [frontends.homeassistant] + backend = "homeassistant" + [frontends.homeassistant.routes.path] + rule = "Path:/homeassistant;ReplacePathRegex: ^/homeassistant(.*) /$1" + + [frontends.influxdb] + backend = "influxdb" + [frontends.influxdb.routes.path] + rule = "Path:/influxdb;ReplacePathRegex: ^/influxdb(.*) /$1" + + [frontends.influxdb-referrer] + backend = "influxdb" + [frontends.influxdb-referrer.routes.referrer] + rule = "HeadersRegexp: Referer, /*.influxdb" + + +[tracing] + [tracing.otlp.http] + endpoint = "http://otel-collector:4318" + insecure = true diff --git a/home-server/.env b/home-server/.env index 1ee58ec..618eb1a 100644 --- a/home-server/.env +++ b/home-server/.env @@ -1,19 +1,4 @@ -# General settings -INTERNAL_IP: 0.0.0.0 +REPO_DIR=/home/pi/repos/homeAutomation -# Maria DB settings -# For testing purposes only. Please create a .env.mariadb to overwrite these variables -MARIADB_ROOT_PASSWORD=testing - -MARIADB_DATABASE=homeassistant -MARIADB_USER=homeassistant_user -MARIADB_PASSWORD=homeassistant_pw - -GF_SECURITY_ADMIN_USER=test -GF_SECURITY_ADMIN_PASSWORD=test -GF_USERS_ALLOW_SIGN_UP=false - -DOCKER_INFLUXDB_INIT_USERNAME=homeassistant -DOCKER_INFLUXDB_INIT_PASSWORD=homeassistant -DOCKER_INFLUXDB_INIT_ORG=homeassistant -DOCKER_INFLUXDB_INIT_BUCKET=homeassistant +# Make sure docker user has read/write access on this folder +STORAGE_DIR=/tmp diff --git a/home-server/docker-compose.yml b/home-server/docker-compose.yml index d979682..cce7026 100644 --- a/home-server/docker-compose.yml +++ b/home-server/docker-compose.yml @@ -1,26 +1,36 @@ -version: "3.9" services: + whoami: + restart: unless-stopped + image: traefik/whoami + command: + - --port=2001 + traefik: + restart: unless-stopped + image: "traefik:1.7.10" + volumes: + - ${REPO_DIR}/configurations/traefik/traefik.1.7.10.toml:/etc/traefik/traefik.toml + - ${STORAGE_DIR}/certificates:/var/lib/certificates + ports: + - 80:80 + - 443:443 db: image: mariadb:latest restart: unless-stopped ports: - - ${INTERNAL_IP}:3306:3306 + - 3306:3306 env_file: - - .env - - .env.production + - envs/local.env + - envs/production.env volumes: - - /home/willem/mariadb:/var/lib/mysql + - ${STORAGE_DIR}/mariadb:/var/lib/mysql homeassistant: image: "ghcr.io/home-assistant/home-assistant:stable" - ports: - - ${INTERNAL_IP}:8123:8123 volumes: - - /home/willem/homeassistant:/config - - /home/willem/repos/homeAutomation/configurations/home-assistant/configuration.production.yaml:/config/configuration.yaml + - ${STORAGE_DIR}/homeassistant:/config restart: unless-stopped env_file: - - .env - - .env.production + - envs/local.env + - envs/production.env syncthing: image: lscr.io/linuxserver/syncthing:latest container_name: syncthing @@ -29,12 +39,11 @@ services: - PGID=1000 - TZ=Europe/London volumes: - - /home/willem/syncthing:/data1 + - ${STORAGE_DIR}/syncthing:/data1 ports: - - ${INTERNAL_IP}:8384:8384 - - ${INTERNAL_IP}:22000:22000/tcp - - ${INTERNAL_IP}:22000:22000/udp - - ${INTERNAL_IP}:21027:21027/udp + - 22000:22000/tcp + - 22000:22000/udp + - 21027:21027/udp restart: unless-stopped node-exporter: image: prom/node-exporter:latest @@ -50,14 +59,14 @@ services: - '--path.sysfs=/host/sys' - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)' ports: - - ${INTERNAL_IP}:9100:9100 + - 9100:9100 prometheus: image: prom/prometheus:latest container_name: prometheus restart: unless-stopped volumes: - - /home/willem/repos/homeAutomation/configurations/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml - - /home/willem/prometheus:/prometheus + - ${REPO_DIR}/configurations/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml + - ${STORAGE_DIR}/prometheus:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' @@ -65,31 +74,37 @@ services: - '--web.console.templates=/etc/prometheus/consoles' - '--web.enable-lifecycle' ports: - - ${INTERNAL_IP}:9090:9090 + - 9090:9090 grafana: image: grafana/grafana:latest - ports: - - ${INTERNAL_IP}:3000:3000 volumes: - - /home/willem/grafana:/var/lib/grafana + - ${STORAGE_DIR}/grafana:/var/lib/grafana env_file: - - .env - - .env.production + - envs/local.env + - envs/production.env influxdb: container_name: influxdb image: influxdb restart: unless-stopped - ports: - - ${INTERNAL_IP}:8086:8086/tcp # So we can access the WebUI environment: - TZ=Europe/Brussels - DOCKER_INFLUXDB_INIT_MODE=setup env_file: - - .env.production + - envs/local.env + - envs/production.env volumes: - - /home/willem/influxdb/data:/var/lib/influxdb2 - - /home/willem/influxdb/config/:/etc/influxdb2 + - ${STORAGE_DIR}/influxdb/data:/var/lib/influxdb2 + - ${STORAGE_DIR}/influxdb/config/:/etc/influxdb2 ulimits: nofile: soft: 32768 hard: 32768 + otel-collector: + container_name: otel-collector + image: otel/opentelemetry-collector-contrib:0.111.0 + restart: unless-stopped + volumes: + - ${REPO_DIR}/configurations/otel/collector-config.yaml:/etc/otelcol-contrib/config.yaml +# Only enable if external services present +# ports: +# - 4317:4317 # OTLP gRPC receiver diff --git a/home-server/envs/local.env b/home-server/envs/local.env new file mode 100644 index 0000000..bb93fe1 --- /dev/null +++ b/home-server/envs/local.env @@ -0,0 +1,16 @@ +# Maria DB settings +# For testing purposes only. Please create a .env.mariadb to overwrite these variables +MARIADB_ROOT_PASSWORD=testing + +MARIADB_DATABASE=homeassistant +MARIADB_USER=homeassistant_user +MARIADB_PASSWORD=homeassistant_pw + +GF_SECURITY_ADMIN_USER=test +GF_SECURITY_ADMIN_PASSWORD=test +GF_USERS_ALLOW_SIGN_UP=false + +DOCKER_INFLUXDB_INIT_USERNAME=homeassistant +DOCKER_INFLUXDB_INIT_PASSWORD=homeassistant +DOCKER_INFLUXDB_INIT_ORG=homeassistant +DOCKER_INFLUXDB_INIT_BUCKET=homeassistant diff --git a/home-server/envs/production.env b/home-server/envs/production.env new file mode 100644 index 0000000..932c21c --- /dev/null +++ b/home-server/envs/production.env @@ -0,0 +1,18 @@ +# Maria DB settings +# For testing purposes only. Please create a .env.mariadb to overwrite these variables +MARIADB_ROOT_PASSWORD=c8gcablGDuJH2tnbAXjPiQ== + +MARIADB_DATABASE=homeassistant +MARIADB_USER=homeassistant_user +MARIADB_PASSWORD=gyxxny8gO6bzczw+ULuALA== + +GF_SECURITY_ADMIN_USER=admin +GF_SECURITY_ADMIN_PASSWORD=QCpuH3Fnet7g9ywlRQ1Gtw== +GF_USERS_ALLOW_SIGN_UP=false + +DOCKER_INFLUXDB_INIT_USERNAME=homeassistant +DOCKER_INFLUXDB_INIT_PASSWORD=IEOUjgdbI3XjJnmqQOPkHw== +DOCKER_INFLUXDB_INIT_ORG=homeassistant +DOCKER_INFLUXDB_INIT_BUCKET=homeassistant + +REPO_DIR=/home/pi/repos/homeAutomation diff --git a/home-server/readme.md b/home-server/envs/readme.md similarity index 66% rename from home-server/readme.md rename to home-server/envs/readme.md index 66d284c..d46ff96 100644 --- a/home-server/readme.md +++ b/home-server/envs/readme.md @@ -35,3 +35,12 @@ docker compose rm db - Start the VPN client automatically after reboot +## Generate self signed certificates + +https://stackoverflow.com/questions/10175812/how-to-generate-a-self-signed-ssl-certificate-using-openssl + +> non-interactive and 10 years expiration + +```bash +openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 3650 -nodes -subj "/C=homeassistant/ST=Belgium/L=Deerlijk/O=Willem/OU=Willem/CN=willem" -subj '/CN=homeassistant.com' +``` diff --git a/home-server/install-docker.sh b/home-server/install-docker.sh new file mode 100755 index 0000000..509ae58 --- /dev/null +++ b/home-server/install-docker.sh @@ -0,0 +1,27 @@ +#!/usr/bin/sh + +# See https://docs.docker.com/engine/install/debian/ +# + # Add Docker's official GPG key: +sudo apt-get update +sudo apt-get install ca-certificates curl +sudo install -m 0755 -d /etc/apt/keyrings +sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc +sudo chmod a+r /etc/apt/keyrings/docker.asc + +# Add the repository to Apt sources: +echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ + $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ + sudo tee /etc/apt/sources.list.d/docker.list > /dev/null +sudo apt-get update + +sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + +sudo groupadd docker +sudo usermod -aG docker $USER + +newgrp docker + +# Verify: +# docker run hello-world From fc0db54fb766872185f08b4a1dac998de5aad8d2 Mon Sep 17 00:00:00 2001 From: wserr Date: Sun, 6 Oct 2024 17:26:49 +0200 Subject: [PATCH 02/13] Update configuration --- .../configuration-production.yaml | 13 ++++ configurations/otel/collector-config.yaml | 11 ++- configurations/prometheus/prometheus.yml | 7 +- configurations/traefik/traefik.1.7.10.toml | 74 ------------------- configurations/traefik/traefik.yml | 25 +++++++ home-server/docker-compose.yml | 45 ++++++++--- home-server/envs/production.env | 2 - 7 files changed, 87 insertions(+), 90 deletions(-) create mode 100644 configurations/home-assistant/configuration-production.yaml delete mode 100644 configurations/traefik/traefik.1.7.10.toml create mode 100644 configurations/traefik/traefik.yml diff --git a/configurations/home-assistant/configuration-production.yaml b/configurations/home-assistant/configuration-production.yaml new file mode 100644 index 0000000..b6919eb --- /dev/null +++ b/configurations/home-assistant/configuration-production.yaml @@ -0,0 +1,13 @@ +# Loads default set of integrations. Do not remove +# This was added to the homeAutomation repo. +# This is a sample configuration. Please create a configuration.production.yml for production use. +default_config: + +automation: !include automations.yaml +script: !include scripts.yaml +scene: !include scenes.yaml + +http: + use_x_forwarded_for: true + trusted_proxies: + - 172.18.0.0/24 diff --git a/configurations/otel/collector-config.yaml b/configurations/otel/collector-config.yaml index 3060b1a..907f3ea 100644 --- a/configurations/otel/collector-config.yaml +++ b/configurations/otel/collector-config.yaml @@ -6,7 +6,12 @@ receivers: http: endpoint: 0.0.0.0:4318 +processors: + batch: + exporters: + prometheus: + endpoint: 0.0.0.0:8889 debug: verbosity: detailed @@ -15,5 +20,9 @@ service: pipelines: traces: receivers: [otlp] - processors: [] + processors: [batch] exporters: [debug] + metrics: + receivers: [otlp] + processors: [batch] + exporters: [prometheus,debug] diff --git a/configurations/prometheus/prometheus.yml b/configurations/prometheus/prometheus.yml index 4be0808..e644fcf 100644 --- a/configurations/prometheus/prometheus.yml +++ b/configurations/prometheus/prometheus.yml @@ -8,8 +8,11 @@ scrape_configs: - targets: ["prometheus:9090"] - job_name: "node" + scrape_interval: 1m static_configs: - targets: ["node-exporter:9100"] - - job_name: "pi_node" + + - job_name: "otel" + scrape_interval: 5s static_configs: - - targets: ["10.55.8.1:9100"] + - targets: ["otel-collector:8889"] diff --git a/configurations/traefik/traefik.1.7.10.toml b/configurations/traefik/traefik.1.7.10.toml deleted file mode 100644 index efe886b..0000000 --- a/configurations/traefik/traefik.1.7.10.toml +++ /dev/null @@ -1,74 +0,0 @@ -[entryPoints] - [entryPoints.http] - address = ":80" - - [entryPoints.https] - address = ":443" - [entryPoints.https.tls] - [[entryPoints.https.tls.certificates]] - certFile = "/var/lib/certificates/cert.pem" - keyFile = "/var/lib/certificates/key.pem" - -[file] -[backends] - [backends.whoami] - [backends.whoami.servers.server1] - url = "http://whoami:2001" - - [backends.grafana] - [backends.grafana.servers.server1] - url = "http://grafana:3000" - - [backends.syncthing] - [backends.syncthing.servers.server1] - url = "http://syncthing:8384" - - [backends.homeassistant] - [backends.homeassistant.servers.server1] - url = "http://homeassistant:8123" - - [backends.influxdb] - [backends.influxdb.servers.server1] - url = "http://influxdb:8086" - -[frontends] - [frontends.whoami] - backend = "whoami" - [frontends.whoami.routes.path] - rule = "Path:/whoami;ReplacePathRegex: ^/whoami(.*) /$1" - - [frontends.grafana] - backend = "grafana" - [frontends.grafana.routes.path] - rule = "Path:/grafana;ReplacePathRegex: ^/grafana(.*) /$1" - - [frontends.syncthing] - backend = "syncthing" - [frontends.syncthing.routes.path] - rule = "Path:/syncthing;ReplacePathRegex: ^/syncthing(.*) /$1" - - [frontends.syncthing-referrer] - backend = "syncthing" - [frontends.syncthing-referrer.routes.referrer] - rule = "HeadersRegexp: Referer, /*.syncthing" - - [frontends.homeassistant] - backend = "homeassistant" - [frontends.homeassistant.routes.path] - rule = "Path:/homeassistant;ReplacePathRegex: ^/homeassistant(.*) /$1" - - [frontends.influxdb] - backend = "influxdb" - [frontends.influxdb.routes.path] - rule = "Path:/influxdb;ReplacePathRegex: ^/influxdb(.*) /$1" - - [frontends.influxdb-referrer] - backend = "influxdb" - [frontends.influxdb-referrer.routes.referrer] - rule = "HeadersRegexp: Referer, /*.influxdb" - - -[tracing] - [tracing.otlp.http] - endpoint = "http://otel-collector:4318" - insecure = true diff --git a/configurations/traefik/traefik.yml b/configurations/traefik/traefik.yml new file mode 100644 index 0000000..3ad12e2 --- /dev/null +++ b/configurations/traefik/traefik.yml @@ -0,0 +1,25 @@ +## traefik.yml + +# Docker configuration backend +providers: + docker: + defaultRule: "Host(`{{ trimPrefix `/` .Name }}.docker.localhost`)" + +# API and dashboard configuration +api: + insecure: true + +tracing: + capturedRequestHeaders: + - X-Forwarded-Prefix + otlp: + grpc: + endpoint: otel-collector:4317 + insecure: true + +metrics: + otlp: + addEntryPointsLabels: true + grpc: + endpoint: otel-collector:4317 + insecure: true diff --git a/home-server/docker-compose.yml b/home-server/docker-compose.yml index cce7026..060c5f4 100644 --- a/home-server/docker-compose.yml +++ b/home-server/docker-compose.yml @@ -1,18 +1,25 @@ services: - whoami: - restart: unless-stopped - image: traefik/whoami - command: - - --port=2001 traefik: restart: unless-stopped - image: "traefik:1.7.10" + image: traefik:v3.2 + labels: + - traefik.http.routers.dashboard.rule=Host(`traefik.pladijs`) + - traefik.http.services.dashboard.loadbalancer.server.port=8080 volumes: - - ${REPO_DIR}/configurations/traefik/traefik.1.7.10.toml:/etc/traefik/traefik.toml + - ${REPO_DIR}/configurations/traefik/traefik.yml:/etc/traefik/traefik.yml - ${STORAGE_DIR}/certificates:/var/lib/certificates + - /var/run/docker.sock:/var/run/docker.sock ports: - 80:80 - 443:443 + whoami: + restart: unless-stopped + image: traefik/whoami + labels: + - traefik.http.routers.whoami.rule=Host(`whoami.pladijs`) + - traefik.http.services.whoami.loadbalancer.server.port=2001 + command: + - --port=2001 db: image: mariadb:latest restart: unless-stopped @@ -25,8 +32,13 @@ services: - ${STORAGE_DIR}/mariadb:/var/lib/mysql homeassistant: image: "ghcr.io/home-assistant/home-assistant:stable" + labels: + - traefik.http.routers.homeassistant.rule=Host(`homeassistant.pladijs`) + - traefik.http.services.homeassistant.loadbalancer.server.port=8123 volumes: - ${STORAGE_DIR}/homeassistant:/config + - ${STORAGE_DIR}/homeassistant:/config + - ${REPO_DIR}/configurations/home-assistant/configuration-production.yaml:/config/configuration.yaml restart: unless-stopped env_file: - envs/local.env @@ -34,6 +46,9 @@ services: syncthing: image: lscr.io/linuxserver/syncthing:latest container_name: syncthing + labels: + - traefik.http.routers.syncthing.rule=Host(`syncthing.pladijs`) + - traefik.http.services.syncthing.loadbalancer.server.port=8384 environment: - PUID=1000 - PGID=1000 @@ -58,12 +73,16 @@ services: - '--path.rootfs=/rootfs' - '--path.sysfs=/host/sys' - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)' - ports: - - 9100:9100 + labels: + - traefik.http.routers.node-exporter.rule=Host(`node-exporter.pladijs`) + - traefik.http.services.node-exporter.loadbalancer.server.port=9100 prometheus: image: prom/prometheus:latest container_name: prometheus restart: unless-stopped + labels: + - traefik.http.routers.prometheus.rule=Host(`prometheus.pladijs`) + - traefik.http.services.prometheus.loadbalancer.server.port=9090 volumes: - ${REPO_DIR}/configurations/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml - ${STORAGE_DIR}/prometheus:/prometheus @@ -73,8 +92,6 @@ services: - '--web.console.libraries=/etc/prometheus/console_libraries' - '--web.console.templates=/etc/prometheus/consoles' - '--web.enable-lifecycle' - ports: - - 9090:9090 grafana: image: grafana/grafana:latest volumes: @@ -82,8 +99,14 @@ services: env_file: - envs/local.env - envs/production.env + labels: + - traefik.http.routers.grafana.rule=Host(`grafana.pladijs`) + - traefik.http.services.grafana.loadbalancer.server.port=3000 influxdb: container_name: influxdb + labels: + - traefik.http.routers.influxdb.rule=Host(`influxdb.pladijs`) + - traefik.http.services.influxdb.loadbalancer.server.port=3000 image: influxdb restart: unless-stopped environment: diff --git a/home-server/envs/production.env b/home-server/envs/production.env index 932c21c..b8cc543 100644 --- a/home-server/envs/production.env +++ b/home-server/envs/production.env @@ -14,5 +14,3 @@ DOCKER_INFLUXDB_INIT_USERNAME=homeassistant DOCKER_INFLUXDB_INIT_PASSWORD=IEOUjgdbI3XjJnmqQOPkHw== DOCKER_INFLUXDB_INIT_ORG=homeassistant DOCKER_INFLUXDB_INIT_BUCKET=homeassistant - -REPO_DIR=/home/pi/repos/homeAutomation From 8c71cc514d30534284541ff0899d11706a9f9192 Mon Sep 17 00:00:00 2001 From: wserr Date: Thu, 26 Dec 2024 08:13:20 +0100 Subject: [PATCH 03/13] Updated setup --- .gitignore | 2 +- configurations/otel/collector-config.yaml | 10 +++++----- home-server/docker-compose.yml | 3 +-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index c2e0ab4..097f5c9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ .env.production # Home assistant configuration file -configuration.production.yaml +configuration-production.yaml .env run-docker.sh diff --git a/configurations/otel/collector-config.yaml b/configurations/otel/collector-config.yaml index 907f3ea..84b9e78 100644 --- a/configurations/otel/collector-config.yaml +++ b/configurations/otel/collector-config.yaml @@ -18,11 +18,11 @@ exporters: service: extensions: [] pipelines: - traces: - receivers: [otlp] - processors: [batch] - exporters: [debug] + #traces: + #receivers: [otlp] + #processors: [batch] + #exporters: [debug] metrics: receivers: [otlp] processors: [batch] - exporters: [prometheus,debug] + exporters: [prometheus] diff --git a/home-server/docker-compose.yml b/home-server/docker-compose.yml index 060c5f4..3e495c3 100644 --- a/home-server/docker-compose.yml +++ b/home-server/docker-compose.yml @@ -36,7 +36,6 @@ services: - traefik.http.routers.homeassistant.rule=Host(`homeassistant.pladijs`) - traefik.http.services.homeassistant.loadbalancer.server.port=8123 volumes: - - ${STORAGE_DIR}/homeassistant:/config - ${STORAGE_DIR}/homeassistant:/config - ${REPO_DIR}/configurations/home-assistant/configuration-production.yaml:/config/configuration.yaml restart: unless-stopped @@ -106,7 +105,7 @@ services: container_name: influxdb labels: - traefik.http.routers.influxdb.rule=Host(`influxdb.pladijs`) - - traefik.http.services.influxdb.loadbalancer.server.port=3000 + - traefik.http.services.influxdb.loadbalancer.server.port=8086 image: influxdb restart: unless-stopped environment: From 6d372c011b36dc74f8533c2969fe9970f37d543b Mon Sep 17 00:00:00 2001 From: wserr Date: Thu, 26 Dec 2024 08:13:51 +0100 Subject: [PATCH 04/13] Updated gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 097f5c9..93acee0 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ .env.production # Home assistant configuration file -configuration-production.yaml +**configuration-production.yaml .env run-docker.sh From 7df598837d058b35faa174bffde828ee51064db2 Mon Sep 17 00:00:00 2001 From: wserr Date: Thu, 26 Dec 2024 08:14:19 +0100 Subject: [PATCH 05/13] Updated gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 93acee0..097f5c9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ .env.production # Home assistant configuration file -**configuration-production.yaml +configuration-production.yaml .env run-docker.sh From ecc41af930cf4a575253cd7b0fef70917fed2822 Mon Sep 17 00:00:00 2001 From: wserr Date: Thu, 26 Dec 2024 08:15:08 +0100 Subject: [PATCH 06/13] Removed production config --- .../home-assistant/configuration-production.yaml | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 configurations/home-assistant/configuration-production.yaml diff --git a/configurations/home-assistant/configuration-production.yaml b/configurations/home-assistant/configuration-production.yaml deleted file mode 100644 index b6919eb..0000000 --- a/configurations/home-assistant/configuration-production.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# Loads default set of integrations. Do not remove -# This was added to the homeAutomation repo. -# This is a sample configuration. Please create a configuration.production.yml for production use. -default_config: - -automation: !include automations.yaml -script: !include scripts.yaml -scene: !include scenes.yaml - -http: - use_x_forwarded_for: true - trusted_proxies: - - 172.18.0.0/24 From f2050c1085f3fcd8e247e416f19b6c8634ee4997 Mon Sep 17 00:00:00 2001 From: wserr Date: Thu, 26 Dec 2024 08:17:14 +0100 Subject: [PATCH 07/13] Removed person detection --- person-detection/readme.md | 1 - person-detection/script.py | 132 ------------------------------------- person-detection/test.jpg | Bin 89899 -> 0 bytes 3 files changed, 133 deletions(-) delete mode 100644 person-detection/readme.md delete mode 100644 person-detection/script.py delete mode 100644 person-detection/test.jpg diff --git a/person-detection/readme.md b/person-detection/readme.md deleted file mode 100644 index 29bfdf6..0000000 --- a/person-detection/readme.md +++ /dev/null @@ -1 +0,0 @@ -# Person Detection Script diff --git a/person-detection/script.py b/person-detection/script.py deleted file mode 100644 index ac1acab..0000000 --- a/person-detection/script.py +++ /dev/null @@ -1,132 +0,0 @@ -import cv2 -import imutils -import numpy as np -import argparse - -HOGCV = cv2.HOGDescriptor() -HOGCV.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector()) - -def detect(frame): - bounding_box_cordinates, weights = HOGCV.detectMultiScale(frame, winStride = (4, 4), padding = (8, 8), scale = 1.03) - - person = 1 - for x,y,w,h in bounding_box_cordinates: - cv2.rectangle(frame, (x,y), (x+w,y+h), (0,255,0), 2) - cv2.putText(frame, f'person {person}', (x,y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,255), 1) - person += 1 - - cv2.putText(frame, 'Status : Detecting ', (40,40), cv2.FONT_HERSHEY_DUPLEX, 0.8, (255,0,0), 2) - cv2.putText(frame, f'Total Persons : {person-1}', (40,70), cv2.FONT_HERSHEY_DUPLEX, 0.8, (255,0,0), 2) - - if str(args["preview"]) == 'true': - cv2.imshow('output', frame) - return frame - -def humanDetector(args): - image_path = args["image"] - image_url_path = args["imageUrl"] - video_path = args['video'] - if str(args["camera"]) == 'true' : camera = True - else : camera = False - writer = None - if args['output'] is not None and image_path is None: - writer = cv2.VideoWriter(args['output'],cv2.VideoWriter_fourcc(*'MJPG'), 10, (600,600)) - if camera: - print('[INFO] Opening Web Cam.') - detectByCamera(ouput_path,writer) - elif video_path is not None: - print('[INFO] Opening Video from path.') - detectByPathVideo(video_path, writer) - elif image_path is not None: - print('[INFO] Opening Image from path.') - detectByPathImage(image_path, args['output']) - elif image_url_path is not None: - print('[INFO] Opening Image from URL path.') - detectByPathUrlImage(image_url_path, args['output']) - -def detectByCamera(writer): - video = cv2.VideoCapture(0) - print('Detecting people...') - while True: - check, frame = video.read() - frame = detect(frame) - if writer is not None: - writer.write(frame) - key = cv2.waitKey(1) - if key == ord('q'): - break - video.release() - cv2.destroyAllWindows() - -def detectByPathVideo(path, writer): - video = cv2.VideoCapture(path) - check, frame = video.read() - if check == False: - print('Video Not Found. Please Enter a Valid Path (Full path of Video Should be Provided).') - return - print('Detecting people...') - while video.isOpened(): - #check is True if reading was successful - check, frame = video.read() - if check: - frame = imutils.resize(frame , width=min(800,frame.shape[1])) - frame = detect(frame) - - if writer is not None: - writer.write(frame) - - key = cv2.waitKey(1) - if key== ord('q'): - break - else: - break - video.release() - cv2.destroyAllWindows() -def detectByCamera(writer): - video = cv2.VideoCapture(0) - print('Detecting people...') - while True: - check, frame = video.read() - frame = detect(frame) - if writer is not None: - writer.write(frame) - key = cv2.waitKey(1) - if key == ord('q'): - break - video.release() - cv2.destroyAllWindows() - -def detectByPathImage(path, output_path): - image = cv2.imread(path) - image = imutils.resize(image, width = min(800, image.shape[1])) - result_image = detect(image) - if output_path is not None: - cv2.imwrite(output_path, result_image) - cv2.waitKey(0) - cv2.destroyAllWindows() - -def detectByPathUrlImage(pathUrl, output_path): - image = imutils.url_to_image(pathUrl) - image = imutils.resize(image, width = min(800, image.shape[1])) - result_image = detect(image) - if output_path is not None: - cv2.imwrite(output_path, result_image) - cv2.waitKey(0) - cv2.destroyAllWindows() - -def argsParser(): - arg_parse = argparse.ArgumentParser() - arg_parse.add_argument("-v", "--video", default=None, help="path to Video File ") - arg_parse.add_argument("-i", "--image", default=None, help="path to Image File ") - arg_parse.add_argument("-iu", "--imageUrl", default=None, help="Url to Image File ") - arg_parse.add_argument("-c", "--camera", default=False, help="Set true if you want to use the camera.") - arg_parse.add_argument("-p", "--preview", default=True, help="Set true if you want to open preview") - arg_parse.add_argument("-o", "--output", type=str, help="path to optional output video file") - args = vars(arg_parse.parse_args()) - return args - -if __name__ == "__main__": - HOGCV = cv2.HOGDescriptor() - HOGCV.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector()) - args = argsParser() - humanDetector(args) \ No newline at end of file diff --git a/person-detection/test.jpg b/person-detection/test.jpg deleted file mode 100644 index e155dfdf587f334a2fdabf79c72537d8669f9374..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 89899 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ξJ;#4l#iKe$Q| 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

+OF0I zsShE3Y(l`F*!P`0LR{c3?l=qy2PZm+{(Xrh2EN702WT(}3?iYlYH$00srjQZ4{#hNIp0c8Nb23>7X|eM<14R`}awJUsG4-WC>i+=XAJ&Q~4no3Dk~#IKp*xgk)`}{Y#65>GK4BT{ zPbBP4dm1RJTM#-hHxr7H$r1n$Vf^T#rS1Zd4&09a0Md{7X+;%FU?o3%eJRiPsG@=% z;rm00Zk%p+3LE{b-_)&_T-N)KZh2 zWcH$pxa>-!$RIasBEjs$&|UZ#;h$N`P%{D58)N{{SE3OM#r@{N{=%0r+^sIqEs0ieNQKGcHf1LoflD0mr2jPy}h!e+pyp#~gFoiYP;4Zh4qz z)`^NKpwFd4C;Fg&+7wY#w*i?dg From 2ca39264d12edd88adec00b1ac1929020a24b99e Mon Sep 17 00:00:00 2001 From: wserr Date: Thu, 26 Dec 2024 09:36:09 +0100 Subject: [PATCH 08/13] Weather service installation --- .gitignore | 1 - microservices/weather/.env | 12 +++++------ microservices/weather/Dockerfile | 2 +- microservices/weather/build-docker.sh | 5 ----- microservices/weather/run-docker.sh | 4 ---- microservices/weather/scripts/build-docker.sh | 3 +++ microservices/weather/scripts/install.sh | 21 +++++++++++++++++++ microservices/weather/scripts/run-docker.sh | 3 +++ microservices/weather/scripts/weather.service | 8 +++++++ microservices/weather/scripts/weather.timer | 8 +++++++ 10 files changed, 50 insertions(+), 17 deletions(-) delete mode 100755 microservices/weather/build-docker.sh delete mode 100755 microservices/weather/run-docker.sh create mode 100755 microservices/weather/scripts/build-docker.sh create mode 100755 microservices/weather/scripts/install.sh create mode 100755 microservices/weather/scripts/run-docker.sh create mode 100644 microservices/weather/scripts/weather.service create mode 100644 microservices/weather/scripts/weather.timer diff --git a/.gitignore b/.gitignore index 097f5c9..57612dd 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,3 @@ configuration-production.yaml .env -run-docker.sh diff --git a/microservices/weather/.env b/microservices/weather/.env index d98824c..d3c36eb 100644 --- a/microservices/weather/.env +++ b/microservices/weather/.env @@ -1,6 +1,6 @@ -weather_weather_api_base_url=https://api.openweathermap.org/data/2.5/weather -weather_weather_api_key=4ce897f7ce77f84919fd990cc68d9d20 -weather_influx_db_base_url=http://192.168.1.44:8092 -weather_influx_db_token=R1BGVaxWrX_ySaovweRz6ZTBDvHa5omQkricJGmn3PrI44jpfU7411PSmHOCjGcNR7OcBjmtE9gA62boHHXoKg== -weather_latitude=50.854019 -weather_longitude=3.355230 +weather_weather_api_base_url= +weather_weather_api_key= +weather_influx_db_base_url= +weather_influx_db_token= +weather_latitude= +weather_longitude= diff --git a/microservices/weather/Dockerfile b/microservices/weather/Dockerfile index 7369127..ad5ed6f 100644 --- a/microservices/weather/Dockerfile +++ b/microservices/weather/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.67 as builder +FROM rust:1.71 as builder WORKDIR /usr/src/weather COPY . . RUN cargo install --path . diff --git a/microservices/weather/build-docker.sh b/microservices/weather/build-docker.sh deleted file mode 100755 index 34d3345..0000000 --- a/microservices/weather/build-docker.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -docker build . -t weather-microservice:latest -docker tag weather-microservice:latest registry.willemserruys.com/weather-microservice:latest -docker push registry.willemserruys.com/weather-microservice:latest diff --git a/microservices/weather/run-docker.sh b/microservices/weather/run-docker.sh deleted file mode 100755 index a9ea35c..0000000 --- a/microservices/weather/run-docker.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -file=/home/willem/repos/homeAutomation/microservices/weather/logs.$(date "+%F").txt - -docker run --env RUST_LOG=info --env-file /home/willem/repos/homeAutomation/microservices/weather/.env registry.willemserruys.com/weather-microservice:latest &>> $file diff --git a/microservices/weather/scripts/build-docker.sh b/microservices/weather/scripts/build-docker.sh new file mode 100755 index 0000000..1b7895a --- /dev/null +++ b/microservices/weather/scripts/build-docker.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +docker build ../ -t weather-service:latest diff --git a/microservices/weather/scripts/install.sh b/microservices/weather/scripts/install.sh new file mode 100755 index 0000000..d5081f4 --- /dev/null +++ b/microservices/weather/scripts/install.sh @@ -0,0 +1,21 @@ +#!/usr/bin/bash + +# This script should be run as root +# Build and install weather service + +./build-docker.sh + +ln -s $HOME/repos/homeAutomation/microservices/weather/run-docker.sh /usr/bin/weather-service + +cp weather.service /etc/systemd/system/ +cp weather.timer /etc/systemd/system/ + +systemctl daemon-reload + +systemctl enable weather.service +systemctl enable weather.timer + +systemctl start weather.service +systemctl start weather.timer + + diff --git a/microservices/weather/scripts/run-docker.sh b/microservices/weather/scripts/run-docker.sh new file mode 100755 index 0000000..ac6e739 --- /dev/null +++ b/microservices/weather/scripts/run-docker.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +# Make sure the weather-service-image exists locally (e.g. by running the build-docker script) +docker run --env RUST_LOG=info --env-file /home/pi/repos/homeAutomation/microservices/weather/.env.production weather-service:latest diff --git a/microservices/weather/scripts/weather.service b/microservices/weather/scripts/weather.service new file mode 100644 index 0000000..7378f4e --- /dev/null +++ b/microservices/weather/scripts/weather.service @@ -0,0 +1,8 @@ +[Unit] +Description=Weather Service + +[Service] +ExecStart=/usr/bin/weather-service + +[Install] +WantedBy=multi-user.target diff --git a/microservices/weather/scripts/weather.timer b/microservices/weather/scripts/weather.timer new file mode 100644 index 0000000..b274785 --- /dev/null +++ b/microservices/weather/scripts/weather.timer @@ -0,0 +1,8 @@ +[Unit] +Description=Run weather service each 2 minutes + +[Timer] +OnCalendar=*:0/2 + +[Install] +WantedBy=timers.target From 395fb6a55039cbcc29f6ea52b01cab748a0aced0 Mon Sep 17 00:00:00 2001 From: wserr Date: Thu, 26 Dec 2024 10:47:53 +0100 Subject: [PATCH 09/13] Removed production settings --- .gitignore | 1 + home-server/envs/production.env | 16 ---------------- 2 files changed, 1 insertion(+), 16 deletions(-) delete mode 100644 home-server/envs/production.env diff --git a/.gitignore b/.gitignore index 57612dd..1003c2c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Environment files for docker composes .env.production +production.env # Home assistant configuration file configuration-production.yaml diff --git a/home-server/envs/production.env b/home-server/envs/production.env deleted file mode 100644 index b8cc543..0000000 --- a/home-server/envs/production.env +++ /dev/null @@ -1,16 +0,0 @@ -# Maria DB settings -# For testing purposes only. Please create a .env.mariadb to overwrite these variables -MARIADB_ROOT_PASSWORD=c8gcablGDuJH2tnbAXjPiQ== - -MARIADB_DATABASE=homeassistant -MARIADB_USER=homeassistant_user -MARIADB_PASSWORD=gyxxny8gO6bzczw+ULuALA== - -GF_SECURITY_ADMIN_USER=admin -GF_SECURITY_ADMIN_PASSWORD=QCpuH3Fnet7g9ywlRQ1Gtw== -GF_USERS_ALLOW_SIGN_UP=false - -DOCKER_INFLUXDB_INIT_USERNAME=homeassistant -DOCKER_INFLUXDB_INIT_PASSWORD=IEOUjgdbI3XjJnmqQOPkHw== -DOCKER_INFLUXDB_INIT_ORG=homeassistant -DOCKER_INFLUXDB_INIT_BUCKET=homeassistant From c572c06ccb3abf815dd2fd81347f3f0cebdef914 Mon Sep 17 00:00:00 2001 From: wserr Date: Thu, 26 Dec 2024 10:48:34 +0100 Subject: [PATCH 10/13] Cleanup MariaDB leftovers --- home-server/envs/local.env | 8 -------- 1 file changed, 8 deletions(-) diff --git a/home-server/envs/local.env b/home-server/envs/local.env index bb93fe1..3498304 100644 --- a/home-server/envs/local.env +++ b/home-server/envs/local.env @@ -1,11 +1,3 @@ -# Maria DB settings -# For testing purposes only. Please create a .env.mariadb to overwrite these variables -MARIADB_ROOT_PASSWORD=testing - -MARIADB_DATABASE=homeassistant -MARIADB_USER=homeassistant_user -MARIADB_PASSWORD=homeassistant_pw - GF_SECURITY_ADMIN_USER=test GF_SECURITY_ADMIN_PASSWORD=test GF_USERS_ALLOW_SIGN_UP=false From 861f72e897b6f02ed2ff47ac6cb6b827c5566388 Mon Sep 17 00:00:00 2001 From: wserr Date: Thu, 26 Dec 2024 10:52:28 +0100 Subject: [PATCH 11/13] Cleanup --- home-server/docker-compose.yml | 16 ++++---- .../{envs => environment-variables}/local.env | 0 home-server/{envs => }/readme.md | 0 raspberrypi/docker-compose.yml | 38 ------------------- raspberrypi/log/.gitkeep | 0 5 files changed, 8 insertions(+), 46 deletions(-) rename home-server/{envs => environment-variables}/local.env (100%) rename home-server/{envs => }/readme.md (100%) delete mode 100644 raspberrypi/docker-compose.yml delete mode 100644 raspberrypi/log/.gitkeep diff --git a/home-server/docker-compose.yml b/home-server/docker-compose.yml index 3e495c3..bf2015d 100644 --- a/home-server/docker-compose.yml +++ b/home-server/docker-compose.yml @@ -26,8 +26,8 @@ services: ports: - 3306:3306 env_file: - - envs/local.env - - envs/production.env + - environment-variables/local.env + - environment-variables/production.env volumes: - ${STORAGE_DIR}/mariadb:/var/lib/mysql homeassistant: @@ -40,8 +40,8 @@ services: - ${REPO_DIR}/configurations/home-assistant/configuration-production.yaml:/config/configuration.yaml restart: unless-stopped env_file: - - envs/local.env - - envs/production.env + - environment-variables/local.env + - environment-variables/production.env syncthing: image: lscr.io/linuxserver/syncthing:latest container_name: syncthing @@ -96,8 +96,8 @@ services: volumes: - ${STORAGE_DIR}/grafana:/var/lib/grafana env_file: - - envs/local.env - - envs/production.env + - environment-variables/local.env + - environment-variables/production.env labels: - traefik.http.routers.grafana.rule=Host(`grafana.pladijs`) - traefik.http.services.grafana.loadbalancer.server.port=3000 @@ -112,8 +112,8 @@ services: - TZ=Europe/Brussels - DOCKER_INFLUXDB_INIT_MODE=setup env_file: - - envs/local.env - - envs/production.env + - environment-variables/local.env + - environment-variables/production.env volumes: - ${STORAGE_DIR}/influxdb/data:/var/lib/influxdb2 - ${STORAGE_DIR}/influxdb/config/:/etc/influxdb2 diff --git a/home-server/envs/local.env b/home-server/environment-variables/local.env similarity index 100% rename from home-server/envs/local.env rename to home-server/environment-variables/local.env diff --git a/home-server/envs/readme.md b/home-server/readme.md similarity index 100% rename from home-server/envs/readme.md rename to home-server/readme.md diff --git a/raspberrypi/docker-compose.yml b/raspberrypi/docker-compose.yml deleted file mode 100644 index f9c212e..0000000 --- a/raspberrypi/docker-compose.yml +++ /dev/null @@ -1,38 +0,0 @@ -version: "3.9" -services: - whoami: - restart: unless-stopped - network_mode: "host" - image: traefik/whoami - command: - - --port=2001 - traefik: - restart: unless-stopped - network_mode: "host" - image: "traefik:1.7.10" - volumes: - - /home/pi/repos/homeAutomation/configurations/traefik/traefik.1.7.10.toml:/etc/traefik/traefik.toml - mosquitto: - restart: unless-stopped - image: eclipse-mosquitto:2 - volumes: - - /home/pi/repos/homeAutomation/configurations/eclipse-mosquitto/:/mosquitto/config/:ro - - ./log/:/mosquitto/log/ - ports: - - 2883:1883 - - 9001:9001 - node-exporter: - image: prom/node-exporter:latest - container_name: node-exporter - restart: unless-stopped - volumes: - - /proc:/host/proc:ro - - /sys:/host/sys:ro - - /:/rootfs:ro - command: - - '--path.procfs=/host/proc' - - '--path.rootfs=/rootfs' - - '--path.sysfs=/host/sys' - - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)' - ports: - - 9100:9100 diff --git a/raspberrypi/log/.gitkeep b/raspberrypi/log/.gitkeep deleted file mode 100644 index e69de29..0000000 From d33fbf8dd0ced0c0027b774c7d617ef18666cca2 Mon Sep 17 00:00:00 2001 From: wserr Date: Thu, 26 Dec 2024 10:54:49 +0100 Subject: [PATCH 12/13] Cleanup --- .gitignore | 2 -- microservices/readme.md | 3 --- microservices/weather/.gitignore | 1 - microservices/weather/{ => environment-variables}/.env | 0 microservices/weather/scripts/run-docker.sh | 2 +- 5 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 microservices/readme.md rename microservices/weather/{ => environment-variables}/.env (100%) diff --git a/.gitignore b/.gitignore index 1003c2c..cbcb1cd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,3 @@ production.env # Home assistant configuration file configuration-production.yaml - -.env diff --git a/microservices/readme.md b/microservices/readme.md deleted file mode 100644 index d357649..0000000 --- a/microservices/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# Microservices - -TODO diff --git a/microservices/weather/.gitignore b/microservices/weather/.gitignore index 9f674f0..7d78b58 100644 --- a/microservices/weather/.gitignore +++ b/microservices/weather/.gitignore @@ -15,7 +15,6 @@ Cargo.lock # App settings Settings.toml -.env # Log files logs.*.txt diff --git a/microservices/weather/.env b/microservices/weather/environment-variables/.env similarity index 100% rename from microservices/weather/.env rename to microservices/weather/environment-variables/.env diff --git a/microservices/weather/scripts/run-docker.sh b/microservices/weather/scripts/run-docker.sh index ac6e739..bd78ed4 100755 --- a/microservices/weather/scripts/run-docker.sh +++ b/microservices/weather/scripts/run-docker.sh @@ -1,3 +1,3 @@ #!/usr/bin/env bash # Make sure the weather-service-image exists locally (e.g. by running the build-docker script) -docker run --env RUST_LOG=info --env-file /home/pi/repos/homeAutomation/microservices/weather/.env.production weather-service:latest +docker run --env RUST_LOG=info --env-file /home/pi/repos/homeAutomation/microservices/weather/environment-variables/.env.production weather-service:latest From 0b2fd2a97170966ff9116c7e9ccdece825e15242 Mon Sep 17 00:00:00 2001 From: wserr Date: Thu, 26 Dec 2024 10:56:16 +0100 Subject: [PATCH 13/13] Cleanup --- configurations/eclipse-mosquitto/mosquitto.conf | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 configurations/eclipse-mosquitto/mosquitto.conf diff --git a/configurations/eclipse-mosquitto/mosquitto.conf b/configurations/eclipse-mosquitto/mosquitto.conf deleted file mode 100644 index 409b5f8..0000000 --- a/configurations/eclipse-mosquitto/mosquitto.conf +++ /dev/null @@ -1,9 +0,0 @@ -listener 1883 -persistence false -# persistence_location /mosquitto/data/ -log_dest file /mosquitto/log/mosquitto.log - -## Authentication ## -# By default, Mosquitto >=2.0 allows only authenticated connections. Change to true to enable anonymous connections. -allow_anonymous true -# password_file /mosquitto/config/password.txt