Repo-Backups, Gitea-Theme und Auto-Deploy
- Repo-Backups: nachts um 04:00 werden alle Gitea-Repos als git-Bundle gesichert — eine Datei pro Repo mit kompletter Historie, aus der sich direkt wieder klonen lässt. 14 Tage Rotation wie beim DB-Backup, Schalter und "Repos jetzt sichern" im System-Tab. Nutzt den bereits vorhandenen Gitea-Token; Dockerfile installiert dafür git mit. - Gitea-Theme im D4RKST3R-Look (docs/gitea-theme/): Neon-Gelb/Orange auf Schwarz, gebaut gegen die Variablen von Gitea 1.26, Diff-Farben bleiben lesbar. Einbau-Anleitung liegt daneben. - Auto-Deploy statt manuellem "Pull and redeploy": Workflow für Gitea Actions (prüft Server-Syntax und Frontend-Build, bevor deployed wird) plus dokumentierter Runner-loser Weg über den Portainer-Webhook. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
# Auto-Deploy statt „Pull and redeploy"
|
||||
|
||||
Bisher: pushen, in Portainer einloggen, Stack suchen, *Pull and redeploy* klicken.
|
||||
Das geht automatisch — zwei Wege, je nachdem wie viel du willst.
|
||||
|
||||
## Weg 1: Portainer-Webhook (2 Minuten, kein Runner nötig) ← empfohlen
|
||||
|
||||
Portainer kann einen Stack per HTTP-Aufruf neu ausrollen. Gitea ruft diese
|
||||
Adresse nach jedem Push auf, fertig.
|
||||
|
||||
**In Portainer:**
|
||||
|
||||
1. Stack `ecobot` öffnen → Reiter **Editor**
|
||||
2. **Automatic updates** einschalten, Methode **Webhook**
|
||||
3. Die erzeugte Webhook-URL kopieren
|
||||
(Form: `https://portainer.../api/stacks/webhooks/<uuid>`)
|
||||
|
||||
**In Gitea:**
|
||||
|
||||
1. Repo `d4rkbot` → **Einstellungen → Webhooks → Webhook hinzufügen → Gitea**
|
||||
2. Ziel-URL: die kopierte Portainer-Adresse
|
||||
3. HTTP-Methode `POST`, Inhaltstyp `application/json`
|
||||
4. Trigger: **Push-Ereignisse**, Branch-Filter `main`
|
||||
5. Speichern, dann **Zustellung testen** — Portainer sollte den Stack neu bauen
|
||||
|
||||
> Der Stack muss aus dem Git-Repository deployed sein (nicht aus einem
|
||||
> hochgeladenen Compose-Text), damit Portainer den neuen Stand ziehen kann.
|
||||
> „Re-pull image" bleibt **aus** — das Image wird ja lokal gebaut.
|
||||
|
||||
## Weg 2: Gitea Actions (prüft den Code vor dem Deploy)
|
||||
|
||||
Der Workflow in `.gitea/workflows/deploy.yml` installiert die Abhängigkeiten,
|
||||
prüft alle Server-Dateien auf Syntaxfehler, baut das Frontend — und stößt erst
|
||||
dann das Redeploy an. Kaputter Code geht damit gar nicht erst live.
|
||||
|
||||
**Voraussetzung: ein Act-Runner.** In deiner Instanz sind Actions aktiviert,
|
||||
aber ohne Runner passiert nichts. Einrichten als zusätzlicher Container:
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml für den Runner
|
||||
services:
|
||||
runner:
|
||||
image: gitea/act_runner:latest
|
||||
restart: always
|
||||
environment:
|
||||
GITEA_INSTANCE_URL: https://git.d4rkst3r.de
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN: <Token aus Gitea>
|
||||
GITEA_RUNNER_NAME: d4rk-runner
|
||||
GITEA_RUNNER_LABELS: ubuntu-latest:docker://node:22-bookworm
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./runner-data:/data
|
||||
```
|
||||
|
||||
Den Registrierungs-Token findest du unter **Site-Administration → Actions →
|
||||
Runner → Runner erstellen** (oder pro Repo unter *Einstellungen → Actions*).
|
||||
|
||||
**Secret hinterlegen:** Repo → *Einstellungen → Actions → Secrets* →
|
||||
`PORTAINER_WEBHOOK` mit der Portainer-Adresse. Fehlt das Secret, läuft nur die
|
||||
Prüfung und der Deploy-Schritt wird übersprungen.
|
||||
|
||||
## Welchen nehmen?
|
||||
|
||||
| | Weg 1 (Webhook) | Weg 2 (Actions) |
|
||||
|---|---|---|
|
||||
| Aufwand | 2 Minuten | Runner-Container aufsetzen |
|
||||
| Prüft den Code | nein | ja (Syntax + Frontend-Build) |
|
||||
| Läuft ohne Zusatzdienst | ja | nein |
|
||||
|
||||
Fang mit Weg 1 an. Weg 2 lohnt sich, sobald du Tests hast oder mehrere Leute
|
||||
pushen — dann verhindert er, dass ein kaputter Stand live geht.
|
||||
@@ -0,0 +1,60 @@
|
||||
# D4RKST3R-Theme für Gitea
|
||||
|
||||
Färbt Gitea im Brand-Look ein — Neon-Gelb (`#f5c518`) und Orange (`#ff4d00`)
|
||||
auf Schwarz, passend zu `bot.d4rkst3r.de` und dem geteilten Design-System.
|
||||
|
||||
Gebaut gegen die Variablen von **Gitea 1.26**.
|
||||
|
||||
## Einbau
|
||||
|
||||
Die Datei muss in den `custom`-Ordner deiner Gitea-Instanz. Bei einer
|
||||
Docker-Installation ist das üblicherweise das gemountete Daten-Volume:
|
||||
|
||||
```bash
|
||||
# Pfad je nach Setup, im offiziellen Image liegt custom unter /data/gitea
|
||||
mkdir -p /data/gitea/public/assets/css
|
||||
cp theme-d4rkst3r.css /data/gitea/public/assets/css/
|
||||
```
|
||||
|
||||
Danach Gitea neu starten:
|
||||
|
||||
```bash
|
||||
docker restart gitea
|
||||
```
|
||||
|
||||
Ab Gitea 1.21 wird jede Datei `theme-*.css` in diesem Ordner automatisch als
|
||||
Theme erkannt. Auswählen kannst du es dann unter **Einstellungen → Aussehen**.
|
||||
|
||||
### Als Standard für alle setzen
|
||||
|
||||
In der `app.ini`:
|
||||
|
||||
```ini
|
||||
[ui]
|
||||
DEFAULT_THEME = d4rkst3r
|
||||
```
|
||||
|
||||
Wer schon ein Theme gewählt hat, behält seins — die Einstellung greift für
|
||||
neue Konten und alle, die nie umgestellt haben.
|
||||
|
||||
## Was das Theme ändert
|
||||
|
||||
* **Marke:** Primärfarbe Gelb statt Gitea-Blau, Orange als Akzent;
|
||||
Buttons bekommen dunklen Text für ordentlichen Kontrast
|
||||
* **Flächen:** durchgehend Schwarz (`#0a0a0a`) statt Dunkelgrau, Karten und
|
||||
Menüs eine Stufe heller
|
||||
* **Diffs:** Grün/Rot bleiben erhalten (Lesbarkeit geht vor Marke), nur
|
||||
dezenter hinterlegt
|
||||
* **Feinschliff:** aktiver Navigationspunkt glüht leicht, weichere Radien,
|
||||
Scrollbar wie im Bot-Webinterface
|
||||
|
||||
## Anpassen
|
||||
|
||||
Alle Farben stehen als CSS-Variablen oben in der Datei. Willst du eine andere
|
||||
Primärfarbe, reicht es, den `--color-primary`-Block zu ändern — die
|
||||
`dark-*`/`light-*`/`alpha-*`-Varianten solltest du dann mit anpassen, sonst
|
||||
wirken Hover- und Aktiv-Zustände schief.
|
||||
|
||||
> Bei einem Gitea-Update kann es passieren, dass neue Variablen dazukommen,
|
||||
> die das Theme noch nicht kennt. Dann erscheinen einzelne Elemente in den
|
||||
> Standardfarben — einfach die fehlende Variable hier ergänzen.
|
||||
@@ -0,0 +1,230 @@
|
||||
/* ═══════════════════════════════════════════════════
|
||||
D4RKST3R — Gitea-Theme
|
||||
Neon-Gelb/Orange auf Schwarz, passend zu bot.d4rkst3r.de
|
||||
|
||||
Einbau: custom/public/assets/css/theme-d4rkst3r.css
|
||||
danach Gitea neu starten und das Theme unter
|
||||
Einstellungen → Aussehen auswählen.
|
||||
═══════════════════════════════════════════════════ */
|
||||
|
||||
:root {
|
||||
/* ── Marke ───────────────────────────────────── */
|
||||
--color-primary: #f5c518;
|
||||
--color-primary-contrast: #0a0a0a; /* Text auf gelben Flächen */
|
||||
--color-primary-hover: #ffd633;
|
||||
--color-primary-active: #e0b40f;
|
||||
--color-primary-dark-1: #e0b40f;
|
||||
--color-primary-dark-2: #c9a20c;
|
||||
--color-primary-dark-3: #b28f0a;
|
||||
--color-primary-dark-4: #9b7c08;
|
||||
--color-primary-dark-5: #7d6406;
|
||||
--color-primary-dark-6: #5e4b05;
|
||||
--color-primary-dark-7: #3f3203;
|
||||
--color-primary-light-1: #f7cd35;
|
||||
--color-primary-light-2: #f9d552;
|
||||
--color-primary-light-3: #fadd6f;
|
||||
--color-primary-light-4: #fce58c;
|
||||
--color-primary-light-5: #fdeda9;
|
||||
--color-primary-light-6: #fef4c6;
|
||||
--color-primary-light-7: #fefae3;
|
||||
--color-primary-alpha-10: #f5c5181a;
|
||||
--color-primary-alpha-20: #f5c51833;
|
||||
--color-primary-alpha-30: #f5c5184d;
|
||||
--color-primary-alpha-40: #f5c51866;
|
||||
--color-primary-alpha-50: #f5c51880;
|
||||
--color-primary-alpha-60: #f5c51899;
|
||||
--color-primary-alpha-70: #f5c518b3;
|
||||
--color-primary-alpha-80: #f5c518cc;
|
||||
--color-primary-alpha-90: #f5c518e6;
|
||||
|
||||
/* Orange als Akzent (Links, Hervorhebungen) */
|
||||
--color-accent: #ff4d00;
|
||||
--color-small-accent: #ff4d0033;
|
||||
|
||||
/* ── Flächen ─────────────────────────────────── */
|
||||
--color-body: #0a0a0a;
|
||||
--color-box-body: #111111;
|
||||
--color-box-body-highlight: #161616;
|
||||
--color-box-header: #141414;
|
||||
--color-nav-bg: #0d0d0d;
|
||||
--color-nav-hover-bg: #1a1a1a;
|
||||
--color-header-wrapper: #0d0d0d;
|
||||
--color-footer: #0d0d0d;
|
||||
--color-menu: #111111;
|
||||
--color-card: #111111;
|
||||
--color-markup-code-block: #f5c5180f;
|
||||
--color-code-bg: #111111;
|
||||
--color-code-sidebar-bg: #141414;
|
||||
--color-console-bg: #0a0a0a;
|
||||
--color-console-fg: #e8e0d0;
|
||||
--color-console-fg-subtle: #8a8378;
|
||||
--color-console-border: #f5c51826;
|
||||
--color-console-hover-bg: #f5c5180f;
|
||||
--color-console-active-bg: #f5c51817;
|
||||
--color-console-menu-bg: #111111;
|
||||
--color-console-menu-border: #f5c51826;
|
||||
|
||||
/* ── Text ────────────────────────────────────── */
|
||||
--color-text: #e8e0d0;
|
||||
--color-text-dark: #ffffff;
|
||||
--color-text-light: #c9c2b4;
|
||||
--color-text-light-1: #a8a294;
|
||||
--color-text-light-2: #8a8378;
|
||||
--color-text-light-3: #6b665d;
|
||||
--color-placeholder-text: #6b665d;
|
||||
|
||||
/* ── Rahmen & Zustände ───────────────────────── */
|
||||
--color-secondary: #2a2a2a;
|
||||
--color-secondary-dark-1: #333333;
|
||||
--color-secondary-dark-2: #3d3d3d;
|
||||
--color-secondary-dark-3: #474747;
|
||||
--color-secondary-dark-4: #525252;
|
||||
--color-secondary-light-1: #232323;
|
||||
--color-secondary-light-2: #1c1c1c;
|
||||
--color-secondary-light-3: #161616;
|
||||
--color-secondary-light-4: #111111;
|
||||
--color-secondary-alpha-40: #2a2a2a66;
|
||||
--color-secondary-alpha-50: #2a2a2a80;
|
||||
--color-secondary-alpha-60: #2a2a2a99;
|
||||
--color-secondary-alpha-70: #2a2a2ab3;
|
||||
--color-secondary-alpha-80: #2a2a2acc;
|
||||
--color-secondary-alpha-90: #2a2a2ae6;
|
||||
--color-secondary-button: #f5c5181a;
|
||||
--color-secondary-hover: #f5c51826;
|
||||
--color-secondary-active: #f5c51833;
|
||||
|
||||
--color-light: #f5c5180d;
|
||||
--color-light-border: #f5c51826;
|
||||
--color-light-mimic-enabled: #f5c5181a;
|
||||
--color-hover: #f5c5180f;
|
||||
--color-active: #f5c51817;
|
||||
--color-input-background: #0f0f0f;
|
||||
--color-input-border: #2a2a2a;
|
||||
--color-input-border-hover: #f5c51866;
|
||||
--color-input-text: #e8e0d0;
|
||||
--color-input-toggle-background: #1a1a1a;
|
||||
--color-button: #161616;
|
||||
--color-caret: #f5c518;
|
||||
--color-shadow: #00000080;
|
||||
--color-shadow-opaque: #000000;
|
||||
--color-overlay-backdrop: #0a0a0acc;
|
||||
--color-border: #2a2a2a;
|
||||
|
||||
/* ── Status ──────────────────────────────────── */
|
||||
--color-red: #f23f43;
|
||||
--color-orange: #ff4d00;
|
||||
--color-yellow: #f5c518;
|
||||
--color-olive: #b7c62b;
|
||||
--color-green: #00c46a;
|
||||
--color-teal: #00b5ad;
|
||||
--color-blue: #4183c4;
|
||||
--color-violet: #8f6ed5;
|
||||
--color-purple: #a333c8;
|
||||
--color-pink: #e03997;
|
||||
--color-brown: #a5673f;
|
||||
--color-grey: #6b665d;
|
||||
--color-gold: #f5c518;
|
||||
|
||||
--color-success: #00c46a;
|
||||
--color-info: #4183c4;
|
||||
--color-warning: #ff4d00;
|
||||
--color-error: #f23f43;
|
||||
--color-danger: #f23f43;
|
||||
|
||||
--color-green-badge: #00c46a1a;
|
||||
--color-green-badge-bg: #00c46a26;
|
||||
--color-red-badge: #f23f431a;
|
||||
--color-red-badge-bg: #f23f4326;
|
||||
--color-yellow-badge: #f5c5181a;
|
||||
--color-yellow-badge-bg: #f5c51826;
|
||||
--color-orange-badge: #ff4d001a;
|
||||
--color-orange-badge-bg: #ff4d0026;
|
||||
|
||||
/* ── Diffs ───────────────────────────────────── */
|
||||
--color-diff-added-fg: #00c46a;
|
||||
--color-diff-added-row-bg: #00c46a12;
|
||||
--color-diff-added-row-border: #00c46a26;
|
||||
--color-diff-added-word-bg: #00c46a33;
|
||||
--color-diff-added-linenum-bg: #00c46a1a;
|
||||
--color-diff-removed-fg: #f23f43;
|
||||
--color-diff-removed-row-bg: #f23f4312;
|
||||
--color-diff-removed-row-border: #f23f4326;
|
||||
--color-diff-removed-word-bg: #f23f4333;
|
||||
--color-diff-removed-linenum-bg: #f23f431a;
|
||||
--color-diff-inactive: #111111;
|
||||
--color-diff-moved-row-bg: #f5c51812;
|
||||
--color-diff-moved-row-border: #f5c51826;
|
||||
|
||||
/* ── Sonstiges ───────────────────────────────── */
|
||||
--color-timeline: #2a2a2a;
|
||||
--color-editor-line-highlight: #f5c5180d;
|
||||
--color-project-column-bg: #111111;
|
||||
--color-reaction-bg: #f5c5181a;
|
||||
--color-reaction-hover-bg: #f5c51833;
|
||||
--color-reaction-active-bg: #f5c51826;
|
||||
--color-tooltip-bg: #1a1a1a;
|
||||
--color-tooltip-text: #e8e0d0;
|
||||
--color-nav-text: #c9c2b4;
|
||||
--color-label-text: #e8e0d0;
|
||||
--color-label-bg: #f5c5181a;
|
||||
--color-label-hover-bg: #f5c51833;
|
||||
--color-label-active-bg: #f5c51826;
|
||||
}
|
||||
|
||||
/* ── Feinschliff im D4RKST3R-Stil ─────────────────── */
|
||||
|
||||
/* Kopfleiste mit Neon-Kante */
|
||||
.page-content,
|
||||
#navbar {
|
||||
border-bottom-color: var(--color-light-border) !important;
|
||||
}
|
||||
#navbar {
|
||||
box-shadow: 0 1px 0 0 var(--color-primary-alpha-20);
|
||||
}
|
||||
|
||||
/* Aktive Navigation glüht leicht */
|
||||
#navbar .item.active {
|
||||
color: var(--color-primary) !important;
|
||||
text-shadow: 0 0 12px var(--color-primary-alpha-40);
|
||||
}
|
||||
|
||||
/* Primär-Buttons kräftiger */
|
||||
.ui.primary.button,
|
||||
.ui.primary.buttons .button {
|
||||
font-weight: 600;
|
||||
letter-spacing: .02em;
|
||||
}
|
||||
.ui.primary.button:hover {
|
||||
box-shadow: 0 0 16px var(--color-primary-alpha-30);
|
||||
}
|
||||
|
||||
/* Repo-Titel in Markenfarbe */
|
||||
.repository .header-wrapper .repo-title .name {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
/* Code-Blöcke abheben */
|
||||
.markup pre,
|
||||
.markup code {
|
||||
border: 1px solid var(--color-light-border);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
/* Weichere Radien wie im Rest der Plattform */
|
||||
.ui.segment,
|
||||
.ui.attached.segment,
|
||||
.ui.card,
|
||||
.repository .ui.segment,
|
||||
.ui.menu {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
/* Scrollbar passend zum Bot-Webinterface */
|
||||
::-webkit-scrollbar { width: 10px; height: 10px; }
|
||||
::-webkit-scrollbar-track { background: var(--color-body); }
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #262626;
|
||||
border: 2px solid var(--color-body);
|
||||
border-radius: 6px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover { background: var(--color-primary); }
|
||||
Reference in New Issue
Block a user