chore: simplify docker-only deployment workflow
This commit is contained in:
@@ -1,10 +1,4 @@
|
|||||||
.git
|
*
|
||||||
.venv
|
!pdf_to_ics.py
|
||||||
__pycache__
|
!web/
|
||||||
*.pyc
|
!web/**
|
||||||
*.pyo
|
|
||||||
*.pyd
|
|
||||||
*.log
|
|
||||||
build/
|
|
||||||
*.ics
|
|
||||||
*.pdf
|
|
||||||
|
|||||||
10
.env.example
Normal file
10
.env.example
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Docker-only Deployment Konfiguration
|
||||||
|
# Kopieren nach .env und Werte anpassen:
|
||||||
|
# cp .env.example .env
|
||||||
|
|
||||||
|
# Container-Image mit festem Release-Tag (kein latest)
|
||||||
|
PDF_TO_ICS_IMAGE=ghcr.io/webfarben/pdf_to_ics:v1.0.0
|
||||||
|
|
||||||
|
# Optional: App-interne Basic Auth (leer = deaktiviert)
|
||||||
|
WEB_AUTH_USER=
|
||||||
|
WEB_AUTH_PASSWORD=
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,6 +3,8 @@
|
|||||||
.venv/
|
.venv/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
.pdf_to_ics_config.json
|
.pdf_to_ics_config.json
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
|
||||||
# Build artifacts
|
# Build artifacts
|
||||||
dist/
|
dist/
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ WORKDIR /app
|
|||||||
COPY web/requirements-web.txt /app/web/requirements-web.txt
|
COPY web/requirements-web.txt /app/web/requirements-web.txt
|
||||||
RUN pip install --no-cache-dir -r /app/web/requirements-web.txt
|
RUN pip install --no-cache-dir -r /app/web/requirements-web.txt
|
||||||
|
|
||||||
COPY . /app
|
COPY pdf_to_ics.py /app/pdf_to_ics.py
|
||||||
|
COPY web /app/web
|
||||||
|
|
||||||
EXPOSE 8000
|
EXPOSE 8000
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,74 @@ Danach im Browser öffnen:
|
|||||||
|
|
||||||
Diese Variante ist für deinen aktuellen Wunsch geeignet: öffentlich erreichbar ohne VPN.
|
Diese Variante ist für deinen aktuellen Wunsch geeignet: öffentlich erreichbar ohne VPN.
|
||||||
|
|
||||||
|
### Docker-only Betrieb (empfohlen für Webserver)
|
||||||
|
|
||||||
|
Wenn auf dem Webserver **nur Docker laufen soll**, nutze die image-basierte Compose-Datei statt lokalem Build.
|
||||||
|
|
||||||
|
1) Vorlage übernehmen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
2) Optional Werte in `.env` anpassen:
|
||||||
|
|
||||||
|
```dotenv
|
||||||
|
PDF_TO_ICS_IMAGE=ghcr.io/webfarben/pdf_to_ics:v1.0.0
|
||||||
|
WEB_AUTH_USER=
|
||||||
|
WEB_AUTH_PASSWORD=
|
||||||
|
```
|
||||||
|
|
||||||
|
3) Starten:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f docker-compose.deploy.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Kurzvariante für Erststart:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./deploy.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
4) Update:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git pull
|
||||||
|
# in .env auf neues Release setzen, z. B. v1.1.0
|
||||||
|
docker compose -f docker-compose.deploy.yml pull
|
||||||
|
docker compose -f docker-compose.deploy.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Kurzvariante mit Helper-Skript:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./update.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Hinweis: Für ein neues Release vorher den Tag in `.env` anpassen.
|
||||||
|
|
||||||
|
Damit entfallen lokale Python/venv-Abhängigkeiten auf dem Host vollständig.
|
||||||
|
Mit festem Tag bleiben Deployments reproduzierbar und Updates kontrolliert.
|
||||||
|
|
||||||
|
### Schlanker Checkout auf dem Server (Sparse)
|
||||||
|
|
||||||
|
Für einen neuen Server-Checkout kannst du den Arbeitsbaum klein halten:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone --filter=blob:none --sparse <REPO_URL> pdf_to_ics
|
||||||
|
cd pdf_to_ics
|
||||||
|
git sparse-checkout set docker-compose.deploy.yml .env.example deploy.sh update.sh WEB_README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Optional zusätzlich aufnehmen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git sparse-checkout add README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Hinweis: Ein bestehender Voll-Clone wird dadurch nicht automatisch klein; dafür einmal neu klonen.
|
||||||
|
|
||||||
### 1) Starten
|
### 1) Starten
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
41
deploy.sh
Executable file
41
deploy.sh
Executable file
@@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
cd "$SCRIPT_DIR"
|
||||||
|
|
||||||
|
COMPOSE_FILE="docker-compose.deploy.yml"
|
||||||
|
|
||||||
|
if ! command -v docker >/dev/null 2>&1; then
|
||||||
|
echo "❌ Fehler: docker ist nicht installiert oder nicht im PATH."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! docker compose version >/dev/null 2>&1; then
|
||||||
|
echo "❌ Fehler: docker compose ist nicht verfügbar."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$COMPOSE_FILE" ]; then
|
||||||
|
echo "❌ Fehler: $COMPOSE_FILE nicht gefunden."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f ".env" ]; then
|
||||||
|
if [ -f ".env.example" ]; then
|
||||||
|
cp .env.example .env
|
||||||
|
echo "ℹ️ .env wurde aus .env.example erstellt. Bitte Werte prüfen."
|
||||||
|
else
|
||||||
|
echo "❌ Fehler: .env fehlt und keine .env.example vorhanden."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "⬇️ Lade Container-Image..."
|
||||||
|
docker compose -f "$COMPOSE_FILE" pull
|
||||||
|
|
||||||
|
echo "🚀 Starte Container..."
|
||||||
|
docker compose -f "$COMPOSE_FILE" up -d
|
||||||
|
|
||||||
|
echo "✅ Deployment abgeschlossen."
|
||||||
|
docker compose -f "$COMPOSE_FILE" ps
|
||||||
25
docker-compose.deploy.yml
Normal file
25
docker-compose.deploy.yml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
name: proxy
|
||||||
|
external: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
pdf-to-ics-web:
|
||||||
|
image: ${PDF_TO_ICS_IMAGE:-ghcr.io/webfarben/pdf_to_ics:latest}
|
||||||
|
container_name: pdf-to-ics-web
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Berlin
|
||||||
|
# Optional aktivieren für App-Login:
|
||||||
|
- WEB_AUTH_USER=${WEB_AUTH_USER:-}
|
||||||
|
- WEB_AUTH_PASSWORD=${WEB_AUTH_PASSWORD:-}
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "python3", "-c", "import http.client,sys;c=http.client.HTTPConnection('127.0.0.1',8000,timeout=5);c.request('GET','/');r=c.getresponse();sys.exit(0 if r.status in (200,401) else 1)"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
@@ -1,3 +1,10 @@
|
|||||||
|
networks:
|
||||||
|
internal:
|
||||||
|
external: false
|
||||||
|
proxy:
|
||||||
|
name: proxy
|
||||||
|
external: true
|
||||||
|
|
||||||
services:
|
services:
|
||||||
pdf-to-ics-web:
|
pdf-to-ics-web:
|
||||||
build: .
|
build: .
|
||||||
@@ -5,8 +12,17 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
- proxy
|
||||||
environment:
|
environment:
|
||||||
- TZ=Europe/Berlin
|
- TZ=Europe/Berlin
|
||||||
# Optional aktivieren für App-Login:
|
# Optional aktivieren für App-Login:
|
||||||
# - WEB_AUTH_USER=kalender
|
- WEB_AUTH_USER=dbregio
|
||||||
# - WEB_AUTH_PASSWORD=BitteSicheresPasswortSetzen
|
- WEB_AUTH_PASSWORD=dbregio
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "python3", "-c", "import http.client,sys;c=http.client.HTTPConnection('127.0.0.1',8000,timeout=5);c.request('GET','/');r=c.getresponse();sys.exit(0 if r.status in (200,401) else 1)"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
|||||||
44
update.sh
Executable file
44
update.sh
Executable file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
cd "$SCRIPT_DIR"
|
||||||
|
|
||||||
|
COMPOSE_FILE="docker-compose.deploy.yml"
|
||||||
|
|
||||||
|
if ! command -v docker >/dev/null 2>&1; then
|
||||||
|
echo "❌ Fehler: docker ist nicht installiert oder nicht im PATH."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! docker compose version >/dev/null 2>&1; then
|
||||||
|
echo "❌ Fehler: docker compose ist nicht verfügbar."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$COMPOSE_FILE" ]; then
|
||||||
|
echo "❌ Fehler: $COMPOSE_FILE nicht gefunden."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f ".env" ]; then
|
||||||
|
if [ -f ".env.example" ]; then
|
||||||
|
cp .env.example .env
|
||||||
|
echo "ℹ️ .env wurde aus .env.example erstellt. Bitte Werte prüfen."
|
||||||
|
else
|
||||||
|
echo "❌ Fehler: .env fehlt und keine .env.example vorhanden."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "📥 Hole aktuelle Git-Änderungen..."
|
||||||
|
git pull --ff-only
|
||||||
|
|
||||||
|
echo "⬇️ Lade aktuelles Container-Image..."
|
||||||
|
docker compose -f "$COMPOSE_FILE" pull
|
||||||
|
|
||||||
|
echo "🚀 Starte/aktualisiere Container..."
|
||||||
|
docker compose -f "$COMPOSE_FILE" up -d
|
||||||
|
|
||||||
|
echo "✅ Update abgeschlossen."
|
||||||
|
docker compose -f "$COMPOSE_FILE" ps
|
||||||
Reference in New Issue
Block a user