MyTime
Persönliche Web-App zur Urlaubsplanung und Überstunden-Erfassung für eine Person im Heimnetz. Ohne Anmeldung — deshalb nur im Heimnetz betreiben.
Starten
docker compose up --build -d
Danach im Browser http://<server-ip>:3000 öffnen. Falls Port 3000 auf
dem Server belegt ist: APP_PORT=3100 docker compose up --build -d und
http://<server-ip>:3100 öffnen.
Deployment auf dem Server (Beispiel)
Voraussetzungen auf dem Server: Docker + Docker Compose Plugin, Git, Zugang zum Gitea-Repo.
# 1. Repo klonen und wechseln
git clone https://gitea.lokcal.de/loki/mytime.git
cd mytime
# 2. Umgebung anlegen (Port ggf. anpassen)
cp .env.example .env
# 3. Bauen und starten (läuft nach Reboot automatisch weiter)
docker compose up --build -d
# 4. Prüfen
curl http://127.0.0.1:3100/api/health
Danach im Heimnetz http://<server-ip>:3100 öffnen und die
Sollstunden eintragen. Daten (./data) und Sicherungen (./backups)
liegen als Ordner neben der Compose-Datei und bleiben bei
Container-Tausch erhalten.
Aktualisieren (neue Version einspielen):
cd mytime
git pull
docker compose up --build -d --force-recreate
curl http://127.0.0.1:3100/api/health
Deployment per fertigem Image (ohne Build auf dem Server)
Einmalig in Gitea einrichten:
- Actions-Runner registrieren (ohne Runner startet kein Workflow).
- Prüfen, dass die Container-Registry aktiv ist.
- Im Repo
mytimeunter Einstellungen → Aktionen → Secrets zwei Secrets anlegen:REGISTRY_USERundREGISTRY_TOKEN(Token mit Schreibrecht für Pakete).
Danach baut jeder Push auf main automatisch das Image
(gitea.lokcal.de/loki/mytime:latest plus Commit-SHA) — inklusive Tests,
tsc und Production-Build als Qualitäts-Tor.
Auf dem Server (kein Node/npm nötig, nur Docker + Git):
git clone https://gitea.lokcal.de/loki/mytime.git
cd mytime
cp .env.example .env
docker compose -f compose.prod.yaml pull
docker compose -f compose.prod.yaml up -d
curl http://127.0.0.1:3100/api/health
Aktualisieren:
cd mytime
docker compose -f compose.prod.yaml pull
docker compose -f compose.prod.yaml up -d --force-recreate
curl http://127.0.0.1:3100/api/health
Beim ersten Start nach den wöchentlichen Sollstunden (Stunden pro Wochentag,
0 für freie Tage) gefragt. Erst danach lassen sich Arbeitszeiten und
Urlaub eintragen.
Bedienung (kurz)
Startseite mit Salden, Jahrestabelle, Zeiterfassung (mit Datumswahl), Feiertagen, Verlauf und Einstellungen — umschaltbar über Tabs (mit Tastatur: Pfeiltasten, ohne Scrollsprung). Über den Tabs steht der MyTime-Header mit Sonne/Mond-Umschalter für Hell- und Dunkelmodus. Unter „Darstellung" in den Einstellungen lässt sich zwischen Hell- und Dunkelmodus wechseln (Wahl wird pro Gerät gespeichert). Unter den Salden steht „Noch N Tage für M Monate" plus Warnung bei knappem Rest. Die Einstellungen teilen sich in „Arbeitszeit" (Tagessolls mit 40-h-Knopf und Wochensumme) und „Urlaub & Bundesland" (Anspruch, Übertrag, Bundesland). An der Jahrestabelle lässt sich das Jahr wechseln (vor/zurück); alle Salden, Tabellen und Einstellungen folgen dem gewählten Jahr. In der Übersicht stehen Überstunden- und Urlaubsformular nebeneinander über der Jahrestabelle; ein Kalendertag wählt das Buchungsdatum, Ziehen über Tage füllt den Urlaubszeitraum vor. Auf dem Smartphone: Tag eine halbe Sekunde gedrückt halten markiert den Starttag („Endtag wählen"), dann Endtag antippen — erneutes Tippen bricht ab; Wischen scrollt wie gewohnt. Urlaub lässt sich nur im Rahmen des Restanspruchs buchen (Anspruch + Übertrag − verbraucht, je Jahr); darüber hinaus lehnt die App mit einer Meldung ab. Gebuchter Urlaub erscheint grün, Feiertage rot. Die Jahrestabelle zeigt das Jahr einmal oben und darunter Monatsspalten im Excel-Stil mit Tageszeilen; die Zellen tragen den abgekürzten Wochentag, die Tageszahl steht in der Zeile. Nach dem Ziehen bleibt der Zeitraum markiert und ein Popup bietet die direkte Buchung mit Anzeige der Arbeitstage an; der nächste Klick schließt es wieder. Ein Klick auf einen Kalendertag öffnet zusätzlich ein Tagesfenster mit Wochentag, Feiertag, Zeiterfassung, Urlaubsstatus (bei mehrtägigem Urlaub mit Zeitraum) und Überstunden des Tages sowie direkter Überstunden- (auch Abbau) und Urlaubsbuchung im Fenster (Schließen per ✕, Escape oder Außen-Tipp). Eine bestehende Urlaubsbuchung lässt sich im Tagesfenster mit Sicherheitsabfrage stornieren; im Verlauf-Tab gibt es unter „Urlaubsbuchungen" eine Mehrfachauswahl zum gemeinsamen Stornieren. Storniertes landet im „Papierkorb" und kann von dort wiederhergestellt oder endgültig gelöscht werden. Überstunden werden per Auswahl gebucht (Stunden, Minuten in 5er-Schritten, Abbau-Schalter), sodass keine Tippfehler möglich sind. Der Verlauf-Tab teilt sich in Jahresübersicht und Überstundenverlauf. Im Feiertage-Tab stehen alle Feiertage des Jahres inklusive vergangener; das Bundesland lässt sich dort wie in den Einstellungen wählen (Standard: Hamburg), ein Klick springt zum Tag. Die Umschalter Feiertage/Brückentage stehen direkt unter den Haupt-Tabs. Darunter schlägt der Feiertage-Tab Brückentage vor: optimale Urlaubsblöcke bis 4 Tage mit Kosten und Ertrag (z. B. „4 Tage Urlaub → 10 Tage frei"), bereits Gebuchtes ausgenommen. Die Vorschläge stammen aus gespeicherten Daten von ferien-feiertage.de (jährlich aktualisierbar) und sind nach Monaten gruppiert; jedem Monat steht ein Mini-Kalender mit markierten Brückentagen voran, auch monatsübergreifende Bereiche erscheinen in beiden Monaten. Eigener Jahr-Umschalter nur für Brückentage; die Liste ist fest nach Datum sortiert. Klick füllt den Zeitraum vor, markiert den Starttag und springt in die Übersicht; „Übernehmen" bucht die Empfehlung nach Sicherheitsabfrage direkt (Anspruch wird serverseitig geprüft). Der Verlauf-Tab zeigt alle zwölf Monate kompakt mit Urlaub, Feiertagen und erfassten Tagen samt Monatssummen und hat einen eigenen Jahr-Umschalter, der nur den Verlauf-Tab betrifft und beim Tabwechsel auf das App-Jahr zurückspringt. Unter „Urlaubsbuchungen" stehen alle Buchungen aller Jahre zur Mehrfach-Stornierung, unter „Überstundenverlauf" alle Überstundeneinträge aller Jahre, unter „Papierkorb" stornierte Buchungen zum Wiederherstellen oder endgültigen Löschen, unter „Jahresvergleich" Anspruch, Verbrauch, Rest und Überstunden von Vorjahr und aktuellem Jahr nebeneinander. Die Mini-Kalender in Brückentage und Jahr tragen Wochentagsköpfe; Urlaub ist grün, Feiertage rot, Brückentage grün umrandet, alle Zellen tragen eine dezente Rasterlinie. Beim Zeigen auf eine Brückentags-Empfehlung werden deren Tage im zugehörigen Monatskalender hervorgehoben. Eine Legende erklärt die Farben in Jahrestabelle, Brückentage, Jahresübersicht und Kalender-Seite; die separate Kalender-Seite zeigt zwei Monate mit Blätterfunktion. Urlaubsbuchungen und Überstundenverlauf lassen sich je als CSV-Datei herunterladen. Die Jahresübersicht lässt sich zusätzlich als gestaltetes PDF exportieren (Kopf mit Jahr, Salden-Box, Monatstabelle mit Gitter, Anhang mit allen Urlaubs- und Überstundenbuchungen samt exakten Daten, Fußzeile mit Stand und Seite).
Brückentage aktualisieren
Die Brückentage stammen von ferien-feiertage.de (alle 16 Bundesländer, mehrere Jahre) und sind im Image eingebaut, damit die App auch offline funktioniert. Einmal im Jahr neu holen (Internet nötig):
npm run scrape:bridge(Standard: laufendes + nächstes Jahr; optional:--years=2028,2029,2030 --states=HH,BY). Bereits gespeicherte Jahre bleiben erhalten.npm test -- --run,npm run test:scripts- Image neu bauen:
APP_PORT=3100 docker compose up --build -d --force-recreate
Für Jahre ohne gespeicherte Daten zeigt der Brückentage-Tab einen Hinweis statt Vorschlägen.
Heimnetz-Hinweis
Der Compose-Port 3000:3000 ist auf allen Interfaces des Servers
erreichbar. Im Router kein Port-Forwarding ins Internet einrichten und den
Port in der Server-Firewall nur für das Heimnetz freigeben.
Daten und Sicherung
- Datenbank:
./data/app.sqlite3(bleibt beim Container-Tausch erhalten). - Sicherung: einmal pro Woche automatisch nach
./backups, höchstens fünf Stände — die älteste Sicherung wird ersetzt. In den Einstellungen gibt es unter „Sicherung" die Liste aller Stände (Datum, Größe) plus einen Knopf „Jetzt sichern".
Sicherung zurückspielen
- App stoppen:
docker compose stop app - Gewünschte Sicherung kopieren:
cp backups/<backup-datei>.sqlite3 data/app.sqlite3 - WAL-Seitendateien löschen (wichtig, sonst legt SQLite alte
Transaktionen über die eingespielte Sicherung):
rm -f data/app.sqlite3-wal data/app.sqlite3-shm - App starten:
docker compose start app - Übersicht und Kalender prüfen.