All tweaks added
This commit is contained in:
Executable
+209
@@ -0,0 +1,209 @@
|
||||
#!/usr/bin/env bash
|
||||
# MileVault installer
|
||||
# Usage: curl -fsSL https://raw.githubusercontent.com/you/milevault/main/install.sh | bash
|
||||
# Or: bash install.sh
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
|
||||
BOLD='\033[1m'
|
||||
|
||||
info() { echo -e "${GREEN}✓${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}!${NC} $*"; }
|
||||
error() { echo -e "${RED}✗ $*${NC}"; exit 1; }
|
||||
step() { echo -e "\n${CYAN}${BOLD}── $* ──${NC}"; }
|
||||
|
||||
echo -e "${BOLD}"
|
||||
echo " ███████╗██╗████████╗████████╗██████╗ █████╗ ██████╗██╗ ██╗███████╗██████╗ "
|
||||
echo " ██╔════╝██║╚══██╔══╝╚══██╔══╝██╔══██╗██╔══██╗██╔════╝██║ ██╔╝██╔════╝██╔══██╗"
|
||||
echo " █████╗ ██║ ██║ ██║ ██████╔╝███████║██║ █████╔╝ █████╗ ██████╔╝"
|
||||
echo " ██╔══╝ ██║ ██║ ██║ ██╔══██╗██╔══██║██║ ██╔═██╗ ██╔══╝ ██╔══██╗"
|
||||
echo " ██║ ██║ ██║ ██║ ██║ ██║██║ ██║╚██████╗██║ ██╗███████╗██║ ██║"
|
||||
echo " ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝"
|
||||
echo -e "${NC}"
|
||||
echo " Self-hosted fitness tracking — Garmin & Strava"
|
||||
echo ""
|
||||
|
||||
# ── Preflight checks ──────────────────────────────────────────────────────────
|
||||
|
||||
step "Checking requirements"
|
||||
|
||||
command -v docker >/dev/null 2>&1 || error "Docker is not installed. Install from https://docs.docker.com/get-docker/"
|
||||
info "Docker found: $(docker --version | head -1)"
|
||||
|
||||
# Check docker compose (v2 plugin or v1 standalone)
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
COMPOSE_CMD="docker compose"
|
||||
elif command -v docker-compose >/dev/null 2>&1; then
|
||||
COMPOSE_CMD="docker-compose"
|
||||
else
|
||||
error "Docker Compose not found. Install from https://docs.docker.com/compose/install/"
|
||||
fi
|
||||
info "Docker Compose found: $($COMPOSE_CMD version | head -1)"
|
||||
|
||||
# Check Docker daemon is running
|
||||
docker info >/dev/null 2>&1 || error "Docker daemon is not running. Start Docker and retry."
|
||||
info "Docker daemon is running"
|
||||
|
||||
# ── Install directory ─────────────────────────────────────────────────────────
|
||||
|
||||
step "Setting up install directory"
|
||||
|
||||
INSTALL_DIR="${FITTRACKER_DIR:-$HOME/milevault}"
|
||||
|
||||
if [ -d "$INSTALL_DIR" ] && [ "$(ls -A "$INSTALL_DIR" 2>/dev/null)" ]; then
|
||||
warn "Directory $INSTALL_DIR already exists."
|
||||
read -rp " Continue and update existing install? [y/N] " confirm
|
||||
[[ "$confirm" =~ ^[Yy]$ ]] || { echo "Aborted."; exit 0; }
|
||||
fi
|
||||
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
cd "$INSTALL_DIR"
|
||||
info "Install directory: $INSTALL_DIR"
|
||||
|
||||
# ── Download project files ────────────────────────────────────────────────────
|
||||
|
||||
step "Downloading MileVault"
|
||||
|
||||
# If we're already inside the repo (files exist), skip download
|
||||
if [ -f "docker-compose.yml" ]; then
|
||||
info "Project files already present — skipping download"
|
||||
else
|
||||
# Try git first, fall back to curl
|
||||
if command -v git >/dev/null 2>&1; then
|
||||
git clone --depth 1 https://github.com/yourusername/milevault.git . 2>/dev/null || {
|
||||
warn "Git clone failed — copying bundled files instead"
|
||||
}
|
||||
fi
|
||||
|
||||
# Fallback: if running this script from inside a downloaded zip, the files are next to it
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
if [ "$SCRIPT_DIR" != "$INSTALL_DIR" ] && [ -f "$SCRIPT_DIR/docker-compose.yml" ]; then
|
||||
cp -r "$SCRIPT_DIR"/. "$INSTALL_DIR/"
|
||||
info "Copied project files from $SCRIPT_DIR"
|
||||
fi
|
||||
fi
|
||||
|
||||
[ -f "docker-compose.yml" ] || error "docker-compose.yml not found. Place install.sh inside the project directory."
|
||||
info "Project files ready"
|
||||
|
||||
# ── Generate .env ─────────────────────────────────────────────────────────────
|
||||
|
||||
step "Configuring environment"
|
||||
|
||||
if [ -f ".env" ]; then
|
||||
warn ".env already exists — skipping generation (delete it to regenerate)"
|
||||
else
|
||||
# Generate secure random values
|
||||
if command -v openssl >/dev/null 2>&1; then
|
||||
SECRET_KEY=$(openssl rand -hex 32)
|
||||
DB_PASSWORD=$(openssl rand -base64 18 | tr -d '/+=')
|
||||
REDIS_PASSWORD=$(openssl rand -base64 12 | tr -d '/+=')
|
||||
ADMIN_PASSWORD=$(openssl rand -base64 12 | tr -d '/+=')
|
||||
else
|
||||
# Fallback if openssl not available
|
||||
SECRET_KEY=$(cat /dev/urandom | tr -dc 'a-f0-9' | head -c 64)
|
||||
DB_PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 18)
|
||||
REDIS_PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 12)
|
||||
ADMIN_PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 12)
|
||||
fi
|
||||
|
||||
ADMIN_USERNAME="${FITTRACKER_ADMIN:-admin}"
|
||||
PORT="${FITTRACKER_PORT:-80}"
|
||||
|
||||
cat > .env << ENV
|
||||
# MileVault configuration — generated $(date)
|
||||
# Edit this file to change settings, then run: docker compose up -d
|
||||
|
||||
# Admin login
|
||||
ADMIN_USERNAME=${ADMIN_USERNAME}
|
||||
ADMIN_PASSWORD=${ADMIN_PASSWORD}
|
||||
|
||||
# Secrets (auto-generated — do not share)
|
||||
SECRET_KEY=${SECRET_KEY}
|
||||
DB_PASSWORD=${DB_PASSWORD}
|
||||
DB_USER=milevault
|
||||
REDIS_PASSWORD=${REDIS_PASSWORD}
|
||||
|
||||
# Server
|
||||
HTTP_PORT=${PORT}
|
||||
ENVIRONMENT=production
|
||||
|
||||
# Optional: Mapbox token for satellite map tiles (free at mapbox.com)
|
||||
VITE_MAPBOX_TOKEN=
|
||||
|
||||
# Optional: PocketID passkey authentication
|
||||
# POCKETID_ISSUER=https://your-pocketid.example.com
|
||||
# POCKETID_CLIENT_ID=milevault
|
||||
# POCKETID_CLIENT_SECRET=
|
||||
ENV
|
||||
|
||||
info ".env created with secure random secrets"
|
||||
|
||||
# Save credentials for display at end
|
||||
SHOW_CREDS=true
|
||||
fi
|
||||
|
||||
source .env
|
||||
|
||||
# ── Build & start ─────────────────────────────────────────────────────────────
|
||||
|
||||
step "Building and starting containers"
|
||||
echo " This takes 3–5 minutes on first run (building images)..."
|
||||
echo ""
|
||||
|
||||
$COMPOSE_CMD up -d --build
|
||||
|
||||
# ── Wait for healthy ──────────────────────────────────────────────────────────
|
||||
|
||||
step "Waiting for services to be ready"
|
||||
|
||||
TIMEOUT=120
|
||||
ELAPSED=0
|
||||
printf " Waiting"
|
||||
while ! docker inspect milevault_backend 2>/dev/null | grep -q '"healthy"' ; do
|
||||
if [ $ELAPSED -ge $TIMEOUT ]; then
|
||||
echo ""
|
||||
warn "Backend taking longer than expected. Check logs: docker compose logs backend"
|
||||
break
|
||||
fi
|
||||
printf "."
|
||||
sleep 3
|
||||
ELAPSED=$((ELAPSED + 3))
|
||||
done
|
||||
echo ""
|
||||
info "All services are up"
|
||||
|
||||
# ── Done ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
PORT="${HTTP_PORT:-80}"
|
||||
URL="http://localhost${PORT:+:${PORT}}"
|
||||
[[ "$PORT" == "80" ]] && URL="http://localhost"
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}${BOLD}╔══════════════════════════════════════════╗${NC}"
|
||||
echo -e "${GREEN}${BOLD}║ MileVault is ready! ║${NC}"
|
||||
echo -e "${GREEN}${BOLD}╚══════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e " 🌐 Open: ${CYAN}${URL}${NC}"
|
||||
echo -e " 👤 Username: ${BOLD}${ADMIN_USERNAME:-admin}${NC}"
|
||||
|
||||
if [ "${SHOW_CREDS:-false}" = "true" ]; then
|
||||
echo -e " 🔑 Password: ${BOLD}${ADMIN_PASSWORD}${NC}"
|
||||
echo ""
|
||||
warn "Save this password — it won't be shown again."
|
||||
warn "It's also stored in: ${INSTALL_DIR}/.env"
|
||||
else
|
||||
echo -e " 🔑 Password: (see ${INSTALL_DIR}/.env — ADMIN_PASSWORD)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo " Useful commands:"
|
||||
echo " docker compose logs -f # View live logs"
|
||||
echo " docker compose logs backend # Backend logs only"
|
||||
echo " docker compose down # Stop everything"
|
||||
echo " docker compose up -d # Start again"
|
||||
echo " docker compose pull && docker compose up -d --build # Update"
|
||||
echo ""
|
||||
echo " Import your data:"
|
||||
echo " Go to ${URL} → Import → upload your Garmin export ZIP or Strava ZIP"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user