All tweaks added
Build and push images / build-backend (push) Successful in 33s
Build and push images / build-worker (push) Successful in 32s
Build and push images / build-frontend (push) Failing after 6s

This commit is contained in:
2026-06-06 18:10:35 +01:00
parent 043b3b7269
commit ec5a01d12a
92 changed files with 7517 additions and 784 deletions
+209
View File
@@ -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 35 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 ""