chore: simplify docker-only deployment workflow
This commit is contained in:
@@ -1,10 +1,4 @@
|
||||
.git
|
||||
.venv
|
||||
__pycache__
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
*.log
|
||||
build/
|
||||
*.ics
|
||||
*.pdf
|
||||
*
|
||||
!pdf_to_ics.py
|
||||
!web/
|
||||
!web/**
|
||||
|
||||
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/
|
||||
__pycache__/
|
||||
.pdf_to_ics_config.json
|
||||
.env
|
||||
.env.local
|
||||
|
||||
# Build artifacts
|
||||
dist/
|
||||
|
||||
@@ -8,7 +8,8 @@ WORKDIR /app
|
||||
COPY web/requirements-web.txt /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
|
||||
|
||||
|
||||
@@ -21,6 +21,74 @@ Danach im Browser öffnen:
|
||||
|
||||
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
|
||||
|
||||
```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:
|
||||
pdf-to-ics-web:
|
||||
build: .
|
||||
@@ -5,8 +12,17 @@ services:
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8000:8000"
|
||||
networks:
|
||||
- internal
|
||||
- proxy
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
# Optional aktivieren für App-Login:
|
||||
# - WEB_AUTH_USER=kalender
|
||||
# - WEB_AUTH_PASSWORD=BitteSicheresPasswortSetzen
|
||||
- WEB_AUTH_USER=dbregio
|
||||
- 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