feat: implement .env-based template building for install.sh

- Read USER_TEMPLATE_IMAGES from .env to determine which templates to build
- Parse semicolon-separated template list and extract image names with tags
- Only build templates defined in .env, not all user-template-* directories
- Validate that template directories and Dockerfiles exist
- Warn when template is defined but directory/Dockerfile missing
- Warn about unused template directories not in USER_TEMPLATE_IMAGES
- Fallback to old logic (build all) when USER_TEMPLATE_IMAGES undefined
- Maintains backward compatibility with existing installations
- Improves .env.example with better documentation and examples
This commit is contained in:
XPS\Micro 2026-02-02 16:40:45 +01:00
parent 57b6cf1068
commit 691c93292b
2 changed files with 193 additions and 57 deletions

View File

@ -45,19 +45,27 @@ USER_TEMPLATE_IMAGE=user-template-01:latest
# Dynamische Template-Liste (Semikolon-getrennt)
# Format: image1:tag;image2:tag;image3:tag
# Die Template-Metadaten (Namen, Beschreibungen) werden aus templates.json geladen
#
# Beispiele:
# - user-template-01:latest (Nginx Basic)
# - user-template-02:latest (Nginx Advanced)
# - user-template-next:latest (Next.js Production)
# WICHTIG: Diese Variable steuert, welche Templates beim 'bash install.sh' gebaut werden!
# - Nur hier definierte Templates werden gebaut
# - Entsprechende Verzeichnisse (user-template-01/, etc.) müssen existieren
# - Die Template-Metadaten (Namen, Beschreibungen) werden aus templates.json geladen
#
# WICHTIG:
# - Alle Images müssen gebaut sein (siehe install.sh)
# - Für Metadaten (Display-Namen, Beschreibungen) siehe templates.json
# Verfügbare Templates (Beispiele):
# - user-template-01:latest (Nginx Basic - Verzeichnis: user-template-01/)
# - user-template-02:latest (Nginx Advanced - Verzeichnis: user-template-02/)
# - user-template-next:latest (Next.js Production - Verzeichnis: user-template-next/)
#
# Tipps:
# - Container-Typen werden automatisch aus Image-Namen extrahiert
# Beispiel: user-template-01:latest → Typ: template-01
# - ANFÜHRUNGSZEICHEN WICHTIG: Variable muss quoted sein!
# - Falls .env fehlt, nutzt install.sh .env.example als Fallback
#
# Beispiele für Anpassungen:
# - Nur Nginx: "user-template-01:latest"
# - Mit Next.js: "user-template-01:latest;user-template-next:latest"
# - Alle: "user-template-01:latest;user-template-02:latest;user-template-next:latest"
USER_TEMPLATE_IMAGES="user-template-01:latest;user-template-02:latest;user-template-next:latest"
# ============================================================

View File

@ -381,45 +381,51 @@ echo ""
# Stoppe laufende Container
${COMPOSE_CMD} down 2>/dev/null || true
# 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
# Lese USER_TEMPLATE_IMAGES aus .env
USER_TEMPLATE_IMAGES=""
if [ -f "${INSTALL_DIR}/.env" ]; then
# Extrahiere USER_TEMPLATE_IMAGES (mit oder ohne Quotes)
USER_TEMPLATE_IMAGES=$(grep "^USER_TEMPLATE_IMAGES=" "${INSTALL_DIR}/.env" | cut -d'=' -f2- | tr -d '"' | tr -d "'")
fi
# Auto-detect und baue alle user-template-* Verzeichnisse
echo " Auto-Detecting Template-Verzeichnisse..."
BUILT_TEMPLATES=0
# Fallback auf .env.example wenn .env nicht existiert
if [ -z "$USER_TEMPLATE_IMAGES" ] && [ -f "${INSTALL_DIR}/.env.example" ]; then
echo -e "${YELLOW}⚠️ .env nicht gefunden oder USER_TEMPLATE_IMAGES nicht definiert${NC}"
echo " Nutze .env.example als Fallback..."
USER_TEMPLATE_IMAGES=$(grep "^USER_TEMPLATE_IMAGES=" "${INSTALL_DIR}/.env.example" | cut -d'=' -f2- | tr -d '"' | tr -d "'")
fi
for template_dir in "${INSTALL_DIR}"/user-template*; do
# Prüfe ob Verzeichnis existiert
# Fallback: Wenn noch immer leer, baue alle Templates (rückwärtskompatibel)
if [ -z "$USER_TEMPLATE_IMAGES" ]; then
echo -e "${YELLOW}⚠️ USER_TEMPLATE_IMAGES nicht konfiguriert${NC}"
echo " Fallback: Baue alle user-template-* Verzeichnisse (alte Logik)..."
echo ""
BUILT_TEMPLATES=0
TEMPLATE_DIRS=$(find "${INSTALL_DIR}" -maxdepth 1 -type d -name "user-template*" 2>/dev/null | wc -l)
TOTAL_BUILDS=$((2 + TEMPLATE_DIRS))
BUILD_STEP=$((BUILD_STEP + 1))
for template_dir in "${INSTALL_DIR}"/user-template*; do
[ -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
echo ""
BUILD_LOG="${LOG_FILE}"
echo "" >> "${LOG_FILE}"
echo "=== Build: ${template_name} ===" >> "${LOG_FILE}"
docker build --no-cache -t "${image_name}" "${template_dir}/" >> "${BUILD_LOG}" 2>&1
BUILD_EXIT=$?
# Gefilterten Output anzeigen
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
if [ $BUILD_EXIT -eq 0 ] && docker image inspect "${image_name}" >/dev/null 2>&1; then
echo ""
echo -e " ${template_name}: ${GREEN}OK${NC}"
@ -428,22 +434,144 @@ for template_dir in "${INSTALL_DIR}"/user-template*; do
echo ""
echo -e " ${template_name}: ${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))
done
done
if [ $BUILT_TEMPLATES -eq 0 ]; then
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
echo ""
echo -e "${GREEN}Alle ${BUILT_TEMPLATES} Template(s) erfolgreich gebaut.${NC}"
echo ""
echo -e "${GREEN}Alle ${BUILT_TEMPLATES} Template(s) erfolgreich gebaut.${NC}"
else
# .env-basiertes Building (neue Logik)
echo " Baue Templates aus .env Konfiguration..."
echo ""
# Konvertiere zu Array (split by ;)
IFS=';' read -ra TEMPLATE_IMAGES <<< "$USER_TEMPLATE_IMAGES"
# Zähle Templates für Fortschrittsanzeige
TOTAL_TEMPLATES=${#TEMPLATE_IMAGES[@]}
TOTAL_BUILDS=$((2 + TOTAL_TEMPLATES))
BUILD_STEP=$((BUILD_STEP + 1))
BUILT_TEMPLATES=0
for image_with_tag in "${TEMPLATE_IMAGES[@]}"; do
# Entferne Whitespace
image_with_tag=$(echo "$image_with_tag" | xargs)
[ -z "$image_with_tag" ] && continue
# Extrahiere Verzeichnisnamen (vor dem :)
template_dir_name="${image_with_tag%%:*}"
# Extrahiere Tag (nach dem :)
template_tag="${image_with_tag##*:}"
# Fallback auf :latest wenn kein Tag
[ -z "$template_tag" ] && template_tag="latest"
# Vollständiger Pfad zum Template-Verzeichnis
template_dir="${INSTALL_DIR}/${template_dir_name}"
echo " [$BUILD_STEP/$TOTAL_BUILDS] Baue Template: ${template_dir_name}:${template_tag}"
# Prüfe ob Verzeichnis existiert
if [ ! -d "$template_dir" ]; then
echo -e " ${RED}❌ Fehler: Template-Verzeichnis nicht gefunden${NC}"
echo " Definiert in .env: USER_TEMPLATE_IMAGES"
echo " Erwartetes Verzeichnis: ${template_dir}"
echo " Überspringe dieses Template."
echo ""
BUILD_STEP=$((BUILD_STEP + 1))
continue
fi
# Dockerfile vorhanden?
if [ ! -f "${template_dir}/Dockerfile" ]; then
echo -e " ${RED}❌ Fehler: Kein Dockerfile gefunden${NC}"
echo " Pfad: ${template_dir}/Dockerfile"
echo " Überspringe dieses Template."
echo ""
BUILD_STEP=$((BUILD_STEP + 1))
continue
fi
# Special handling für Next.js Templates
if [[ "$template_dir_name" == *"next"* ]]; then
echo -e " ${BLUE}Dies kann 2-5 Minuten dauern (npm install + build)...${NC}"
fi
echo ""
BUILD_LOG="${LOG_FILE}"
echo "" >> "${LOG_FILE}"
echo "=== Build: ${template_dir_name}:${template_tag} ===" >> "${LOG_FILE}"
docker build --no-cache -t "${template_dir_name}:${template_tag}" "${template_dir}/" >> "${BUILD_LOG}" 2>&1
BUILD_EXIT=$?
# Gefilterten Output anzeigen
grep -E "(Step |#[0-9]+ |Successfully|ERROR|error:|COPY|RUN|FROM)" "${BUILD_LOG}" 2>/dev/null | sed 's/^/ /' || true
# Prüfe ob Build erfolgreich UND Image existiert
if [ $BUILD_EXIT -eq 0 ] && docker image inspect "${template_dir_name}:${template_tag}" >/dev/null 2>&1; then
echo ""
echo -e " ${template_dir_name}: ${GREEN}OK${NC}"
BUILT_TEMPLATES=$((BUILT_TEMPLATES + 1))
else
echo ""
echo -e " ${template_dir_name}: ${RED}FEHLER${NC}"
echo " Siehe Build-Log: ${LOG_FILE}"
echo " Letzte 50 Zeilen:"
tail -50 "${BUILD_LOG}"
exit 1
fi
echo ""
BUILD_STEP=$((BUILD_STEP + 1))
done
if [ $BUILT_TEMPLATES -eq 0 ]; then
echo -e "${RED}FEHLER: Keine Templates aus USER_TEMPLATE_IMAGES gebaut!${NC}"
echo "Prüfe .env: USER_TEMPLATE_IMAGES"
exit 1
fi
echo -e "${GREEN}${BUILT_TEMPLATES}/${TOTAL_TEMPLATES} Template(s) erfolgreich gebaut.${NC}"
# Warne bei ungenutzten Template-Verzeichnissen
echo ""
echo " Prüfe auf ungekonfigurierte Template-Verzeichnisse..."
UNUSED_COUNT=0
for template_dir in "${INSTALL_DIR}"/user-template*; do
[ -d "$template_dir" ] || continue
template_name=$(basename "$template_dir")
# Ist dieses Template in USER_TEMPLATE_IMAGES definiert?
if [[ ! "$USER_TEMPLATE_IMAGES" =~ "$template_name" ]]; then
if [ $UNUSED_COUNT -eq 0 ]; then
echo -e " ${YELLOW}⚠️ Ungekonfigurierte Template-Verzeichnisse:${NC}"
fi
echo " - ${template_name} (nicht in USER_TEMPLATE_IMAGES definiert)"
UNUSED_COUNT=$((UNUSED_COUNT + 1))
fi
done
if [ $UNUSED_COUNT -gt 0 ]; then
echo " Hinweis: Diese Templates wurden NICHT gebaut."
echo " Um sie zu bauen, füge sie zu .env hinzu: USER_TEMPLATE_IMAGES=...;${template_name}:latest"
fi
echo ""
fi
# Spawner Backend Image bauen
echo " [$BUILD_STEP/$TOTAL_BUILDS] Baue Spawner API (Flask Backend)..."