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) <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@ Die Datei **noise.tgz** enthält die folgenden Dateien und Verzeichnisse:
|
|||||||
+- <d>noisesensors
|
+- <d>noisesensors
|
||||||
|
|
|
|
||||||
+- <f>docker-compose.yml
|
+- <f>docker-compose.yml
|
||||||
|
+- <f>readarchive-stack.yml
|
||||||
+- <d>log
|
+- <d>log
|
||||||
+- <d>data
|
+- <d>data
|
||||||
| +- <d>mongo
|
| +- <d>mongo
|
||||||
@@ -25,6 +26,8 @@ Die Datei **noise.tgz** enthält die folgenden Dateien und Verzeichnisse:
|
|||||||
|
|
||||||
* **docker-compose.yml**
|
* **docker-compose.yml**
|
||||||
enthält die Anweisungen für die Docker-Container. Dies kann so an das aktuelle Portainer-Stack angehängt werden.
|
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**
|
* **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.
|
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**
|
* **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
|
Über diesen Container werden alle 5 min. die aktuellen Daten von *sensor.community* abgeholt und in den beiden Datenbanken gespeichert
|
||||||
|
|
||||||
* **readarchive**
|
* **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 (`<stack-name>_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**
|
* **logrotate**
|
||||||
Mit Hilfe dieses Containers werde die Log-Files im Unterverzeichnis *log* täglich rotiert. Es werden 7 Versionen behalten, ältere gelöscht.
|
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:<datum-alt>
|
|||||||
Den Stand aus `noisesensors/docker-compose.yml` dieses Repositories übernehmen. Zu beachten:
|
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.
|
* **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.
|
* **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
|
### 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 |
|
1.0.0 | 2023-11-30 |
|
||||||
2.0.0 | 2026-07-25 | Anpassung an Stack-Änderungen
|
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.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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,3 +11,11 @@ LOCALDIR=<Aktuelle Direcrory ab />
|
|||||||
|
|
||||||
# Datenbank, in welche die laufenden Messwerte gespeichert werden (kannn 'influx' oder 'mongo' sein)
|
# Datenbank, in welche die laufenden Messwerte gespeichert werden (kannn 'influx' oder 'mongo' sein)
|
||||||
STORE=influx
|
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
|
||||||
|
|||||||
@@ -48,24 +48,6 @@ services:
|
|||||||
container_name: readin
|
container_name: readin
|
||||||
restart: unless-stopped
|
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:
|
logrotate:
|
||||||
image: linkyard/logrotate
|
image: linkyard/logrotate
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -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 <stack-name>_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
|
||||||
Reference in New Issue
Block a user