Vorbereitungen fuer das Deployen in die Produktionsumgebung wurden getroffen. Unter anderen wurde eine zweites docker-compose.prod.yml File erstellt. Dieses sollte praktisch identisch mit docker-compose.yml sein. Aber das Haendling der Secrets erledigen. Lokal wird imer docker-compose.yml verwendet.
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
services:
|
||||
logic-red:
|
||||
build: ./logic
|
||||
volumes:
|
||||
- ./logic/node-red-data:/data
|
||||
- ./shared_data:/data/results # Hier landen die JSON/SQLite Dateien
|
||||
- ./logic/scripts:/data/scripts
|
||||
environment:
|
||||
- TZ=Europe/Zurich
|
||||
- GROUPINFO_JSON_LNK_NAME=archivegroup_information.json
|
||||
- GROUPINFO_JSON_LNK_NAME_WITH_PATH=/data/archivegroup_information.json
|
||||
- NON_SPECIFIED_GROUPS=/data/non_specified_groups.csv
|
||||
- BEGIN_NAME_GROUPINFO_JSON_FILE=size_by_ownergroup_and_number_of_copies_
|
||||
- BEGIN_NAME_GROUPINFO_JSON_FILE_WITH_PATH=/data/size_by_ownergroup_and_number_of_copies_
|
||||
- ERROR_LOGFILE=/data/logs/get_new_groupinfo_error.log
|
||||
- JSON_CACHE=json_cache.json
|
||||
- JSON_CACHE_WITH_PATH=/data/json_cache.json
|
||||
- AD_SERVER=d.psi.ch
|
||||
- AD_SEARCH_BASE=DC=d,DC=psi,DC=ch
|
||||
- AD_USER=${AD_USER}
|
||||
- AD_PASSWORD=${AD_PASSWORD}
|
||||
- METABASE_API_KEY=${METABASE_API_KEY}
|
||||
# Behalte size_by_ownergroup_and_number_of_copies_ Files juenger als CLEANUP_TIME Tage
|
||||
- CLEANUP_TIME=20
|
||||
# Ausfuehrungszeitpunkt fuer den Cleanup im Cron-Format (Minuten Stunden * * *)
|
||||
- CLEANUP_CRON=0 7 * * *
|
||||
# Pfad zum Cleanup-Skript
|
||||
- CLEANUP_SCRIPT_PATH=/data/scripts/cleanup.sh
|
||||
# Pfad zum Logfile des Cleanup-Skripts
|
||||
- CLEANUP_LOGFILE_PATH=/data/logs/cleanup.log
|
||||
# Ausfuehrungszeitpunkt fuer den Haupt-Workflow im Cron-Format
|
||||
- MAIN_WORKFLOW_CRON=0 6 * * *
|
||||
secrets:
|
||||
- ad_user
|
||||
- ad_password
|
||||
- metabase_api_key
|
||||
ports:
|
||||
- "1880:1880"
|
||||
|
||||
# --- NEUER STREAMLIT CONTAINER ---
|
||||
analytics-app:
|
||||
build: ./analytics
|
||||
ports:
|
||||
- "8501:8501" # Standard-Port für Streamlit im Browser
|
||||
volumes:
|
||||
- ./analytics:/app # Mappt deinen Code, damit Änderungen live ohne Rebuild sichtbar sind
|
||||
- ./shared_data:/data:ro # Bindet die JSON-Daten NUR LESEND unter /data ein
|
||||
- ./analytics/config:/app/config # Mappt den config Ordner
|
||||
- ./analytics/data:/app/data # Mappt den data Ordner
|
||||
environment:
|
||||
- TZ=Europe/Zurich
|
||||
|
||||
# Deklarieren, dass die Secrets von "außen" kommen
|
||||
secrets:
|
||||
ad_user:
|
||||
external: true
|
||||
ad_password:
|
||||
external: true
|
||||
metabase_api_key:
|
||||
external: true
|
||||
+3
-5
@@ -39,9 +39,7 @@ services:
|
||||
ports:
|
||||
- "8501:8501" # Standard-Port für Streamlit im Browser
|
||||
volumes:
|
||||
- ./analytics:/app # Mappt deinen Code, damit Änderungen live ohne Rebuild sichtbar sind
|
||||
- ./shared_data:/data:ro # Bindet die JSON-Daten NUR LESEND unter /data ein
|
||||
- ./analytics/config:/app/config # Mappt den config Ordner
|
||||
- ./analytics/data:/app/data # Mappt den data Ordner
|
||||
- ./analytics:/app
|
||||
- ./shared_data:/data:ro
|
||||
environment:
|
||||
- TZ=Europe/Zurich
|
||||
- TZ=Europe/Zurich
|
||||
@@ -1,6 +0,0 @@
|
||||
# Wir nehmen einen einfachen, leichten Webserver
|
||||
FROM nginx:alpine
|
||||
|
||||
# Kopiere alle Dateien aus dem lokalen frontend-Ordner
|
||||
# in das Standard-Verzeichnis des Webservers
|
||||
COPY . /usr/share/nginx/html
|
||||
@@ -1,58 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Archivkosten Abfrage</title>
|
||||
<style>
|
||||
body { font-family: sans-serif; margin: 40px; line-height: 1.6; background-color: #f4f4f9; }
|
||||
.container { max-width: 600px; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
|
||||
h1 { color: #333; border-bottom: 2px solid #007bff; padding-bottom: 10px; }
|
||||
.data-row { border-bottom: 1px solid #eee; padding: 10px 0; }
|
||||
.label { font-weight: bold; color: #555; }
|
||||
.error { color: red; font-style: italic; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<h1>Archivkosten Übersicht</h1>
|
||||
<div id="content">
|
||||
<p>Lade aktuelle Daten...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Pfad zur JSON-Datei, die von Node-RED im Shared Volume erstellt wird
|
||||
// In der docker-compose Konfiguration ist dies unter /data/ erreichbar
|
||||
const dataPath = './data/kosten_historie.json';
|
||||
|
||||
async function loadCosts() {
|
||||
const contentDiv = document.getElementById('content');
|
||||
try {
|
||||
const response = await fetch(dataPath);
|
||||
if (!response.ok) throw new Error('Datei nicht gefunden');
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
// Falls die Daten ein Array sind (Historie), zeigen wir das letzte Element
|
||||
const latest = Array.isArray(data) ? data[data.length - 1] : data;
|
||||
|
||||
contentDiv.innerHTML = `
|
||||
<div class="data-row"><span class="label">Datum:</span> ${latest.datum || 'N/A'}</div>
|
||||
<div class="data-row"><span class="label">Kunde:</span> ${latest.kunde || 'Unbekannt'}</div>
|
||||
<div class="data-row"><span class="label">Volumen:</span> ${latest.volumen_gb || 0} GB</div>
|
||||
<div class="data-row"><span class="label">Kosten:</span> CHF ${latest.kosten || 0}</div>
|
||||
`;
|
||||
} catch (error) {
|
||||
contentDiv.innerHTML = `<p class="error">Noch keine aktuellen Daten verfügbar. (Warte auf tägliches Update von Node-RED)</p>`;
|
||||
console.error('Fehler beim Laden:', error);
|
||||
}
|
||||
}
|
||||
|
||||
loadCosts();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -31,3 +31,16 @@ USER node-red
|
||||
|
||||
# Node-RED Module installieren
|
||||
RUN npm install node-red-contrib-moment node-red-contrib-cron-plus
|
||||
|
||||
# Wechsel zu root, um das Entrypoint-Skript zu kopieren und die Rechte zu setzen
|
||||
USER root
|
||||
|
||||
# Kopiere unser neues Entrypoint-Skript
|
||||
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
RUN chmod +x /usr/local/bin/entrypoint.sh
|
||||
|
||||
# Setze unser Skript als den neuen Entrypoint
|
||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||
|
||||
# Der ursprüngliche CMD des Node-RED-Images wird automatisch beibehalten und
|
||||
# an unser Entrypoint-Skript als "$@" übergeben.
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Setze Umgebungsvariablen aus Docker Secrets, falls die Dateien existieren
|
||||
# Wir prüfen, ob die Secret-Dateien existieren, bevor wir sie lesen
|
||||
if [ -f /run/secrets/ad_user ]; then
|
||||
export AD_USER=$(cat /run/secrets/ad_user)
|
||||
fi
|
||||
if [ -f /run/secrets/ad_password ]; then
|
||||
export AD_PASSWORD=$(cat /run/secrets/ad_password)
|
||||
fi
|
||||
if [ -f /run/secrets/metabase_api_key ]; then
|
||||
export METABASE_API_KEY=$(cat /run/secrets/metabase_api_key)
|
||||
fi
|
||||
|
||||
# Führe den ursprünglichen Entrypoint des Node-RED-Images aus.
|
||||
# Der exec-Befehl ersetzt den aktuellen Prozess, was eine bewährte Praxis ist.
|
||||
exec /usr/src/node-red/entrypoint.sh "$@"
|
||||
|
||||
@@ -1 +1 @@
|
||||
size_by_ownergroup_and_number_of_copies_2026-06-25T14_49_44.json
|
||||
size_by_ownergroup_and_number_of_copies_2026-06-25T17_25_58.json
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user