feat: implement dynamic template system with auto-detection

**Backend (config.py):**
- Add dynamic template loading from USER_TEMPLATE_IMAGES (.env)
- Add template metadata loading from templates.json
- Implement automatic type extraction from image names
- Remove hardcoded template definitions (dev/prod)
- Maintain legacy USER_TEMPLATE_IMAGE for backward compatibility

**Configuration:**
- Add templates.json with metadata for template-01, template-02, template-next
- Update .env.example with new USER_TEMPLATE_IMAGES variable (semicolon-separated)
- Document automatic template type extraction

**Installation (install.sh):**
- Implement auto-detection for all user-template-* directories
- Replace hardcoded template builds with dynamic loop
- Calculate TOTAL_BUILDS dynamically
- Add special handling for Next.js templates

**Documentation:**
- Move MVP_DEPLOYMENT_GUIDE.md to docs/install/DEPLOYMENT_GUIDE.md
- Add "Dynamic Template System" section to CLAUDE.md
- Update docs/install/README.md with Quick Links and dynamic system info
- Add references to deployment guide in CLAUDE.md

**Templates:**
- Reorganize user-template/ → user-template-01/ (Nginx Basic)
- Add user-template-02/ (Nginx Advanced)
- Keep user-template-next/ unchanged

**Benefits:**
- Unlimited number of templates (no longer hardcoded to 2)
- Metadata-driven display in dashboard
- Automatic image discovery and building
- Extensible without code changes

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
XPS\Micro 2026-02-01 09:04:59 +01:00
parent 5cfad38b3c
commit 10b28179fc
14 changed files with 568 additions and 103 deletions

View File

@ -31,7 +31,7 @@ TRAEFIK_CERTRESOLVER=lets-encrypt
TRAEFIK_ENTRYPOINT=websecure TRAEFIK_ENTRYPOINT=websecure
# ============================================================ # ============================================================
# DOCKER - Normalerweise keine Aenderung noetig # DOCKER - Template-Konfiguration (Dynamisches System)
# ============================================================ # ============================================================
# Docker Socket Pfad (Standard fuer Linux) # Docker Socket Pfad (Standard fuer Linux)
@ -39,18 +39,25 @@ TRAEFIK_ENTRYPOINT=websecure
# Fuer TCP: tcp://localhost:2375 # Fuer TCP: tcp://localhost:2375
DOCKER_HOST=unix:///var/run/docker.sock DOCKER_HOST=unix:///var/run/docker.sock
# Docker-Image fuer User-Container (LEGACY - wird noch verwendet) # LEGACY Variable (wird noch für alte spawn_container() verwendet)
# Verfuegbare Templates: # Nutze diese nur für Fallback, nutze stattdessen USER_TEMPLATE_IMAGES
# - user-service-template:latest (nginx, einfache Willkommensseite) USER_TEMPLATE_IMAGE=user-template-01:latest
# - user-template-next:latest (Next.js, moderne React-App)
USER_TEMPLATE_IMAGE=user-service-template:latest
# Multi-Container Templates (MVP) # Dynamische Template-Liste (Semikolon-getrennt)
# Development Container Image # Format: image1:tag;image2:tag;image3:tag
USER_TEMPLATE_IMAGE_DEV=user-service-template:latest # Die Template-Metadaten (Namen, Beschreibungen) werden aus templates.json geladen
#
# Production Container Image (Next.js mit Shadcn/UI) # Beispiele:
USER_TEMPLATE_IMAGE_PROD=user-template-next:latest # - user-template-01:latest (Nginx Basic)
# - user-template-02:latest (Nginx Advanced)
# - user-template-next:latest (Next.js Production)
#
# WICHTIG:
# - Alle Images müssen gebaut sein (siehe install.sh)
# - Für Metadaten (Display-Namen, Beschreibungen) siehe templates.json
# - Container-Typen werden automatisch aus Image-Namen extrahiert
# Beispiel: user-template-01:latest → Typ: template-01
USER_TEMPLATE_IMAGES=user-template-01:latest;user-template-02:latest;user-template-next:latest
# ============================================================ # ============================================================
# RESSOURCEN - Container-Limits # RESSOURCEN - Container-Limits

105
config.py
View File

@ -1,4 +1,6 @@
import os import os
import json
from pathlib import Path
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv() load_dotenv()
@ -35,24 +37,97 @@ class Config:
SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_TRACK_MODIFICATIONS = False
# ======================================== # ========================================
# Docker-Konfiguration # Docker-Konfiguration - DYNAMISCHES TEMPLATE-SYSTEM
# ======================================== # ========================================
DOCKER_SOCKET = os.getenv('DOCKER_SOCKET', 'unix://var/run/docker.sock') DOCKER_SOCKET = os.getenv('DOCKER_SOCKET', 'unix://var/run/docker.sock')
USER_TEMPLATE_IMAGE = os.getenv('USER_TEMPLATE_IMAGE', 'user-service-template:latest')
# Multi-Container Templates # LEGACY: Wird noch für alte spawn_container() verwendet
CONTAINER_TEMPLATES = { USER_TEMPLATE_IMAGE = os.getenv('USER_TEMPLATE_IMAGE', 'user-template-01:latest')
'dev': {
'image': os.getenv('USER_TEMPLATE_IMAGE_DEV', 'user-service-template:latest'), # ========================================
'display_name': 'Development Container', # Dynamisches Template-Loading
'description': 'Nginx-basierter Development Container' # ========================================
},
'prod': { @staticmethod
'image': os.getenv('USER_TEMPLATE_IMAGE_PROD', 'user-template-next:latest'), def _extract_type_from_image(image_name: str) -> str:
'display_name': 'Production Container', """
'description': 'Next.js Production Build' Extrahiert Container-Typ aus Image-Namen
}
} Examples:
'user-template-01:latest' 'template-01'
'user-template-next:latest' 'template-next'
'custom-nginx:v1.0' 'custom-nginx'
"""
# Entferne Tag (:latest, :v1.0, etc.)
base_name = image_name.split(':')[0]
# Entferne 'user-' Prefix falls vorhanden
if base_name.startswith('user-'):
base_name = base_name[5:] # 'user-template-01' → 'template-01'
return base_name
@staticmethod
def _load_template_images() -> list:
"""Lädt Template-Image-Liste aus USER_TEMPLATE_IMAGES (semikolon-getrennt)"""
raw_images = os.getenv('USER_TEMPLATE_IMAGES', '')
if not raw_images:
# Fallback für Kompatibilität
return ['user-template-01:latest']
return [img.strip() for img in raw_images.split(';') if img.strip()]
@staticmethod
def _load_templates_config() -> dict:
"""Lädt Template-Konfiguration aus templates.json"""
config_path = Path(__file__).parent / 'templates.json'
if not config_path.exists():
return {}
try:
with open(config_path, 'r', encoding='utf-8') as f:
data = json.load(f)
# Konvertiere Array zu Dictionary (key=type)
return {
template['type']: template
for template in data.get('templates', [])
}
except (json.JSONDecodeError, KeyError) as e:
import sys
print(f"[CONFIG] Warnung: Fehler beim Laden von templates.json: {e}", file=sys.stderr)
return {}
@staticmethod
def _build_container_templates() -> dict:
"""
Baut CONTAINER_TEMPLATES Dictionary aus:
1. TEMPLATE_IMAGES (Liste der verfügbaren Images)
2. TEMPLATES_CONFIG (Metadaten aus templates.json)
"""
templates = {}
for image in Config.TEMPLATE_IMAGES:
# Extrahiere Typ aus Image-Namen
container_type = Config._extract_type_from_image(image)
# Hole Metadaten aus JSON (falls vorhanden)
config = Config.TEMPLATES_CONFIG.get(container_type, {})
# Verwende JSON-Metadaten oder Fallback
templates[container_type] = {
'image': image,
'display_name': config.get('display_name', container_type.replace('-', ' ').title()),
'description': config.get('description', f'Container basierend auf {image}')
}
return templates
# Dynamisches Template-Loading initialisieren
TEMPLATE_IMAGES = _load_template_images.__func__()
TEMPLATES_CONFIG = _load_templates_config.__func__()
CONTAINER_TEMPLATES = _build_container_templates.__func__()
# ======================================== # ========================================
# Traefik/Domain-Konfiguration # Traefik/Domain-Konfiguration

View File

@ -1,12 +1,17 @@
# Multi-Container MVP - Deployment Guide # Container Spawner - Deployment Guide
## 🎯 Überblick ## 🎯 Überblick
Das Multi-Container MVP implementiert Unterstützung für 2 Container-Typen pro User: Das System unterstützt **beliebig viele User-Templates** über ein dynamisches Konfigurationssystem:
- **Development (dev)**: Nginx mit einfacher Willkommensseite - Templates werden in `.env` definiert (semikolon-getrennt)
- **Production (prod)**: Next.js mit Shadcn/UI - Metadaten (Namen, Beschreibungen) kommen aus `templates.json`
- `install.sh` baut automatisch alle `user-template-*` Verzeichnisse
- Jeder Benutzer kann beliebig viele Container verschiedener Typen erstellen
Jeder Benutzer kann beide Container independent verwalten über das Dashboard. **Standardtemplates (können beliebig erweitert werden):**
- **template-01**: Nginx Basic - Einfacher Nginx-Server mit statischen Dateien
- **template-02**: Nginx Advanced - Nginx mit erweiterten Features
- **template-next**: Next.js Production - React-App mit Shadcn/UI
--- ---
@ -40,23 +45,22 @@ rm -f spawner.db
rm -rf logs/* rm -rf logs/*
``` ```
#### 1.3 Template-Images bauen #### 1.3 Templates werden automatisch gebaut!
```bash ```bash
# Development Template (Nginx) # install.sh erkennt AUTOMATISCH alle user-template-* Verzeichnisse und baut sie:
docker build -t user-service-template:latest user-template/ # - user-template-01/
# - user-template-02/
# - user-template-next/
# etc.
# Production Template (Next.js) # Überprüfung der verfügbaren Template-Verzeichnisse:
docker build -t user-template-next:latest user-template-next/ ls -d user-template*
# Überprüfung # Expected output:
docker images | grep user- # user-template-01 user-template-02 user-template-next
``` ```
**Erwartet Output:** **WICHTIG:** Das `install.sh`-Script baut automatisch alle Templates - **keine manuellen Docker-Builds nötig**!
```
user-service-template latest abc123... 5 minutes ago 100MB
user-template-next latest def456... 3 minutes ago 250MB
```
#### 1.4 Environment konfigurieren #### 1.4 Environment konfigurieren
```bash ```bash
@ -69,7 +73,7 @@ nano .env
**Erforderliche Änderungen in .env:** **Erforderliche Änderungen in .env:**
```bash ```bash
# Neue Zeilen hinzufügen oder bestehende aktualisieren: # Pflichtfelder
SECRET_KEY=<generiert mit: python3 -c "import secrets; print(secrets.token_hex(32))"> SECRET_KEY=<generiert mit: python3 -c "import secrets; print(secrets.token_hex(32))">
BASE_DOMAIN=yourdomain.com BASE_DOMAIN=yourdomain.com
SPAWNER_SUBDOMAIN=coder SPAWNER_SUBDOMAIN=coder
@ -77,9 +81,10 @@ TRAEFIK_NETWORK=web
TRAEFIK_CERTRESOLVER=lets-encrypt TRAEFIK_CERTRESOLVER=lets-encrypt
TRAEFIK_ENTRYPOINT=websecure TRAEFIK_ENTRYPOINT=websecure
# Multi-Container Templates (NEU!) # Dynamische Template-Konfiguration (Semikolon-getrennt)
USER_TEMPLATE_IMAGE_DEV=user-service-template:latest # Liste aller verfügbaren Container-Images
USER_TEMPLATE_IMAGE_PROD=user-template-next:latest # Metadaten (Namen, Beschreibungen) werden aus templates.json geladen
USER_TEMPLATE_IMAGES=user-template-01:latest;user-template-02:latest;user-template-next:latest
# Optional: SMTP für Magic Links # Optional: SMTP für Magic Links
SMTP_HOST=smtp.example.com SMTP_HOST=smtp.example.com
@ -90,6 +95,8 @@ SMTP_FROM=noreply@example.com
FRONTEND_URL=https://coder.yourdomain.com FRONTEND_URL=https://coder.yourdomain.com
``` ```
**Hinweis:** Behalte alle anderen Einstellungen aus `.env.example` (CORS, JWT, etc.)
### Phase 2: Services starten (10 Minuten) ### Phase 2: Services starten (10 Minuten)
#### 2.1 Docker Compose starten #### 2.1 Docker Compose starten
@ -153,8 +160,10 @@ https://coder.yourdomain.com
6. Du wirst zum Dashboard weitergeleitet 6. Du wirst zum Dashboard weitergeleitet
#### 3.3 Dashboard überprüfen #### 3.3 Dashboard überprüfen
- [ ] 2 Container-Cards sichtbar (Dev und Prod) - [ ] N Container-Cards sichtbar (entsprechend USER_TEMPLATE_IMAGES)
- [ ] Beide haben Status "Noch nicht erstellt" - Standardmäßig: template-01, template-02, template-next
- [ ] Alle haben Status "Noch nicht erstellt"
- [ ] Jede Card zeigt Display-Namen und Beschreibung aus `templates.json`
- [ ] Buttons zeigen "Erstellen & Öffnen" - [ ] Buttons zeigen "Erstellen & Öffnen"
### Phase 4: Teste beide Container (10 Minuten) ### Phase 4: Teste beide Container (10 Minuten)
@ -506,5 +515,5 @@ EOF
**Version**: 1.0.0 (MVP) **Version**: 1.0.0 (MVP)
**Deployment Date**: 2025-01-31 **Deployment Date**: 2025-01-31
**Last Updated**: 2025-01-31 **Last Updated**: 2025-02-01
**Status**: ✅ Ready for Production **Status**: ✅ Ready for Production

View File

@ -2,8 +2,18 @@
Anleitung zur Installation und Aktualisierung des Container Spawner. Anleitung zur Installation und Aktualisierung des Container Spawner.
## 🚀 Quick Links
- **[📋 Deployment Guide](./DEPLOYMENT_GUIDE.md)** - Vollständige Step-by-Step Anleitung für Deployment
- Phase 1: Vorbereitung (Daten bereinigen, Environment konfigurieren)
- Phase 2: Services starten
- Phase 3: Erste Registrierung
- Phase 4: Testing
- Troubleshooting, Monitoring, Security Checklist
## Inhaltsverzeichnis ## Inhaltsverzeichnis
- [Quick Links](#quick-links)
- [Voraussetzungen](#voraussetzungen) - [Voraussetzungen](#voraussetzungen)
- [Neuinstallation](#neuinstallation) - [Neuinstallation](#neuinstallation)
- [Update/Upgrade](#updateupgrade) - [Update/Upgrade](#updateupgrade)
@ -183,21 +193,39 @@ docker-compose up -d
**Hinweis**: Die Email-Konfiguration wird fuer die Email-Verifizierung bei der Registrierung und fuer Passwort-Reset-Emails benoetigt. **Hinweis**: Die Email-Konfiguration wird fuer die Email-Verifizierung bei der Registrierung und fuer Passwort-Reset-Emails benoetigt.
### User-Templates ### User-Templates (Dynamisches System)
Es stehen zwei Templates fuer User-Container zur Verfuegung: Das System unterstützt **beliebig viele User-Templates** durch ein dynamisches Konfigurationssystem:
**Verfügbare Standard-Templates:**
| Image | Verzeichnis | Beschreibung | | Image | Verzeichnis | Beschreibung |
|-------|-------------|--------------| |-------|-------------|--------------|
| `user-service-template:latest` | `user-template/` | Einfache nginx-Willkommensseite (Standard) | | `user-template-01:latest` | `user-template-01/` | Nginx Basic - Einfacher Nginx-Server |
| `user-template-next:latest` | `user-template-next/` | Moderne Next.js React-Anwendung | | `user-template-02:latest` | `user-template-02/` | Nginx Advanced - Nginx mit erweiterten Features |
| `user-template-next:latest` | `user-template-next/` | Next.js Production - React-App mit Shadcn/UI |
Um ein anderes Template zu verwenden, aendere `USER_TEMPLATE_IMAGE` in `.env`: **Konfiguration:**
Templates werden in `.env` als semikolon-getrennte Liste definiert:
```bash ```bash
USER_TEMPLATE_IMAGE=user-template-next:latest USER_TEMPLATE_IMAGES=user-template-01:latest;user-template-02:latest;user-template-next:latest
``` ```
**Automatisches Bauen:**
Das `install.sh` Script erkennt automatisch alle `user-template-*` Verzeichnisse und baut sie.
**Neues Template hinzufügen:**
1. Erstelle `user-template-xyz/Dockerfile`
2. Füge zu `.env` ein: `USER_TEMPLATE_IMAGES=...;user-template-xyz:latest`
3. Füge Metadaten zu `templates.json` ein
4. Führe `bash install.sh` aus
Siehe auch: [CLAUDE.md - Dynamisches Template-System](../../CLAUDE.md#dynamisches-template-system)
### Produktions-Variablen ### Produktions-Variablen
| Variable | Beschreibung | | Variable | Beschreibung |

View File

@ -375,81 +375,75 @@ fi
# 7. Docker-Images bauen # 7. Docker-Images bauen
# ============================================================ # ============================================================
echo "" echo ""
echo "Baue Docker-Images fuer Multi-Container MVP..." echo "Baue Docker-Images (Dynamisches Template-System)..."
echo " - user-service-template (Development)"
echo " - user-template-next (Production)"
echo " - spawner-api (Backend)"
echo " - spawner-frontend (Frontend)"
echo "" echo ""
# Stoppe laufende Container # Stoppe laufende Container
${COMPOSE_CMD} down 2>/dev/null || true ${COMPOSE_CMD} down 2>/dev/null || true
# Zaehle aktive Builds fuer Fortschrittsanzeige # Zähle Templates für Fortschrittsanzeige
TEMPLATE_DIRS=$(find "${INSTALL_DIR}" -maxdepth 1 -type d -name "user-template*" 2>/dev/null | wc -l)
TOTAL_BUILDS=$((2 + TEMPLATE_DIRS)) # spawner-api + frontend + templates
BUILD_STEP=1 BUILD_STEP=1
TOTAL_BUILDS=3 # user-service-template + spawner-api + frontend
# Multi-Container Support: Baue auch user-template-next wenn Verzeichnis existiert # Auto-detect und baue alle user-template-* Verzeichnisse
[ -d "${INSTALL_DIR}/user-template-next" ] && TOTAL_BUILDS=$((TOTAL_BUILDS + 1)) echo " Auto-Detecting Template-Verzeichnisse..."
BUILT_TEMPLATES=0
for template_dir in "${INSTALL_DIR}"/user-template*; do
# Prüfe ob Verzeichnis existiert
[ -d "$template_dir" ] || continue
# Extrahiere Template-Namen (z.B. user-template-01)
template_name=$(basename "$template_dir")
# Image-Name = Verzeichnis-Name + :latest
image_name="${template_name}:latest"
echo " [$BUILD_STEP/$TOTAL_BUILDS] Baue ${template_name}..."
# Special handling für Next.js Templates (längere Build-Zeit)
if [[ "$template_name" == *"next"* ]]; then
echo -e " ${BLUE}Dies kann 2-5 Minuten dauern (npm install + build)...${NC}"
fi
# User-Template Image bauen (fuer User-Container)
if [ -d "${INSTALL_DIR}/user-template" ]; then
echo " [$BUILD_STEP/$TOTAL_BUILDS] Baue user-service-template (User-Container)..."
echo "" echo ""
# Build ausfuehren und Output in Datei speichern
BUILD_LOG="${LOG_FILE}" BUILD_LOG="${LOG_FILE}"
echo "" >> "${LOG_FILE}" echo "" >> "${LOG_FILE}"
echo "=== Build: user-service-template ===" >> "${LOG_FILE}" echo "=== Build: ${template_name} ===" >> "${LOG_FILE}"
docker build --no-cache -t user-service-template:latest "${INSTALL_DIR}/user-template/" >> "${BUILD_LOG}" 2>&1
docker build --no-cache -t "${image_name}" "${template_dir}/" >> "${BUILD_LOG}" 2>&1
BUILD_EXIT=$? BUILD_EXIT=$?
# Gefilterten Output anzeigen # Gefilterten Output anzeigen
grep -E "(Step |#[0-9]+ |Successfully|ERROR|error:|COPY|RUN|FROM)" "${BUILD_LOG}" 2>/dev/null | sed 's/^/ /' || true grep -E "(Step |#[0-9]+ |Successfully|ERROR|error:|COPY|RUN|FROM)" "${BUILD_LOG}" 2>/dev/null | sed 's/^/ /' || true
# Pruefe ob Build erfolgreich UND Image existiert # Pruefe ob Build erfolgreich UND Image existiert
if [ $BUILD_EXIT -eq 0 ] && docker image inspect user-service-template:latest >/dev/null 2>&1; then if [ $BUILD_EXIT -eq 0 ] && docker image inspect "${image_name}" >/dev/null 2>&1; then
echo "" echo ""
echo -e " user-service-template: ${GREEN}OK${NC}" echo -e " ${template_name}: ${GREEN}OK${NC}"
BUILT_TEMPLATES=$((BUILT_TEMPLATES + 1))
else else
echo "" echo ""
echo -e " user-service-template: ${RED}FEHLER${NC}" echo -e " ${template_name}: ${RED}FEHLER${NC}"
echo " Siehe Build-Log: ${LOG_FILE}" echo " Siehe Build-Log: ${LOG_FILE}"
echo " Letzte 50 Zeilen:" echo " Letzte 50 Zeilen:"
tail -50 "${BUILD_LOG}" tail -50 "${BUILD_LOG}"
exit 1 exit 1
fi fi
BUILD_STEP=$((BUILD_STEP + 1)) BUILD_STEP=$((BUILD_STEP + 1))
done
if [ $BUILT_TEMPLATES -eq 0 ]; then
echo -e "${RED}FEHLER: Keine Template-Verzeichnisse gefunden!${NC}"
echo "Erwartete Verzeichnisse: user-template*, z.B. user-template-01, user-template-next"
exit 1
fi fi
# User-Template-Next Image bauen (Production Template fuer Multi-Container MVP) echo ""
# Wird automatisch gebaut wenn Verzeichnis existiert echo -e "${GREEN}Alle ${BUILT_TEMPLATES} Template(s) erfolgreich gebaut.${NC}"
if [ -d "${INSTALL_DIR}/user-template-next" ]; then
echo " [$BUILD_STEP/$TOTAL_BUILDS] Baue user-template-next (Next.js Template - Production)..."
echo -e " ${BLUE}Dies kann 2-5 Minuten dauern (npm install + build)...${NC}"
echo ""
BUILD_LOG="${LOG_FILE}"
echo "" >> "${LOG_FILE}"
echo "=== Build: user-template-next ===" >> "${LOG_FILE}"
docker build --no-cache -t user-template-next:latest "${INSTALL_DIR}/user-template-next/" >> "${BUILD_LOG}" 2>&1
BUILD_EXIT=$?
grep -E "(Step |#[0-9]+ |Successfully|ERROR|error:|COPY|RUN|FROM)" "${BUILD_LOG}" 2>/dev/null | sed 's/^/ /' || true
if [ $BUILD_EXIT -eq 0 ] && docker image inspect user-template-next:latest >/dev/null 2>&1; then
echo ""
echo -e " user-template-next: ${GREEN}OK${NC}"
else
echo ""
echo -e " user-template-next: ${RED}FEHLER${NC}"
echo " Siehe Build-Log: ${LOG_FILE}"
echo " Letzte 50 Zeilen:"
tail -50 "${BUILD_LOG}"
exit 1
fi
BUILD_STEP=$((BUILD_STEP + 1))
fi
# Spawner Backend Image bauen # Spawner Backend Image bauen
echo " [$BUILD_STEP/$TOTAL_BUILDS] Baue Spawner API (Flask Backend)..." echo " [$BUILD_STEP/$TOTAL_BUILDS] Baue Spawner API (Flask Backend)..."

22
templates.json Normal file
View File

@ -0,0 +1,22 @@
{
"templates": [
{
"type": "template-01",
"image": "user-template-01:latest",
"display_name": "Nginx Basic",
"description": "Einfacher Nginx-Server mit statischen Dateien und Willkommensseite"
},
{
"type": "template-02",
"image": "user-template-02:latest",
"display_name": "Nginx Advanced",
"description": "Nginx mit erweiterten Features und Konfigurationen"
},
{
"type": "template-next",
"image": "user-template-next:latest",
"display_name": "Next.js Production",
"description": "React-Anwendung mit Shadcn/UI, TypeScript und modernem Build-Setup"
}
]
}

View File

@ -0,0 +1,23 @@
FROM nginxinc/nginx-unprivileged:alpine
# Wechsel zu root um Pakete zu installieren
USER root
# gettext für envsubst installieren
RUN apk add --no-cache gettext
# HTML-Template kopieren
COPY index.html /usr/share/nginx/html/index.html.template
# Nginx-Konfiguration kopieren
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Entrypoint Script kopieren und executable machen
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh && \
chmod 777 /usr/share/nginx/html
EXPOSE 8080
# Entrypoint Script starten (läuft als root, startet Nginx)
ENTRYPOINT ["/entrypoint.sh"]

View File

@ -0,0 +1,8 @@
#!/bin/sh
set -e
# Umgebungsvariablen in die HTML-Datei einfügen
envsubst < /usr/share/nginx/html/index.html.template > /usr/share/nginx/html/index.html
# Nginx starten
exec nginx -g "daemon off;"

284
user-template-02/index.html Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,15 @@
server {
listen 8080;
server_name _;
# Root-Verzeichnis
root /usr/share/nginx/html;
# Alle Anfragen einfach auf root Location
location / {
try_files $uri $uri/ /index.html;
}
# Error pages
error_page 404 /index.html;
}