feat: Major UI improvements to ez-homelab.sh
- Add professional ASCII box styling to main menu - Implement interactive variable configuration with validation - Add icons to all prompts (🌐 🌍 🦆 🔑 👤 🔒 📧 🏠) - Create vanishing prompts that replace with status confirmations - Add comprehensive menu system with proceed/review/quit options - Show current configuration values before deployment choices - Implement proper error handling for invalid inputs - Add immediate quit functionality with 'q' during any prompt - Improve spacing and visual hierarchy throughout interface - Fix deployment flow to prevent accidental starts on invalid input
This commit is contained in:
4
aliases.sh
Executable file
4
aliases.sh
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
alias ll='ls -alF'
|
||||||
|
alias dkrtable='docker ps --format "table {{.Names}}\t{{.Status}}\t{{.RunningFor}}"'
|
||||||
|
alias dkrrecreate='docker compose up -d --force-recreate'
|
||||||
|
alias fixpermissions='sudo chown -R 1000:1000 /opt ~'
|
||||||
@@ -13,6 +13,6 @@
|
|||||||
# host: 192.168.4.5
|
# host: 192.168.4.5
|
||||||
# port: 2375
|
# port: 2375
|
||||||
|
|
||||||
#${SERVER_HOSTNAME}:
|
#jasper:
|
||||||
# host: 192.168.4.11
|
# host: 192.168.4.11
|
||||||
# port: 2375
|
# port: 2375
|
||||||
|
|||||||
@@ -4,288 +4,288 @@
|
|||||||
- Dashboards:
|
- Dashboards:
|
||||||
- Homepage:
|
- Homepage:
|
||||||
icon: homepage.png
|
icon: homepage.png
|
||||||
href: https://homepage.${DOMAIN}
|
href: https://homepage.kelinreij.duckdns.org
|
||||||
description: Hosted on Raspberry Pi
|
description: Hosted on Raspberry Pi
|
||||||
|
|
||||||
- Homepage - ${REMOTE_SERVER_HOSTNAME}:
|
- Homepage - ${REMOTE_SERVER_HOSTNAME}:
|
||||||
icon: homepage.png
|
icon: homepage.png
|
||||||
href: https://homepage.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}
|
href: https://homepage.${REMOTE_SERVER_HOSTNAME}.kelinreij.duckdns.org
|
||||||
description: ${REMOTE_SERVER_HOSTNAME} - Application Dashboard
|
description: ${REMOTE_SERVER_HOSTNAME} - Application Dashboard
|
||||||
|
|
||||||
- Homarr:
|
- Homarr:
|
||||||
icon: homarr.png
|
icon: homarr.png
|
||||||
href: https://homarr.${DOMAIN}
|
href: https://homarr.kelinreij.duckdns.org
|
||||||
description: Alternative Dashboard
|
description: Alternative Dashboard
|
||||||
|
|
||||||
- Homarr - ${REMOTE_SERVER_HOSTNAME}:
|
- Homarr - ${REMOTE_SERVER_HOSTNAME}:
|
||||||
icon: homarr.png
|
icon: homarr.png
|
||||||
href: https://homarr.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}
|
href: https://homarr.${REMOTE_SERVER_HOSTNAME}.kelinreij.duckdns.org
|
||||||
description: ${REMOTE_SERVER_HOSTNAME} - Alternative Dashboard
|
description: ${REMOTE_SERVER_HOSTNAME} - Alternative Dashboard
|
||||||
|
|
||||||
- Dockge - ${SERVER_HOSTNAME}:
|
- Dockge - jasper:
|
||||||
icon: dockge.png
|
icon: dockge.png
|
||||||
href: https://${SERVER_HOSTNAME}.${DOMAIN}
|
href: https://jasper.kelinreij.duckdns.org
|
||||||
description: Main Server
|
description: Main Server
|
||||||
|
|
||||||
- Dockge - ${REMOTE_SERVER_HOSTNAME}:
|
- Dockge - ${REMOTE_SERVER_HOSTNAME}:
|
||||||
icon: dockge.png
|
icon: dockge.png
|
||||||
href: https://${REMOTE_SERVER_HOSTNAME}.${DOMAIN}
|
href: https://${REMOTE_SERVER_HOSTNAME}.kelinreij.duckdns.org
|
||||||
description: Raspberry Pi Authentication Server
|
description: Raspberry Pi Authentication Server
|
||||||
|
|
||||||
- Core:
|
- Core:
|
||||||
- Traefik:
|
- Traefik:
|
||||||
icon: traefik.png
|
icon: traefik.png
|
||||||
href: https://traefik.${DOMAIN}
|
href: https://traefik.kelinreij.duckdns.org
|
||||||
description: Reverse Proxy & SSL
|
description: Reverse Proxy & SSL
|
||||||
|
|
||||||
- Authelia:
|
- Authelia:
|
||||||
icon: authelia.png
|
icon: authelia.png
|
||||||
href: https://auth.${DOMAIN}
|
href: https://auth.kelinreij.duckdns.org
|
||||||
description: Authentication SSO Portal
|
description: Authentication SSO Portal
|
||||||
|
|
||||||
- Pi-hole:
|
- Pi-hole:
|
||||||
icon: pi-hole.png
|
icon: pi-hole.png
|
||||||
href: https://pihole.${DOMAIN}
|
href: https://pihole.kelinreij.duckdns.org
|
||||||
description: Network-wide Ad Blocking
|
description: Network-wide Ad Blocking
|
||||||
|
|
||||||
- Monitoring Stack:
|
- Monitoring Stack:
|
||||||
- Dozzle:
|
- Dozzle:
|
||||||
icon: dozzle.png
|
icon: dozzle.png
|
||||||
href: https://dozzle.${SERVER_HOSTNAME}.${DOMAIN}
|
href: https://dozzle.jasper.kelinreij.duckdns.org
|
||||||
description: ${SERVER_HOSTNAME} - Real-time Log Viewer
|
description: jasper - Real-time Log Viewer
|
||||||
|
|
||||||
- Dozzle:
|
- Dozzle:
|
||||||
icon: dozzle.png
|
icon: dozzle.png
|
||||||
href: https://dozzle.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}
|
href: https://dozzle.${REMOTE_SERVER_HOSTNAME}.kelinreij.duckdns.org
|
||||||
description: ${REMOTE_SERVER_HOSTNAME} - Real-time Log Viewer
|
description: ${REMOTE_SERVER_HOSTNAME} - Real-time Log Viewer
|
||||||
|
|
||||||
- Glances - ${SERVER_HOSTNAME}:
|
- Glances - jasper:
|
||||||
icon: glances.png
|
icon: glances.png
|
||||||
href: https://glances.${SERVER_HOSTNAME}.${DOMAIN}
|
href: https://glances.jasper.kelinreij.duckdns.org
|
||||||
description: ${SERVER_HOSTNAME} - System Monitoring
|
description: jasper - System Monitoring
|
||||||
|
|
||||||
- Glances - ${REMOTE_SERVER_HOSTNAME}:
|
- Glances - ${REMOTE_SERVER_HOSTNAME}:
|
||||||
icon: glances.png
|
icon: glances.png
|
||||||
href: https://glances.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}
|
href: https://glances.${REMOTE_SERVER_HOSTNAME}.kelinreij.duckdns.org
|
||||||
description: ${REMOTE_SERVER_HOSTNAME} - System Monitoring
|
description: ${REMOTE_SERVER_HOSTNAME} - System Monitoring
|
||||||
|
|
||||||
- Uptime Kuma:
|
- Uptime Kuma:
|
||||||
icon: uptime-kuma.png
|
icon: uptime-kuma.png
|
||||||
href: https://uptime-kuma.${DOMAIN}
|
href: https://uptime-kuma.kelinreij.duckdns.org
|
||||||
description: Uptime Monitoring
|
description: Uptime Monitoring
|
||||||
|
|
||||||
- Grafana - ${REMOTE_SERVER_HOSTNAME}:
|
- Grafana - ${REMOTE_SERVER_HOSTNAME}:
|
||||||
icon: grafana.png
|
icon: grafana.png
|
||||||
href: https://grafana.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}
|
href: https://grafana.${REMOTE_SERVER_HOSTNAME}.kelinreij.duckdns.org
|
||||||
description: ${REMOTE_SERVER_HOSTNAME} - Metrics Dashboard
|
description: ${REMOTE_SERVER_HOSTNAME} - Metrics Dashboard
|
||||||
|
|
||||||
- Prometheus - ${REMOTE_SERVER_HOSTNAME}:
|
- Prometheus - ${REMOTE_SERVER_HOSTNAME}:
|
||||||
icon: prometheus.png
|
icon: prometheus.png
|
||||||
href: https://prometheus.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}
|
href: https://prometheus.${REMOTE_SERVER_HOSTNAME}.kelinreij.duckdns.org
|
||||||
description: ${REMOTE_SERVER_HOSTNAME} - Metrics Collection
|
description: ${REMOTE_SERVER_HOSTNAME} - Metrics Collection
|
||||||
|
|
||||||
- Uptime Kuma - ${REMOTE_SERVER_HOSTNAME}:
|
- Uptime Kuma - ${REMOTE_SERVER_HOSTNAME}:
|
||||||
icon: uptime-kuma.png
|
icon: uptime-kuma.png
|
||||||
href: https://status.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}
|
href: https://status.${REMOTE_SERVER_HOSTNAME}.kelinreij.duckdns.org
|
||||||
description: ${REMOTE_SERVER_HOSTNAME} - Uptime Monitoring
|
description: ${REMOTE_SERVER_HOSTNAME} - Uptime Monitoring
|
||||||
|
|
||||||
- Media:
|
- Media:
|
||||||
- Jellyfin:
|
- Jellyfin:
|
||||||
icon: jellyfin.png
|
icon: jellyfin.png
|
||||||
href: https://jellyfin.${DOMAIN}
|
href: https://jellyfin.kelinreij.duckdns.org
|
||||||
description: Open Source Media Server
|
description: Open Source Media Server
|
||||||
|
|
||||||
- Jellyseerr:
|
- Jellyseerr:
|
||||||
icon: jellyseerr.png
|
icon: jellyseerr.png
|
||||||
href: https://jellyseerr.${DOMAIN}
|
href: https://jellyseerr.kelinreij.duckdns.org
|
||||||
description: Media Request Manager
|
description: Media Request Manager
|
||||||
|
|
||||||
- Calibre-Web:
|
- Calibre-Web:
|
||||||
icon: calibre-web.png
|
icon: calibre-web.png
|
||||||
href: https://calibre.${DOMAIN}
|
href: https://calibre.kelinreij.duckdns.org
|
||||||
description: Ebook Library
|
description: Ebook Library
|
||||||
|
|
||||||
- Media Management:
|
- Media Management:
|
||||||
- Sonarr:
|
- Sonarr:
|
||||||
icon: sonarr.png
|
icon: sonarr.png
|
||||||
href: https://sonarr.${DOMAIN}
|
href: https://sonarr.kelinreij.duckdns.org
|
||||||
description: TV Shows Automation
|
description: TV Shows Automation
|
||||||
|
|
||||||
- Radarr:
|
- Radarr:
|
||||||
icon: radarr.png
|
icon: radarr.png
|
||||||
href: https://radarr.${DOMAIN}
|
href: https://radarr.kelinreij.duckdns.org
|
||||||
description: Movies Automation
|
description: Movies Automation
|
||||||
|
|
||||||
- Prowlarr:
|
- Prowlarr:
|
||||||
icon: prowlarr.png
|
icon: prowlarr.png
|
||||||
href: https://prowlarr.${DOMAIN}
|
href: https://prowlarr.kelinreij.duckdns.org
|
||||||
description: Indexer Manager
|
description: Indexer Manager
|
||||||
|
|
||||||
- Readarr:
|
- Readarr:
|
||||||
icon: readarr.png
|
icon: readarr.png
|
||||||
href: https://readarr.${DOMAIN}
|
href: https://readarr.kelinreij.duckdns.org
|
||||||
description: Books Automation
|
description: Books Automation
|
||||||
|
|
||||||
- Lidarr:
|
- Lidarr:
|
||||||
icon: lidarr.png
|
icon: lidarr.png
|
||||||
href: https://lidarr.${DOMAIN}
|
href: https://lidarr.kelinreij.duckdns.org
|
||||||
description: Music Automation
|
description: Music Automation
|
||||||
|
|
||||||
- Mylar3:
|
- Mylar3:
|
||||||
icon: mylar.png
|
icon: mylar.png
|
||||||
href: https://mylar.${DOMAIN}
|
href: https://mylar.kelinreij.duckdns.org
|
||||||
description: Comics Manager
|
description: Comics Manager
|
||||||
|
|
||||||
- Home Automation:
|
- Home Automation:
|
||||||
- Home Assistant:
|
- Home Assistant:
|
||||||
icon: home-assistant.png
|
icon: home-assistant.png
|
||||||
href: https://hass.${DOMAIN}
|
href: https://hass.kelinreij.duckdns.org
|
||||||
description: Home Automation Platform
|
description: Home Automation Platform
|
||||||
|
|
||||||
- ESPHome:
|
- ESPHome:
|
||||||
icon: esphome.png
|
icon: esphome.png
|
||||||
href: https://esphome.${DOMAIN}
|
href: https://esphome.kelinreij.duckdns.org
|
||||||
description: ESP Device Manager
|
description: ESP Device Manager
|
||||||
|
|
||||||
- Node-RED:
|
- Node-RED:
|
||||||
icon: node-red.png
|
icon: node-red.png
|
||||||
href: https://nodered.${DOMAIN}
|
href: https://nodered.kelinreij.duckdns.org
|
||||||
description: Flow-based Automation
|
description: Flow-based Automation
|
||||||
|
|
||||||
- Zigbee2MQTT:
|
- Zigbee2MQTT:
|
||||||
icon: zigbee2mqtt.png
|
icon: zigbee2mqtt.png
|
||||||
href: https://zigbee.${DOMAIN}
|
href: https://zigbee.kelinreij.duckdns.org
|
||||||
description: Zigbee Bridge
|
description: Zigbee Bridge
|
||||||
|
|
||||||
- Mosquitto:
|
- Mosquitto:
|
||||||
icon: mosquitto.png
|
icon: mosquitto.png
|
||||||
href: https://mqtt.${DOMAIN}
|
href: https://mqtt.kelinreij.duckdns.org
|
||||||
description: MQTT Broker
|
description: MQTT Broker
|
||||||
|
|
||||||
- Productivity:
|
- Productivity:
|
||||||
- Nextcloud:
|
- Nextcloud:
|
||||||
icon: nextcloud.png
|
icon: nextcloud.png
|
||||||
href: https://nextcloud.${DOMAIN}
|
href: https://nextcloud.kelinreij.duckdns.org
|
||||||
description: Cloud Storage & Collaboration
|
description: Cloud Storage & Collaboration
|
||||||
|
|
||||||
- Gitea:
|
- Gitea:
|
||||||
icon: gitea.png
|
icon: gitea.png
|
||||||
href: https://gitea.${DOMAIN}
|
href: https://gitea.kelinreij.duckdns.org
|
||||||
description: Git Repository
|
description: Git Repository
|
||||||
|
|
||||||
- Mealie:
|
- Mealie:
|
||||||
icon: mealie.png
|
icon: mealie.png
|
||||||
href: https://mealie.${DOMAIN}
|
href: https://mealie.kelinreij.duckdns.org
|
||||||
description: Recipe Manager
|
description: Recipe Manager
|
||||||
|
|
||||||
- WordPress:
|
- WordPress:
|
||||||
icon: wordpress.png
|
icon: wordpress.png
|
||||||
href: https://wordpress.${DOMAIN}
|
href: https://wordpress.kelinreij.duckdns.org
|
||||||
description: CMS Platform
|
description: CMS Platform
|
||||||
|
|
||||||
- Wikis:
|
- Wikis:
|
||||||
- BookStack:
|
- BookStack:
|
||||||
icon: bookstack.png
|
icon: bookstack.png
|
||||||
href: https://bookstack.${DOMAIN}
|
href: https://bookstack.kelinreij.duckdns.org
|
||||||
description: Wiki Platform
|
description: Wiki Platform
|
||||||
|
|
||||||
- DokuWiki:
|
- DokuWiki:
|
||||||
icon: dokuwiki.png
|
icon: dokuwiki.png
|
||||||
href: https://dokuwiki.${DOMAIN}
|
href: https://dokuwiki.kelinreij.duckdns.org
|
||||||
description: Simple Wiki
|
description: Simple Wiki
|
||||||
|
|
||||||
- Mediawiki:
|
- Mediawiki:
|
||||||
icon: mediawiki.png
|
icon: mediawiki.png
|
||||||
href: https://mediawiki.${DOMAIN}
|
href: https://mediawiki.kelinreij.duckdns.org
|
||||||
description: Collaborative Wiki
|
description: Collaborative Wiki
|
||||||
|
|
||||||
- Development:
|
- Development:
|
||||||
- VS Code Server:
|
- VS Code Server:
|
||||||
icon: vscode.png
|
icon: vscode.png
|
||||||
href: https://code.${DOMAIN}
|
href: https://code.kelinreij.duckdns.org
|
||||||
description: Browser-based IDE
|
description: Browser-based IDE
|
||||||
|
|
||||||
- Jupyter:
|
- Jupyter:
|
||||||
icon: jupyter.png
|
icon: jupyter.png
|
||||||
href: https://jupyter.${DOMAIN}
|
href: https://jupyter.kelinreij.duckdns.org
|
||||||
description: Data Science Notebooks
|
description: Data Science Notebooks
|
||||||
|
|
||||||
- Downloaders:
|
- Downloaders:
|
||||||
- qBittorrent:
|
- qBittorrent:
|
||||||
icon: qbittorrent.png
|
icon: qbittorrent.png
|
||||||
href: https://qbit.${DOMAIN}
|
href: https://qbit.kelinreij.duckdns.org
|
||||||
description: Torrent Client
|
description: Torrent Client
|
||||||
- Transcoders:
|
- Transcoders:
|
||||||
- Tdarr:
|
- Tdarr:
|
||||||
icon: tdarr.png
|
icon: tdarr.png
|
||||||
href: https://tdarr.${DOMAIN}
|
href: https://tdarr.kelinreij.duckdns.org
|
||||||
description: Media Transcoding
|
description: Media Transcoding
|
||||||
|
|
||||||
- Unmanic:
|
- Unmanic:
|
||||||
icon: unmanic.png
|
icon: unmanic.png
|
||||||
href: https://unmanic.${DOMAIN}
|
href: https://unmanic.kelinreij.duckdns.org
|
||||||
description: Media Transcoder
|
description: Media Transcoder
|
||||||
|
|
||||||
- Utilities:
|
- Utilities:
|
||||||
- Vaultwarden:
|
- Vaultwarden:
|
||||||
icon: vaultwarden.png
|
icon: vaultwarden.png
|
||||||
href: https://vault.${DOMAIN}
|
href: https://vault.kelinreij.duckdns.org
|
||||||
description: Password Manager
|
description: Password Manager
|
||||||
|
|
||||||
- Formio:
|
- Formio:
|
||||||
icon: mdi-form-select
|
icon: mdi-form-select
|
||||||
href: https://formio.${DOMAIN}
|
href: https://formio.kelinreij.duckdns.org
|
||||||
description: Form Builder
|
description: Form Builder
|
||||||
|
|
||||||
- Backup:
|
- Backup:
|
||||||
- Backrest:
|
- Backrest:
|
||||||
icon: mdi-backup-restore
|
icon: mdi-backup-restore
|
||||||
href: https://backrest.${DOMAIN}
|
href: https://backrest.kelinreij.duckdns.org
|
||||||
description: Backup Solution
|
description: Backup Solution
|
||||||
|
|
||||||
- Backrest - ${REMOTE_SERVER_HOSTNAME}:
|
- Backrest - ${REMOTE_SERVER_HOSTNAME}:
|
||||||
icon: mdi-backup-restore
|
icon: mdi-backup-restore
|
||||||
href: https://backrest.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}
|
href: https://backrest.${REMOTE_SERVER_HOSTNAME}.kelinreij.duckdns.org
|
||||||
description: ${REMOTE_SERVER_HOSTNAME} - Backup Solution
|
description: ${REMOTE_SERVER_HOSTNAME} - Backup Solution
|
||||||
|
|
||||||
- Duplicati:
|
- Duplicati:
|
||||||
icon: duplicati.png
|
icon: duplicati.png
|
||||||
href: https://duplicati.${DOMAIN}
|
href: https://duplicati.kelinreij.duckdns.org
|
||||||
description: Backup Software
|
description: Backup Software
|
||||||
|
|
||||||
- Duplicati - ${REMOTE_SERVER_HOSTNAME}:
|
- Duplicati - ${REMOTE_SERVER_HOSTNAME}:
|
||||||
icon: duplicati.png
|
icon: duplicati.png
|
||||||
href: https://duplicati.${REMOTE_SERVER_HOSTNAME}.${DOMAIN}
|
href: https://duplicati.${REMOTE_SERVER_HOSTNAME}.kelinreij.duckdns.org
|
||||||
description: ${REMOTE_SERVER_HOSTNAME} - Backup Software
|
description: ${REMOTE_SERVER_HOSTNAME} - Backup Software
|
||||||
|
|
||||||
- Metrics:
|
- Metrics:
|
||||||
- Grafana:
|
- Grafana:
|
||||||
icon: grafana.png
|
icon: grafana.png
|
||||||
href: https://grafana.${DOMAIN}
|
href: https://grafana.kelinreij.duckdns.org
|
||||||
description: Metrics Dashboard
|
description: Metrics Dashboard
|
||||||
|
|
||||||
- Prometheus:
|
- Prometheus:
|
||||||
icon: prometheus.png
|
icon: prometheus.png
|
||||||
href: https://prometheus.${DOMAIN}
|
href: https://prometheus.kelinreij.duckdns.org
|
||||||
description: Metrics Collection
|
description: Metrics Collection
|
||||||
|
|
||||||
- cAdvisor:
|
- cAdvisor:
|
||||||
icon: cadvisor.png
|
icon: cadvisor.png
|
||||||
href: https://cadvisor.${DOMAIN}
|
href: https://cadvisor.kelinreij.duckdns.org
|
||||||
description: Container Metrics
|
description: Container Metrics
|
||||||
|
|
||||||
- Alternatives:
|
- Alternatives:
|
||||||
- Portainer:
|
- Portainer:
|
||||||
icon: portainer.png
|
icon: portainer.png
|
||||||
href: https://portainer.${DOMAIN}
|
href: https://portainer.kelinreij.duckdns.org
|
||||||
description: Container Management UI
|
description: Container Management UI
|
||||||
|
|
||||||
- Authentik:
|
- Authentik:
|
||||||
icon: authentik.png
|
icon: authentik.png
|
||||||
href: https://authentik.${DOMAIN}
|
href: https://authentik.kelinreij.duckdns.org
|
||||||
description: Alternative Auth Provider
|
description: Alternative Auth Provider
|
||||||
|
|
||||||
- Plex:
|
- Plex:
|
||||||
icon: plex.png
|
icon: plex.png
|
||||||
href: https://plex.${DOMAIN}
|
href: https://plex.kelinreij.duckdns.org
|
||||||
description: Media Server
|
description: Media Server
|
||||||
|
|||||||
60
markup.yml
Normal file
60
markup.yml
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
|
||||||
|
|
||||||
|
echo "╔═════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ EZ-HOMELAB SETUP & DEPLOYMENT ║"
|
||||||
|
echo "║ ║"
|
||||||
|
echo "║ 1) Install Docker ║"
|
||||||
|
echo "║ 2) Deploy Core Server ║"
|
||||||
|
echo "║ 3) Deploy Additional Server ║"
|
||||||
|
echo "║ 4) Install NVIDIA Drivers ║"
|
||||||
|
echo "║ ║"
|
||||||
|
echo "║ q) Quit ║"
|
||||||
|
echo "╚═════════════════════════════════════════════════════════════╝"
|
||||||
|
|
||||||
|
|
||||||
|
echo "╔═════════════════════════════════════════════════════════════╗
|
||||||
|
echo "║ ✅ SERVER_IP: 192.168.4.4 ║
|
||||||
|
echo "║ ✅ SERVER_HOSTNAME: jasper ║
|
||||||
|
echo "║ ✅ DUCKDNS_SUBDOMAINS: kelinreij ║
|
||||||
|
echo "║ ✅ DUCKDNS_TOKEN: 41ef7faa-fc93-41d2-a32f-340fd2b75b2f ║
|
||||||
|
echo "║ ✅ DOMAIN: kelinreij.duckdns.org ║
|
||||||
|
echo "║ ✅ DEFAULT_USER: kelin ║
|
||||||
|
echo "║ ✅ DEFAULT_PASSWORD: Tiberi0u$ ║
|
||||||
|
echo "║ ✅ DEFAULT_EMAIL: kelinshomelab@gmail.com ║
|
||||||
|
echo "╚═════════════════════════════════════════════════════════════╝
|
||||||
|
|
||||||
|
echo "╔═════════════════════════════════════════════════════════════╗
|
||||||
|
echo "║ Use These Values ? (Y/n) ║
|
||||||
|
echo "╚═════════════════════════════════════════════════════════════╝
|
||||||
|
|
||||||
|
echo "╔═════════════════════════════════════════════════════════════╗
|
||||||
|
echo "║ Deployment Complete! ║
|
||||||
|
echo "║ SSL Certificates may take a few minutes to be issued. ║
|
||||||
|
echo "║ ║
|
||||||
|
echo "║ https://dockge.kelinreij.duckdns.org ║
|
||||||
|
echo "║ http://192.168.4.4:5001 ║
|
||||||
|
echo "║ ║
|
||||||
|
echo "║ https://homepage.kelinreij.duckdns.org ║
|
||||||
|
echo "║ http://192.168.4.4:3003 ║
|
||||||
|
echo "║ ║
|
||||||
|
echo "║ https://authelia.kelinreij.duckdns.org ║
|
||||||
|
echo "║ http://192.168.4.4:9091 ║
|
||||||
|
echo "║ ║
|
||||||
|
echo "║ https://traefik.kelinreij.duckdns.org ║
|
||||||
|
echo "║ http://192.168.4.4:8080 ║
|
||||||
|
echo "║ ║
|
||||||
|
echo "╚═════════════════════════════════════════════════════════════╝
|
||||||
|
|
||||||
|
echo "╔═════════════════════════════════════════════════════════════╗
|
||||||
|
echo "║ ⚠️ WARNING ⚠️ ║
|
||||||
|
echo "║ The following variables were not defined ║
|
||||||
|
echo "║ If something isn't working as expected check these first ║
|
||||||
|
echo "║ ║
|
||||||
|
echo "║ WATCHTOWER_NOTIFICATION_URL WATCHTOWER_NOTIFICATION_URL ║
|
||||||
|
echo "║ AUTHENTIK_DB_NAME AUTHENTIK_DB_PASSWORD ║
|
||||||
|
echo "║ ║
|
||||||
|
echo "╚═════════════════════════════════════════════════════════════╝
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -8,6 +8,7 @@ set -e # Exit on error
|
|||||||
|
|
||||||
# Debug logging configuration
|
# Debug logging configuration
|
||||||
DEBUG=${DEBUG:-false}
|
DEBUG=${DEBUG:-false}
|
||||||
|
VERBOSE=${VERBOSE:-false} # New verbosity toggle
|
||||||
DEBUG_LOG_FILE="/tmp/ez-homelab-debug.log"
|
DEBUG_LOG_FILE="/tmp/ez-homelab-debug.log"
|
||||||
|
|
||||||
# Colors for output
|
# Colors for output
|
||||||
@@ -33,17 +34,23 @@ fi
|
|||||||
|
|
||||||
# Log functions
|
# Log functions
|
||||||
log_info() {
|
log_info() {
|
||||||
|
if [ "$VERBOSE" = true ]; then
|
||||||
echo -e "${BLUE}[INFO]${NC} $1"
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||||||
|
fi
|
||||||
debug_log "[INFO] $1"
|
debug_log "[INFO] $1"
|
||||||
}
|
}
|
||||||
|
|
||||||
log_success() {
|
log_success() {
|
||||||
|
if [ "$VERBOSE" = true ]; then
|
||||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||||
|
fi
|
||||||
debug_log "[SUCCESS] $1"
|
debug_log "[SUCCESS] $1"
|
||||||
}
|
}
|
||||||
|
|
||||||
log_warning() {
|
log_warning() {
|
||||||
|
if [ "$VERBOSE" = true ]; then
|
||||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||||
|
fi
|
||||||
debug_log "[WARNING] $1"
|
debug_log "[WARNING] $1"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,6 +114,14 @@ replace_env_placeholders() {
|
|||||||
debug_log "Found variables to replace: $vars"
|
debug_log "Found variables to replace: $vars"
|
||||||
|
|
||||||
for var in $vars; do
|
for var in $vars; do
|
||||||
|
# Skip derived variables that should not be replaced
|
||||||
|
case "$var" in
|
||||||
|
"ACME_EMAIL"|"AUTHELIA_ADMIN_EMAIL"|"SMTP_USERNAME"|"SMTP_PASSWORD")
|
||||||
|
debug_log "Skipping derived variable: $var"
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
if [ -z "${!var:-}" ]; then
|
if [ -z "${!var:-}" ]; then
|
||||||
log_warning "Environment variable $var not found in .env file"
|
log_warning "Environment variable $var not found in .env file"
|
||||||
debug_log "Missing variable: $var"
|
debug_log "Missing variable: $var"
|
||||||
@@ -132,6 +147,38 @@ replace_env_placeholders() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Enhanced placeholder replacement for all configuration files
|
||||||
|
enhance_placeholder_replacement() {
|
||||||
|
log_info "Starting enhanced placeholder replacement..."
|
||||||
|
|
||||||
|
local processed_files=0
|
||||||
|
|
||||||
|
# Process docker-compose files
|
||||||
|
if [ -d "$REPO_DIR/docker-compose" ]; then
|
||||||
|
while IFS= read -r -d '' file_path; do
|
||||||
|
if [ -f "$file_path" ]; then
|
||||||
|
debug_log "Processing docker-compose file: $file_path"
|
||||||
|
replace_env_placeholders "$file_path" false
|
||||||
|
processed_files=$((processed_files + 1))
|
||||||
|
fi
|
||||||
|
done < <(find "$REPO_DIR/docker-compose" -name "*.yml" -o -name "*.yaml" -print0 2>/dev/null)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Process config-templates files
|
||||||
|
if [ -d "$REPO_DIR/config-templates" ]; then
|
||||||
|
while IFS= read -r -d '' file_path; do
|
||||||
|
if [ -f "$file_path" ]; then
|
||||||
|
debug_log "Processing config template file: $file_path"
|
||||||
|
replace_env_placeholders "$file_path" false
|
||||||
|
processed_files=$((processed_files + 1))
|
||||||
|
fi
|
||||||
|
done < <(find "$REPO_DIR/config-templates" -name "*.yml" -o -name "*.yaml" -print0 2>/dev/null)
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "Enhanced placeholder replacement completed - processed $processed_files files"
|
||||||
|
debug_log "Enhanced replacement completed for $processed_files files"
|
||||||
|
}
|
||||||
|
|
||||||
# Function to generate shared CA for multi-server TLS
|
# Function to generate shared CA for multi-server TLS
|
||||||
generate_shared_ca() {
|
generate_shared_ca() {
|
||||||
local ca_dir="/opt/stacks/core/shared-ca"
|
local ca_dir="/opt/stacks/core/shared-ca"
|
||||||
@@ -296,35 +343,14 @@ DEPLOY_DASHBOARDS=false
|
|||||||
SETUP_STACKS=false
|
SETUP_STACKS=false
|
||||||
TLS_ISSUES_SUMMARY=""
|
TLS_ISSUES_SUMMARY=""
|
||||||
|
|
||||||
|
# Required variables for configuration
|
||||||
|
REQUIRED_VARS=("SERVER_IP" "SERVER_HOSTNAME" "DUCKDNS_SUBDOMAINS" "DUCKDNS_TOKEN" "DOMAIN" "DEFAULT_USER" "DEFAULT_PASSWORD" "DEFAULT_EMAIL")
|
||||||
|
|
||||||
# Load existing .env file if it exists
|
# Load existing .env file if it exists
|
||||||
load_env_file() {
|
load_env_file() {
|
||||||
if [ -f "$REPO_DIR/.env" ]; then
|
if [ -f "$REPO_DIR/.env" ]; then
|
||||||
log_info "Found existing .env file, loading current configuration..."
|
log_info "Found existing .env file, loading current configuration..."
|
||||||
load_env_file_safely "$REPO_DIR/.env"
|
load_env_file_safely "$REPO_DIR/.env"
|
||||||
|
|
||||||
# Show current values
|
|
||||||
echo ""
|
|
||||||
echo "Current configuration:"
|
|
||||||
echo " Domain: ${DOMAIN:-Not set}"
|
|
||||||
echo " Server IP: ${SERVER_IP:-Not set}"
|
|
||||||
echo " Server Hostname: ${SERVER_HOSTNAME:-Not set}"
|
|
||||||
echo " Remote Server IP: ${REMOTE_SERVER_IP:-Not set}"
|
|
||||||
echo " Remote Server Hostname: ${REMOTE_SERVER_HOSTNAME:-Not set}"
|
|
||||||
echo " Remote Server User: ${REMOTE_SERVER_USER:-Not set}"
|
|
||||||
if [ -n "${REMOTE_SERVER_PASSWORD:-}" ]; then
|
|
||||||
echo " Remote Server Password: [HIDDEN]"
|
|
||||||
else
|
|
||||||
echo " Remote Server Password: Not set"
|
|
||||||
fi
|
|
||||||
echo " Default User: ${DEFAULT_USER:-Not set}"
|
|
||||||
if [ -n "${DEFAULT_PASSWORD:-}" ]; then
|
|
||||||
echo " Default Password: [HIDDEN]"
|
|
||||||
else
|
|
||||||
echo " Default Password: Not set"
|
|
||||||
fi
|
|
||||||
echo " Timezone: ${TZ:-Not set}"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
log_info "No existing .env file found. We'll create one during setup."
|
log_info "No existing .env file found. We'll create one during setup."
|
||||||
@@ -332,6 +358,256 @@ load_env_file() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Validate variable values
|
||||||
|
validate_variable() {
|
||||||
|
local var_name="$1"
|
||||||
|
local var_value="$2"
|
||||||
|
|
||||||
|
case "$var_name" in
|
||||||
|
"SERVER_IP")
|
||||||
|
# Basic IP validation
|
||||||
|
if [[ $var_value =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"DOMAIN")
|
||||||
|
# Basic domain validation
|
||||||
|
if [[ $var_value =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"DUCKDNS_SUBDOMAINS")
|
||||||
|
# DuckDNS subdomain should be non-empty and contain only valid characters
|
||||||
|
local trimmed_value=$(echo "$var_value" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||||
|
if [ -n "$trimmed_value" ] && [[ $trimmed_value =~ ^[a-zA-Z0-9.-]+$ ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"DEFAULT_PASSWORD")
|
||||||
|
# Password should be at least 8 characters
|
||||||
|
if [ ${#var_value} -ge 8 ]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"DEFAULT_EMAIL")
|
||||||
|
# Basic email validation
|
||||||
|
if [[ $var_value =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# For other variables, trim whitespace and check they're not empty
|
||||||
|
local trimmed_value=$(echo "$var_value" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||||
|
if [ -n "$trimmed_value" ]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prompt for a single variable
|
||||||
|
prompt_for_variable() {
|
||||||
|
local var="$1"
|
||||||
|
local user_input=""
|
||||||
|
local current_value="${!var:-}"
|
||||||
|
local prompt_text=""
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
# Build prompt text with current value if it exists
|
||||||
|
if [ -n "$current_value" ]; then
|
||||||
|
if [ "$var" = "DEFAULT_PASSWORD" ]; then
|
||||||
|
prompt_text="🔒 ${var} ([HIDDEN]): "
|
||||||
|
else
|
||||||
|
prompt_text="${var} (${current_value}): "
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
prompt_text="${var}: "
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add icon prefix
|
||||||
|
case "$var" in
|
||||||
|
"SERVER_IP")
|
||||||
|
prompt_text="🌐 ${prompt_text}"
|
||||||
|
;;
|
||||||
|
"DOMAIN")
|
||||||
|
prompt_text="🌍 ${prompt_text}"
|
||||||
|
;;
|
||||||
|
"DUCKDNS_SUBDOMAINS")
|
||||||
|
prompt_text="🦆 ${prompt_text}"
|
||||||
|
;;
|
||||||
|
"DUCKDNS_TOKEN")
|
||||||
|
prompt_text="🔑 ${prompt_text}"
|
||||||
|
;;
|
||||||
|
"DEFAULT_USER")
|
||||||
|
prompt_text="👤 ${prompt_text}"
|
||||||
|
;;
|
||||||
|
"DEFAULT_PASSWORD")
|
||||||
|
# Lock icon already added above for passwords
|
||||||
|
;;
|
||||||
|
"DEFAULT_EMAIL")
|
||||||
|
prompt_text="📧 ${prompt_text}"
|
||||||
|
;;
|
||||||
|
"SERVER_HOSTNAME")
|
||||||
|
prompt_text="🏠 ${prompt_text}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Get user input
|
||||||
|
if [ "$var" = "DEFAULT_PASSWORD" ]; then
|
||||||
|
read -s -p "$prompt_text" user_input
|
||||||
|
echo ""
|
||||||
|
else
|
||||||
|
read -p "$prompt_text" user_input
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for quit command
|
||||||
|
if [ "$user_input" = "q" ] || [ "$user_input" = "Q" ]; then
|
||||||
|
log_info "Setup cancelled by user"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$user_input" ]; then
|
||||||
|
if [ -n "$current_value" ]; then
|
||||||
|
# Use existing value - overwrite prompt with status
|
||||||
|
if [ "$var" != "DEFAULT_PASSWORD" ]; then
|
||||||
|
echo -e "\033[1A\033[K✅ ${var}: ${current_value}"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_warning "${var} cannot be empty. Please provide a value."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if validate_variable "$var" "$user_input"; then
|
||||||
|
eval "$var=\"$user_input\""
|
||||||
|
# Overwrite prompt with status
|
||||||
|
if [ "$var" != "DEFAULT_PASSWORD" ]; then
|
||||||
|
echo -e "\033[1A\033[K✅ ${var}: ${user_input}"
|
||||||
|
else
|
||||||
|
echo -e "\033[1A\033[K✅ ${var}: [HIDDEN]"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_warning "Invalid value for ${var}. Please try again."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Validate and prompt for required variables with loop
|
||||||
|
validate_and_prompt_variables() {
|
||||||
|
local all_valid=false
|
||||||
|
local user_wants_to_review=false
|
||||||
|
local first_display=true
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
user_wants_to_review=false
|
||||||
|
|
||||||
|
all_valid=true
|
||||||
|
|
||||||
|
# Check validity without showing initial summary
|
||||||
|
for var in "${REQUIRED_VARS[@]}"; do
|
||||||
|
local display_value=$(echo "${!var:-}" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||||
|
if [ -z "$display_value" ] || ! validate_variable "$var" "${!var}"; then
|
||||||
|
all_valid=false
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$all_valid" = true ]; then
|
||||||
|
if [ "$first_display" = true ]; then
|
||||||
|
echo "Current configuration:"
|
||||||
|
for var in "${REQUIRED_VARS[@]}"; do
|
||||||
|
local display_value=$(echo "${!var:-}" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||||
|
if [ "$var" = "DEFAULT_PASSWORD" ]; then
|
||||||
|
echo " ✅ ${var}: [HIDDEN]"
|
||||||
|
else
|
||||||
|
echo " ✅ ${var}: ${display_value}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
first_display=false
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
echo "Choose an option:"
|
||||||
|
echo " 1) ✅ Deploy now"
|
||||||
|
echo " 2) 🔄 Make Changes"
|
||||||
|
echo " q) ❌ Quit setup"
|
||||||
|
echo ""
|
||||||
|
read -p "Enter your choice (1, 2, or q): " user_choice
|
||||||
|
|
||||||
|
case "$user_choice" in
|
||||||
|
1|"p"|"proceed")
|
||||||
|
log_info "Proceeding with current configuration..."
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
2|"r"|"review"|"change")
|
||||||
|
user_wants_to_review=true
|
||||||
|
echo ""
|
||||||
|
echo "Reviewing all variables - press Enter to keep current value or enter new value:"
|
||||||
|
echo ""
|
||||||
|
;;
|
||||||
|
[Qq]|[Qq]uit)
|
||||||
|
log_info "Setup cancelled by user"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_warning "Invalid choice. Please enter 1, 2, or q."
|
||||||
|
echo ""
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
echo "Some variables need configuration. Press Enter to continue or 'q' to quit."
|
||||||
|
read -p "Press Enter to configure missing variables, or 'q' to quit: " user_choice
|
||||||
|
|
||||||
|
case "$user_choice" in
|
||||||
|
[Qq]|[Qq]uit)
|
||||||
|
log_info "Setup cancelled by user"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
""|"c"|"continue")
|
||||||
|
# Continue with prompting
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_warning "Invalid choice. Press Enter to continue or 'q' to quit."
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prompt for variables (either missing ones or all if reviewing)
|
||||||
|
if [ "$user_wants_to_review" = true ]; then
|
||||||
|
# Review all variables one by one
|
||||||
|
for var in "${REQUIRED_VARS[@]}"; do
|
||||||
|
prompt_for_variable "$var"
|
||||||
|
done
|
||||||
|
# After review, continue the loop to show menu again
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
# Only prompt for missing/invalid variables
|
||||||
|
for var in "${REQUIRED_VARS[@]}"; do
|
||||||
|
if [ -z "${!var:-}" ] || ! validate_variable "$var" "${!var}"; then
|
||||||
|
prompt_for_variable "$var"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
# Save configuration to .env file
|
# Save configuration to .env file
|
||||||
save_env_file() {
|
save_env_file() {
|
||||||
debug_log "save_env_file() called, DEPLOY_CORE=$DEPLOY_CORE"
|
debug_log "save_env_file() called, DEPLOY_CORE=$DEPLOY_CORE"
|
||||||
@@ -342,15 +618,20 @@ save_env_file() {
|
|||||||
sudo -u "$ACTUAL_USER" cp "$REPO_DIR/.env.example" "$REPO_DIR/.env"
|
sudo -u "$ACTUAL_USER" cp "$REPO_DIR/.env.example" "$REPO_DIR/.env"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Update values as the actual user
|
# Update only the required variables
|
||||||
sudo -u "$ACTUAL_USER" sed -i "s%DOMAIN=.*%DOMAIN=$DOMAIN%" "$REPO_DIR/.env"
|
for var in "${REQUIRED_VARS[@]}"; do
|
||||||
sudo -u "$ACTUAL_USER" sed -i "s%SERVER_IP=.*%SERVER_IP=$SERVER_IP%" "$REPO_DIR/.env"
|
if [ -n "${!var:-}" ]; then
|
||||||
sudo -u "$ACTUAL_USER" sed -i "s%SERVER_HOSTNAME=.*%SERVER_HOSTNAME=$SERVER_HOSTNAME%" "$REPO_DIR/.env"
|
sudo -u "$ACTUAL_USER" sed -i "s|^${var}=.*|${var}=${!var}|" "$REPO_DIR/.env"
|
||||||
sudo -u "$ACTUAL_USER" sed -i "s%REMOTE_SERVER_IP=.*%REMOTE_SERVER_IP=$REMOTE_SERVER_IP%" "$REPO_DIR/.env"
|
fi
|
||||||
sudo -u "$ACTUAL_USER" sed -i "s%REMOTE_SERVER_HOSTNAME=.*%REMOTE_SERVER_HOSTNAME=$REMOTE_SERVER_HOSTNAME%" "$REPO_DIR/.env"
|
done
|
||||||
sudo -u "$ACTUAL_USER" sed -i "s%REMOTE_SERVER_USER=.*%REMOTE_SERVER_USER=$REMOTE_SERVER_USER%" "$REPO_DIR/.env"
|
|
||||||
sudo -u "$ACTUAL_USER" sed -i "s%REMOTE_SERVER_PASSWORD=.*%REMOTE_SERVER_PASSWORD=$REMOTE_SERVER_PASSWORD%" "$REPO_DIR/.env"
|
# Update HOMEPAGE_ALLOWED_HOSTS dynamically
|
||||||
sudo -u "$ACTUAL_USER" sed -i "s%TZ=.*%TZ=$TZ%" "$REPO_DIR/.env"
|
if [ -n "${DOMAIN:-}" ] && [ -n "${SERVER_IP:-}" ]; then
|
||||||
|
# Allow user to specify homepage subdomain
|
||||||
|
HOMEPAGE_SUBDOMAIN="${HOMEPAGE_SUBDOMAIN:-homepage}"
|
||||||
|
HOMEPAGE_ALLOWED_HOSTS="${HOMEPAGE_SUBDOMAIN}.${DOMAIN},${SERVER_IP}:3003"
|
||||||
|
sudo -u "$ACTUAL_USER" sed -i "s|HOMEPAGE_ALLOWED_HOSTS=.*|HOMEPAGE_ALLOWED_HOSTS=$HOMEPAGE_ALLOWED_HOSTS|" "$REPO_DIR/.env"
|
||||||
|
fi
|
||||||
|
|
||||||
# Authelia settings (only generate secrets if deploying core)
|
# Authelia settings (only generate secrets if deploying core)
|
||||||
if [ "$DEPLOY_CORE" = true ]; then
|
if [ "$DEPLOY_CORE" = true ]; then
|
||||||
@@ -471,141 +752,6 @@ validate_secrets() {
|
|||||||
debug_log "Secret validation passed"
|
debug_log "Secret validation passed"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Prompt for required values
|
|
||||||
prompt_for_values() {
|
|
||||||
echo ""
|
|
||||||
log_info "Configuration Setup:"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Set defaults from env file or hardcoded fallbacks
|
|
||||||
DEFAULT_DOMAIN="${DOMAIN:-example.duckdns.org}"
|
|
||||||
DEFAULT_SERVER_IP="${SERVER_IP:-$(hostname -I | awk '{print $1}')}"
|
|
||||||
DEFAULT_CORE_SERVER_IP="${CORE_SERVER_IP:-}"
|
|
||||||
DEFAULT_SERVER_HOSTNAME="${SERVER_HOSTNAME:-$(hostname)}"
|
|
||||||
DEFAULT_REMOTE_SERVER_IP="${REMOTE_SERVER_IP:-}"
|
|
||||||
DEFAULT_REMOTE_SERVER_HOSTNAME="${REMOTE_SERVER_HOSTNAME:-}"
|
|
||||||
DEFAULT_REMOTE_SERVER_USER="${REMOTE_SERVER_USER:-${DEFAULT_USER}}"
|
|
||||||
DEFAULT_REMOTE_SERVER_PASSWORD="${REMOTE_SERVER_PASSWORD:-}"
|
|
||||||
DEFAULT_TZ="${TZ:-America/New_York}"
|
|
||||||
|
|
||||||
# Display current/default configuration
|
|
||||||
echo "Please review the following configuration:"
|
|
||||||
echo " Domain: $DEFAULT_DOMAIN"
|
|
||||||
echo " Server IP: $DEFAULT_SERVER_IP"
|
|
||||||
echo " Server Hostname: $DEFAULT_SERVER_HOSTNAME"
|
|
||||||
echo " Remote Server IP: $DEFAULT_REMOTE_SERVER_IP"
|
|
||||||
echo " Remote Server Hostname: $DEFAULT_REMOTE_SERVER_HOSTNAME"
|
|
||||||
echo " Remote Server User: $DEFAULT_REMOTE_SERVER_USER"
|
|
||||||
if [ -n "$DEFAULT_REMOTE_SERVER_PASSWORD" ]; then
|
|
||||||
echo " Remote Server Password: [HIDDEN]"
|
|
||||||
else
|
|
||||||
echo " Remote Server Password: Not set"
|
|
||||||
fi
|
|
||||||
echo " Timezone: $DEFAULT_TZ"
|
|
||||||
|
|
||||||
if [ "$DEPLOY_CORE" = false ] && [ -z "$DEFAULT_CORE_SERVER_IP" ]; then
|
|
||||||
echo " Core Server IP: [Will be prompted for multi-server TLS]"
|
|
||||||
elif [ -n "$DEFAULT_CORE_SERVER_IP" ]; then
|
|
||||||
echo " Core Server IP: $DEFAULT_CORE_SERVER_IP"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$DEPLOY_CORE" = true ]; then
|
|
||||||
DEFAULT_ADMIN_USER="${DEFAULT_USER:-admin}"
|
|
||||||
DEFAULT_ADMIN_EMAIL="${DEFAULT_EMAIL:-${DEFAULT_ADMIN_USER}@${DEFAULT_DOMAIN}}"
|
|
||||||
echo " Admin User: $DEFAULT_ADMIN_USER"
|
|
||||||
echo " Admin Email: $DEFAULT_ADMIN_EMAIL"
|
|
||||||
echo " Admin Password: [Will be prompted if needed]"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
read -p "Use these default values? (Y/n): " -n 1 -r
|
|
||||||
echo ""
|
|
||||||
if [[ $REPLY =~ ^[Nn]$ ]]; then
|
|
||||||
echo "Please enter custom values:"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Domain
|
|
||||||
read -p "Domain [$DEFAULT_DOMAIN]: " DOMAIN
|
|
||||||
DOMAIN="${DOMAIN:-$DEFAULT_DOMAIN}"
|
|
||||||
|
|
||||||
# Server IP
|
|
||||||
read -p "Server IP [$DEFAULT_SERVER_IP]: " SERVER_IP
|
|
||||||
SERVER_IP="${SERVER_IP:-$DEFAULT_SERVER_IP}"
|
|
||||||
|
|
||||||
# Server Hostname
|
|
||||||
read -p "Server Hostname [$DEFAULT_SERVER_HOSTNAME]: " SERVER_HOSTNAME
|
|
||||||
SERVER_HOSTNAME="${SERVER_HOSTNAME:-$DEFAULT_SERVER_HOSTNAME}"
|
|
||||||
|
|
||||||
# Remote Server IP
|
|
||||||
read -p "Remote Server IP [$DEFAULT_REMOTE_SERVER_IP]: " REMOTE_SERVER_IP
|
|
||||||
REMOTE_SERVER_IP="${REMOTE_SERVER_IP:-$DEFAULT_REMOTE_SERVER_IP}"
|
|
||||||
|
|
||||||
# Remote Server Hostname
|
|
||||||
read -p "Remote Server Hostname [$DEFAULT_REMOTE_SERVER_HOSTNAME]: " REMOTE_SERVER_HOSTNAME
|
|
||||||
REMOTE_SERVER_HOSTNAME="${REMOTE_SERVER_HOSTNAME:-$DEFAULT_REMOTE_SERVER_HOSTNAME}"
|
|
||||||
|
|
||||||
# Remote Server User
|
|
||||||
read -p "Remote Server User [$DEFAULT_REMOTE_SERVER_USER]: " REMOTE_SERVER_USER
|
|
||||||
REMOTE_SERVER_USER="${REMOTE_SERVER_USER:-$DEFAULT_REMOTE_SERVER_USER}"
|
|
||||||
|
|
||||||
# Remote Server Password
|
|
||||||
read -s -p "Remote Server Password: " REMOTE_SERVER_PASSWORD
|
|
||||||
echo ""
|
|
||||||
if [ -z "$REMOTE_SERVER_PASSWORD" ]; then
|
|
||||||
REMOTE_SERVER_PASSWORD="$DEFAULT_REMOTE_SERVER_PASSWORD"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Timezone
|
|
||||||
read -p "Timezone [$DEFAULT_TZ]: " TZ
|
|
||||||
TZ="${TZ:-$DEFAULT_TZ}"
|
|
||||||
|
|
||||||
# Core server IP (for multi-server setup)
|
|
||||||
if [ "$DEPLOY_CORE" = false ]; then
|
|
||||||
echo ""
|
|
||||||
read -p "Core server IP (for shared TLS CA): " CORE_SERVER_IP
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Admin credentials (only if deploying core)
|
|
||||||
if [ "$DEPLOY_CORE" = true ]; then
|
|
||||||
echo ""
|
|
||||||
log_info "Authelia Admin Credentials:"
|
|
||||||
|
|
||||||
read -p "Admin username [$DEFAULT_ADMIN_USER]: " ADMIN_USER
|
|
||||||
ADMIN_USER="${ADMIN_USER:-$DEFAULT_ADMIN_USER}"
|
|
||||||
|
|
||||||
read -p "Admin email [$DEFAULT_ADMIN_EMAIL]: " ADMIN_EMAIL
|
|
||||||
ADMIN_EMAIL="${ADMIN_EMAIL:-$DEFAULT_ADMIN_EMAIL}"
|
|
||||||
|
|
||||||
if [ -z "$ADMIN_PASSWORD" ]; then
|
|
||||||
while [ -z "$ADMIN_PASSWORD" ]; do
|
|
||||||
read -s -p "Admin password (will be hashed): " ADMIN_PASSWORD
|
|
||||||
echo ""
|
|
||||||
if [ ${#ADMIN_PASSWORD} -lt 8 ]; then
|
|
||||||
log_warning "Password must be at least 8 characters"
|
|
||||||
ADMIN_PASSWORD=""
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
else
|
|
||||||
log_info "Admin password already configured"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Use defaults
|
|
||||||
DOMAIN="$DEFAULT_DOMAIN"
|
|
||||||
SERVER_IP="$DEFAULT_SERVER_IP"
|
|
||||||
SERVER_HOSTNAME="$DEFAULT_SERVER_HOSTNAME"
|
|
||||||
TZ="$DEFAULT_TZ"
|
|
||||||
CORE_SERVER_IP="$DEFAULT_CORE_SERVER_IP"
|
|
||||||
|
|
||||||
if [ "$DEPLOY_CORE" = true ]; then
|
|
||||||
ADMIN_USER="$DEFAULT_ADMIN_USER"
|
|
||||||
ADMIN_EMAIL="$DEFAULT_ADMIN_EMAIL"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
}
|
|
||||||
|
|
||||||
# System setup function (Docker, directories, etc.)
|
# System setup function (Docker, directories, etc.)
|
||||||
system_setup() {
|
system_setup() {
|
||||||
log_info "Performing system setup..."
|
log_info "Performing system setup..."
|
||||||
@@ -1057,13 +1203,7 @@ perform_deployment() {
|
|||||||
log_info "Please update your .env file and redeploy affected stacks."
|
log_info "Please update your .env file and redeploy affected stacks."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Report any TLS issues
|
# TLS issues will be reported in the final summary
|
||||||
if [ -n "$TLS_ISSUES_SUMMARY" ]; then
|
|
||||||
echo ""
|
|
||||||
log_warning "TLS Configuration Issues Detected:"
|
|
||||||
echo "$TLS_ISSUES_SUMMARY"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Setup Docker TLS function
|
# Setup Docker TLS function
|
||||||
@@ -1186,28 +1326,18 @@ setup_stacks_for_dockge() {
|
|||||||
|
|
||||||
# Main menu
|
# Main menu
|
||||||
show_main_menu() {
|
show_main_menu() {
|
||||||
echo "=========================================="
|
clear
|
||||||
echo " EZ-HOMELAB SETUP & DEPLOYMENT"
|
|
||||||
echo "=========================================="
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "What would you like to do?"
|
echo "╔═════════════════════════════════════════════════════════════╗"
|
||||||
echo ""
|
echo "║ EZ-HOMELAB SETUP & DEPLOYMENT ║"
|
||||||
echo "1) 🚀 Default Setup (Recommended)"
|
echo "║ ║"
|
||||||
echo " - Deploy Dockge, core infrastructure, dashboards & monitoring"
|
echo "║ 1) Install Prerequisites ║"
|
||||||
echo " - All additional stacks prepared for Dockge"
|
echo "║ 2) Deploy Core Server ║"
|
||||||
echo ""
|
echo "║ 3) Deploy Additional Server ║"
|
||||||
echo "2) 🏗️ Core Only"
|
echo "║ 4) Install NVIDIA Drivers ║"
|
||||||
echo " - Deploy Dockge and core infrastructure only"
|
echo "║ ║"
|
||||||
echo " - All stacks prepared for Dockge"
|
echo "║ q) Quit ║"
|
||||||
echo ""
|
echo "╚═════════════════════════════════════════════════════════════╝"
|
||||||
echo "3) 🔧 Infrastructure Only"
|
|
||||||
echo " - Deploy Dockge and monitoring tools"
|
|
||||||
echo " - Requires existing Traefik (from previous setup)"
|
|
||||||
echo " - Configures TLS for remote Docker access (Sablier)"
|
|
||||||
echo " - Services accessible without authentication"
|
|
||||||
echo " - All stacks prepared for Dockge"
|
|
||||||
echo ""
|
|
||||||
echo "4) ❌ Exit"
|
|
||||||
echo ""
|
echo ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1228,31 +1358,24 @@ main() {
|
|||||||
|
|
||||||
# Show main menu
|
# Show main menu
|
||||||
show_main_menu
|
show_main_menu
|
||||||
read -p "Choose an option (1-4): " MAIN_CHOICE
|
read -p "Choose an option (1-3): " MAIN_CHOICE
|
||||||
|
|
||||||
case $MAIN_CHOICE in
|
case $MAIN_CHOICE in
|
||||||
1)
|
1)
|
||||||
log_info "Selected: Default Setup"
|
log_info "Selected: Core Server"
|
||||||
DEPLOY_CORE=true
|
DEPLOY_CORE=true
|
||||||
DEPLOY_INFRASTRUCTURE=true
|
DEPLOY_INFRASTRUCTURE=true
|
||||||
DEPLOY_DASHBOARDS=true
|
DEPLOY_DASHBOARDS=true
|
||||||
SETUP_STACKS=true
|
SETUP_STACKS=true
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
log_info "Selected: Core Only"
|
log_info "Selected: Additional Server"
|
||||||
DEPLOY_CORE=true
|
|
||||||
DEPLOY_INFRASTRUCTURE=false
|
|
||||||
DEPLOY_DASHBOARDS=true
|
|
||||||
SETUP_STACKS=true
|
|
||||||
;;
|
|
||||||
3)
|
|
||||||
log_info "Selected: Infrastructure Only"
|
|
||||||
DEPLOY_CORE=false
|
DEPLOY_CORE=false
|
||||||
DEPLOY_INFRASTRUCTURE=true
|
DEPLOY_INFRASTRUCTURE=true
|
||||||
DEPLOY_DASHBOARDS=false
|
DEPLOY_DASHBOARDS=false
|
||||||
SETUP_STACKS=true
|
SETUP_STACKS=true
|
||||||
;;
|
;;
|
||||||
4)
|
3)
|
||||||
log_info "Exiting..."
|
log_info "Exiting..."
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
@@ -1316,11 +1439,14 @@ main() {
|
|||||||
log_success "Directories ready"
|
log_success "Directories ready"
|
||||||
|
|
||||||
# Prompt for configuration values
|
# Prompt for configuration values
|
||||||
prompt_for_values
|
validate_and_prompt_variables
|
||||||
|
|
||||||
# Save configuration
|
# Save configuration
|
||||||
save_env_file
|
save_env_file
|
||||||
|
|
||||||
|
# Perform enhanced placeholder replacement across all config files
|
||||||
|
enhance_placeholder_replacement
|
||||||
|
|
||||||
# Validate secrets for core deployment
|
# Validate secrets for core deployment
|
||||||
validate_secrets
|
validate_secrets
|
||||||
|
|
||||||
@@ -1329,36 +1455,49 @@ main() {
|
|||||||
|
|
||||||
# Show completion message
|
# Show completion message
|
||||||
echo ""
|
echo ""
|
||||||
echo "=========================================="
|
echo "╔═════════════════════════════════════════════════════════════╗"
|
||||||
log_success "Setup and deployment completed successfully!"
|
echo "║ Deployment Complete! ║"
|
||||||
echo "=========================================="
|
echo "║ SSL Certificates may take a few minutes to be issued. ║"
|
||||||
echo ""
|
echo "║ ║"
|
||||||
|
echo "║ https://dockge.kelinreij.duckdns.org ║"
|
||||||
|
echo "║ http://192.168.4.4:5001 ║"
|
||||||
|
echo "║ ║"
|
||||||
|
echo "║ https://homepage.kelinreij.duckdns.org ║"
|
||||||
|
echo "║ http://192.168.4.4:3003 ║"
|
||||||
|
echo "║ ║"
|
||||||
|
echo "╚═════════════════════════════════════════════════════════════╝"
|
||||||
|
|
||||||
if [ "$DEPLOY_INFRASTRUCTURE" = true ]; then
|
# Show consolidated warnings if any
|
||||||
log_info "Access your services:"
|
if [ -n "$MISSING_VARS_SUMMARY" ] || [ -n "$TLS_ISSUES_SUMMARY" ]; then
|
||||||
echo ""
|
echo "╔═════════════════════════════════════════════════════════════╗"
|
||||||
echo " 🚀 Dockge: https://dockge.${DOMAIN}"
|
echo "║ ⚠️ WARNING ⚠️ ║"
|
||||||
[ "$DEPLOY_CORE" = true ] && echo " 🔒 Authelia: https://auth.${DOMAIN}"
|
echo "║ The following variables were not defined ║"
|
||||||
[ "$DEPLOY_CORE" = true ] && echo " 🔀 Traefik: https://traefik.${DOMAIN}"
|
echo "║ If something isn't working as expected check these first ║"
|
||||||
echo " 📊 Homepage: https://homepage.${DOMAIN}"
|
echo "║ ║"
|
||||||
echo ""
|
|
||||||
|
if [ -n "$MISSING_VARS_SUMMARY" ]; then
|
||||||
|
log_warning "Missing Environment Variables:"
|
||||||
|
echo "$MISSING_VARS_SUMMARY"
|
||||||
|
echo "║ ║"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log_info "Next steps:"
|
if [ -n "$TLS_ISSUES_SUMMARY" ]; then
|
||||||
echo ""
|
log_warning "TLS Configuration Issues:"
|
||||||
echo " 1. Access Dockge at https://dockge.${DOMAIN}"
|
echo "$TLS_ISSUES_SUMMARY"
|
||||||
if [ "$DEPLOY_CORE" = true ]; then
|
echo "║ ║"
|
||||||
echo " (Use your Authelia credentials: ${AUTHELIA_ADMIN_USER})"
|
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
echo "╚═════════════════════════════════════════════════════════════╝"
|
||||||
|
|
||||||
|
echo "╔══════════════════════════════════════════╗"
|
||||||
|
echo "║ 📚 RESOURCES ║"
|
||||||
|
echo "╚══════════════════════════════════════════╝"
|
||||||
echo ""
|
echo ""
|
||||||
echo " 2. Start additional stacks from Dockge's web UI"
|
echo " 📖 Documentation: $REPO_DIR/docs/"
|
||||||
|
echo " 🔧 Quick Reference: $REPO_DIR/docs/quick-reference.md"
|
||||||
|
echo " 🐙 Repository: https://github.com/your-repo/ez-homelab"
|
||||||
|
echo " 📋 Wiki: https://github.com/your-repo/ez-homelab/wiki"
|
||||||
echo ""
|
echo ""
|
||||||
echo " 3. Configure services via the AI assistant in VS Code"
|
|
||||||
echo ""
|
|
||||||
echo "=========================================="
|
|
||||||
echo ""
|
|
||||||
log_info "For documentation, see: $REPO_DIR/docs/"
|
|
||||||
log_info "For troubleshooting, see: $REPO_DIR/docs/quick-reference.md"
|
|
||||||
debug_log "Script completed successfully"
|
debug_log "Script completed successfully"
|
||||||
echo ""
|
echo ""
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user