From e2ebebcd421ffc971af14de02acb70a8901b6462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20X=2E=20F=C3=BCrst?= Date: Sun, 2 Aug 2026 13:17:59 +0000 Subject: [PATCH] readarchive als eigenes Stack statt Profil im Haupt-Stack readarchive ist kein Dauerdienst, sondern ein Lauf mit Parametern. Als Service mit profiles: ["tools"] liess er sich aus Portainer gar nicht starten - eine Profil-Auswahl gibt es dort nicht, und ein Gegenstueck zu "docker compose run" ebenso wenig. Jetzt steht er in noisesensors/readarchive-stack.yml. Dieselbe Datei bedient beide Wege: auf der Kommandozeile mit Argumenten via "docker compose -f readarchive-stack.yml run --rm readarchive ...", im Portainer als eigenes Stack mit den Parametern als Environment-Variablen (readFromcsv.js liest -s/-e/-t/-d auch aus START/END/TYP/DBASE). - eigener Projektname "name: readarchive", damit die Datei auf der Kommandozeile nicht das Projekt des Haupt-Stacks uebernimmt - Netz des Haupt-Stacks als external eingebunden - README: readarchive-Abschnitt neu, Profil-Hinweis in der Update-Anleitung ersetzt, Datei in Struktur und Dateiliste ergaenzt - .env.example: Block fuer START/END/TYP/DBASE - noise.tgz neu gepackt, damit die Datei mit ausgeliefert wird Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 29 ++++++++++++-- noise.tgz | Bin 10240 -> 20480 bytes noisesensors/.env.example | 8 ++++ noisesensors/docker-compose.yml | 18 --------- noisesensors/readarchive-stack.yml | 61 +++++++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 22 deletions(-) create mode 100644 noisesensors/readarchive-stack.yml diff --git a/README.md b/README.md index e6eb1f6..5407d28 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Die Datei **noise.tgz** enthält die folgenden Dateien und Verzeichnisse: +- noisesensors | +- docker-compose.yml + +- readarchive-stack.yml +- log +- data | +- mongo @@ -25,6 +26,8 @@ Die Datei **noise.tgz** enthält die folgenden Dateien und Verzeichnisse: * **docker-compose.yml** enthält die Anweisungen für die Docker-Container. Dies kann so an das aktuelle Portainer-Stack angehängt werden. +* **readarchive-stack.yml** +eigenes, kleines Stack für den Einmal-Lauf *readarchive* (siehe unten). Gehört bewusst nicht ins Haupt-Stack, weil es kein Dauerdienst ist. * **log** Ablage für die Logdateien der einzelnene Container (**noise.log**, **sensorapi.log** und **readin.log**) . Diese werden täglich komprimiert. Es werden Versionen für 7 Tage aufgehoben. * **data** @@ -73,11 +76,28 @@ Das Logfile kann via **tail -f log/noise.log** im Verzeichnise **noisesensors** Über diesen Container werden alle 5 min. die aktuellen Daten von *sensor.community* abgeholt und in den beiden Datenbanken gespeichert * **readarchive** -Gegenstück zu *readin*: liest rückwirkend die Tagesdateien von *archive.sensor.community* ein, um Lücken zu füllen. Kein Dauerdienst, sondern ein Lauf mit Parametern — deshalb hängt er im Compose am Profil `tools` und wird von `docker compose up` nicht mitgestartet: +Gegenstück zu *readin*: liest rückwirkend die Tagesdateien von *archive.sensor.community* ein, um Lücken zu füllen. Kein Dauerdienst, sondern ein Lauf mit Parametern — deshalb steht er **nicht** im Haupt-Stack, sondern in der eigenen Datei `readarchive-stack.yml`. + +Auf der Kommandozeile mit Argumenten: ~~~ -docker compose run --rm readarchive -t noise -s 2026-07-22 -e 2026-07-23 -d influx +docker compose -f readarchive-stack.yml run --rm readarchive \ + -t noise -s 2026-07-22 -e 2026-07-23 -d influx ~~~ -Parameter: `-s` Startdatum, `-e` Enddatum (**exklusiv**), `-t` Sensortyp, `-d` Ziel (`mongo`, `influx` oder `both`). Ohne Argumente gilt der Default `-t noise` für den Vortag. Ein Tag dauert etwa zwei Minuten. Schlägt ein Influx-Write fehl, werden die betroffenen Sensoren am Ende aufgelistet und der Exit-Code ist ≠ 0. + +Im **Portainer** als eigenes Stack anlegen (Inhalt von `readarchive-stack.yml`) und die Parameter unten als *Environment variables* eintragen — `docker compose run` hat dort kein Gegenstück, aber `readFromcsv.js` liest jeden Parameter auch aus einer Env-Variablen: + + CLI | Env | Default +---- | ---- | ---- + `-s` | `START` | gestern + `-e` | `END` | Startdatum + 1 Tag (**exklusiv**) + `-t` | `TYP` | `noise` + `-d` | `DBASE` | `both`, in der Stack-Datei auf `influx` vorbelegt + +*Deploy the stack* startet den Lauf, der Container endet danach und bleibt als „Exited" stehen. Für den nächsten Zeitraum nur die Variablen ändern und *Update the stack*. Der Haupt-Stack wird dabei nicht angefasst. + +Beide Wege brauchen das Netz des laufenden Haupt-Stacks (`_default`, in `readarchive-stack.yml` als `external` eingetragen) sowie dieselben Zugangsdaten und `LOCALDIR` — auf der Kommandozeile aus einer `.env` neben der Datei, im Portainer aus den Stack-Variablen. Auch mit `-d influx` wird Mongo gebraucht, dort liegen die Metadaten der Sensoren. + +Ein Tag dauert etwa zwei Minuten. Schlägt ein Influx-Write fehl, werden die betroffenen Sensoren am Ende aufgelistet und der Exit-Code ist ≠ 0 (im Portainer als „Exited (1)" sichtbar). * **logrotate** Mit Hilfe dieses Containers werde die Log-Files im Unterverzeichnis *log* täglich rotiert. Es werden 7 Versionen behalten, ältere gelöscht. @@ -147,7 +167,7 @@ docker push docker.citysensor.de/readin: Den Stand aus `noisesensors/docker-compose.yml` dieses Repositories übernehmen. Zu beachten: * **Zwingend** bei einem Update von einem Stand vor August 2026: das Volume von *readin* muss auf `/opt/app/readin/data` zeigen, nicht mehr auf `/opt/app/data`. Das Layout im Image spiegelt seit der Einführung von `common/` das Repository. Bleibt der alte Pfad stehen, schreibt readin `aktdata.json` in die Container-Schicht statt auf den Host. -* Optional der Service **readarchive** mit `profiles: ["tools"]`. +* Der Service **readarchive** gehört nicht mehr ins `docker-compose.yml`. Steht er dort noch (mit `profiles: ["tools"]`), kann er beim Update entfallen — er wird durch das eigene Stack `readarchive-stack.yml` ersetzt. * **Nicht** aufnehmen: ein Mount auf `/etc/influxdb2`. Das Entrypoint von influxdb legt dort beim Setup das CLI-Profil `default` an. Ist bereits eines vorhanden, scheitert der Setup — und das Entrypoint löscht daraufhin `influxd.bolt` und `engine/` im Datenverzeichnis und startet neu. Weil der Mount das Aufräumen überlebt, wiederholt sich das endlos und der Datenbestand ist bei jeder Runde weg. ### 3. Nur den geänderten Container ziehen @@ -183,6 +203,7 @@ Image-Tag im Stack auf den in Schritt 1 gesicherten Stand setzen, die Volume-Zei 1.0.0 | 2023-11-30 | 2.0.0 | 2026-07-25 | Anpassung an Stack-Änderungen 2.1.0 | 2026-08-01 | readarchive dazu, gemeinsame Module unter common/, Zeitstempel in UTC + 2.1.1 | 2026-08-02 | readarchive als eigenes Stack (readarchive-stack.yml) diff --git a/noise.tgz b/noise.tgz index 76988ca33fcfbadd4d5e9ab729fecc5ca5f6be97..ca87082c4e4afe0cba2a6caf9d109d97a003f60e 100644 GIT binary patch delta 2530 zcmai0U2hvj6m8N{BGb=@KC~~~#uO#sb?kgfhEz?PlvcP&)TFJ5D#64%wkO%0wPt41 zq^Q~oc;W?B{sTPnhSa?AS9szd@Dn(9b`x(45`IY5J2Q9AJ@?#m{d)8DuVZh=e;U8O zwA4J)T$r7kTbyq!EG?dCG#BO<=FU)K*c=Ow$36(p9{)CR;cQl=&8`SZ#q=;1JxR(s z+LP|3qnTvjX2f7HW26X`uF(srBFeu|szd)MOsB67WQF{vN>+9H)Jftv(KF<5Kx)4? z6qefJC`ldh<6}8Uta6E|9FZL;*^`kQemC*ywbpyL&V<5=p}2VMe17rp%_SP%y72RO zqjCKEg>z>ob)u}aQrpB>kF-D(SSLFB^`kg?bM@}|20n}P!@YAit~Wu(h?oTsv)F7d zoDy?$Y%E(-Jp^<@>JU$swm1}ZQ)$XMQ$YJtX<8Ln2o;~Gkxg_cjV4}bi?my*Qmh

Qv@2DJz0bh5ZuxCQUn8W@Ve*noMN=MU#z09# zmR3wJjd4^?W52I(nBYFc6-EIi1>G_uBhHbYrXVnJd6}LUL2|KB;K)~x0!y=v*~Or- z6wJ<2kjc^4ISL?7-Hp=20`X>IoKPAdaqwjMW(e^i+%Q-e$y}PotwtND?Ll17#svJbg5xKr3FSIXkk)eBuF0e&H zrd`K%ibX_WiZ=0mfND#J8Wj}KeHIm0MGM*KTZgBeOe$vts>`w%Wx{e~X`%H-=O>>G zSTiFaleqx6Tke}A?%0F+o~6iZZcp+}r&=VD0+mQD!vqWv=!wfbb9u#4nq~5Y(bTH! ziZpU9f>2q?(=`etmcd?W5zS&8FaiJP)MQ!LJY0FWAEj0u@F|B=pty9(lg&#ZEoV9B zrPbZU^{4a1o+hBiS~ygya~*@q&rlCT4@5d}LEfx6|23x8YXBWY>o`Pcxsdt_+mUon z?t)D;jX%GR7Gv;qf23ikni>-GA>G4VE6WAI?n*7^L)uzC6V z@R!Q`)khoaUu~>B*?!QXNeAzo98P@HA6~xnAqH3^K|mxR3JqNqDy1o_Pzg#v(sVJN zypCJ+$@lp~@TzzZ0rOk_clr+UM)$yLe|PCnmFUD(_6Q zB0oRU{LNKb^ZpR$G;LTyQVJ;>~4hfYDHO)L@nYHwt%K!Ws-WmJj EA7^4C<^TWy delta 220 zcmZozz}OJLlb4@aoLZckSDar|JXugGc%lO9#1vH#QzK(TLnCuzQ$q#=Lql_OBL)T2 z$%c$6n;98-7&r2kGfA46nlKoGlo^{Dn;4q{m6@8Dm@+6BK$J13Fi$oUR}#w1OUo&( z&`-|KOUq2R(oZc(-W3@8&;TEX)&E_->MF7LYP9H-_2@cbtilks;hx?b}S7x9h2}0010GIjaBw diff --git a/noisesensors/.env.example b/noisesensors/.env.example index 3fca492..c34144b 100644 --- a/noisesensors/.env.example +++ b/noisesensors/.env.example @@ -11,3 +11,11 @@ LOCALDIR= # Datenbank, in welche die laufenden Messwerte gespeichert werden (kannn 'influx' oder 'mongo' sein) STORE=influx + +# Nur fuer readarchive-stack.yml: Zeitraum und Ziel des Einmal-Laufs. +# Leer lassen = Default (gestern, ein Tag, TYP=noise, DBASE=influx). +# END ist exklusiv. +#START=2026-07-22 +#END=2026-07-23 +#TYP=noise +#DBASE=influx diff --git a/noisesensors/docker-compose.yml b/noisesensors/docker-compose.yml index 3f38e13..6ac4cbe 100644 --- a/noisesensors/docker-compose.yml +++ b/noisesensors/docker-compose.yml @@ -48,24 +48,6 @@ services: container_name: readin restart: unless-stopped - # Kein Dauerdienst, sondern ein Lauf mit Parametern - liest rueckwirkend die - # Tagesdateien von archive.sensor.community ein: - # docker compose run --rm readarchive -t noise -s 2026-07-25 -e 2026-07-29 - # Das Profil verhindert, dass "docker compose up" ihn mitstartet. - readarchive: - image: docker.citysensor.de/readarchive - profiles: ["tools"] - environment: - MONGOHOST: mongodb - INFLUXHOST: influxdb - MONGOAUTH: "true" - MONGOUSRP: ${MONGO_ROOT_USERNAME}:${MONGO_ROOT_PASSWORD} - INFLUXTOKEN: ${DOCKER_INFLUXTOKEN} - volumes: - - ${LOCALDIR}/noisesensors/log:/var/log - - ${LOCALDIR}/noisesensors/data/readarchive:/opt/app/readarchive/data - restart: "no" - logrotate: image: linkyard/logrotate volumes: diff --git a/noisesensors/readarchive-stack.yml b/noisesensors/readarchive-stack.yml new file mode 100644 index 0000000..6fad3df --- /dev/null +++ b/noisesensors/readarchive-stack.yml @@ -0,0 +1,61 @@ +# Eigenstaendiges Stack fuer readarchive - kein Dauerdienst, sondern ein Lauf +# mit Parametern. Liest rueckwirkend die Tagesdateien von +# archive.sensor.community ein, um Luecken zu fuellen. +# +# Dieselbe Datei dient beiden Wegen: +# +# Kommandozeile (Parameter als Argumente): +# docker compose -f readarchive-stack.yml run --rm readarchive \ +# -t noise -s 2026-07-22 -e 2026-07-23 -d influx +# +# Portainer (Parameter als Environment-Variablen des Stacks): +# START=2026-07-22 END=2026-07-23 TYP=noise DBASE=influx +# -> Deploy the stack; der Container laeuft einmal durch und endet. +# Fuer den naechsten Zeitraum die Variablen aendern und +# "Update the stack". +# +# readFromcsv.js liest jeden Parameter auch aus einer Env-Variablen: +# -s = START (Default: gestern), -e = END (Default: Startdatum + 1 Tag, +# exklusiv), -t = TYP (Default: noise), -d = DBASE (Default: both). +# +# Voraussetzungen: +# * Der Haupt-Stack laeuft, denn dessen Netz wird hier eingebunden. Der Name +# ist _default (im Portainer unter Networks nachsehen). +# * Zugangsdaten und LOCALDIR wie im Haupt-Stack - auf der Kommandozeile aus +# einer .env neben dieser Datei, im Portainer aus den Stack-Variablen. +# * Auch mit DBASE=influx wird Mongo gebraucht (dort liegen die Metadaten der +# Sensoren), das Netz muss also beide erreichen. + +# Eigener Projektname, damit dieses Compose-File auf der Kommandozeile nicht +# das Projekt des Haupt-Stacks uebernimmt (sonst "orphan containers" und ein +# versehentliches "down" trifft den ganzen Stack). Portainer setzt den +# Projektnamen ueber den Stack-Namen und ueberschreibt diesen Wert. +name: readarchive + +services: + readarchive: + image: docker.citysensor.de/readarchive + environment: + MONGOHOST: mongodb + INFLUXHOST: influxdb + MONGOAUTH: "true" + MONGOUSRP: ${MONGO_ROOT_USERNAME}:${MONGO_ROOT_PASSWORD} + INFLUXTOKEN: ${DOCKER_INFLUXTOKEN} + # leer lassen = Default (siehe oben) + START: ${START:-} + END: ${END:-} + TYP: ${TYP:-noise} + DBASE: ${DBASE:-influx} + volumes: + - ${LOCALDIR}/noisesensors/log:/var/log + - ${LOCALDIR}/noisesensors/data/readarchive:/opt/app/readarchive/data + # Einmal-Lauf: nach dem Ende nicht neu starten. Exit-Code != 0 bedeutet, + # dass Influx-Writes fehlgeschlagen sind (Details im Log). + restart: "no" + networks: + - noise + +networks: + noise: + external: true + name: noisesensors_default