feat(infra): install Ollama + full raw-VM bootstrap in setup.sh
This commit is contained in:
parent
2b9fd71740
commit
7c34cee0ab
@ -1,16 +1,18 @@
|
|||||||
# ByteLyst Single-VM Deployment
|
# ByteLyst Single-VM Deployment
|
||||||
|
|
||||||
> Deploy the **entire ByteLyst ecosystem** on a single Azure VM from scratch.
|
> Deploy the **entire ByteLyst ecosystem** on a single **raw** Azure VM.
|
||||||
|
> Nothing pre-installed required — the script handles everything from a blank Ubuntu machine.
|
||||||
> Two files: this README and `setup.sh`. Copy both to the VM and run the script.
|
> Two files: this README and `setup.sh`. Copy both to the VM and run the script.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- **Azure VM:** Ubuntu 24.04 LTS (or 22.04), Standard_D8s_v5 (8 vCPU, 32 GB RAM) recommended
|
- **Azure VM:** Ubuntu 24.04 LTS (or 22.04), **Standard_D8s_v5** (8 vCPU, 32 GB RAM) recommended
|
||||||
- **Disk:** 100 GB+ (Docker images, Cosmos emulator, build artifacts)
|
- **Disk:** 128 GB+ (Docker images, Cosmos emulator, Ollama models, build artifacts)
|
||||||
- **Network:** NSG allowing inbound on ports 80, 3000-3100, 4003-4019, 8025, 8080, 8081
|
- **Network:** NSG allowing inbound on ports listed in the Port Map below
|
||||||
- **GitHub access:** Repos must be accessible (public or deploy key configured)
|
- **GitHub access:** Repos must be accessible (public or `GITHUB_TOKEN` for private)
|
||||||
|
- **Nothing else needed** — the script installs Docker, Node.js, pnpm, Gitea, Ollama, and everything
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
@ -31,25 +33,39 @@ sudo ./setup.sh
|
|||||||
docker compose -f /opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml ps
|
docker compose -f /opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml ps
|
||||||
```
|
```
|
||||||
|
|
||||||
## What the Script Does
|
## What the Script Installs & Does
|
||||||
|
|
||||||
|
### Software installed on the VM (from scratch)
|
||||||
|
|
||||||
|
| Software | Version | Purpose |
|
||||||
|
|----------|---------|----------|
|
||||||
|
| **Docker CE** | latest | Container runtime + Compose + BuildKit |
|
||||||
|
| **Node.js** | 22 LTS | Build toolchain for TypeScript packages |
|
||||||
|
| **pnpm** | 10.6.5 | Package manager (workspace-aware) |
|
||||||
|
| **Gitea** | 1.22 (Docker) | Local npm package registry on `:3300` |
|
||||||
|
| **Ollama** | latest | Local LLM inference for LocalMemGPT on `:11434` |
|
||||||
|
| **git, jq, curl** | latest | System utilities |
|
||||||
|
|
||||||
|
### Execution phases
|
||||||
|
|
||||||
| Phase | Duration | Description |
|
| Phase | Duration | Description |
|
||||||
|-------|----------|-------------|
|
|-------|----------|-------------|
|
||||||
| 1. System | ~2 min | Install Docker, Node.js 22, pnpm 10.6.5, git |
|
| 1. System | ~3 min | Install Docker, Node.js 22, pnpm 10.6.5, Ollama, git, jq |
|
||||||
| 2. Gitea | ~1 min | Start Gitea Docker container (npm registry on :3300) |
|
| 2. Gitea | ~1 min | Start Gitea Docker container, create admin + org + API token |
|
||||||
| 3. Clone | ~3 min | Clone all 11 repos to `/opt/bytelyst/` |
|
| 3. Clone | ~3 min | Clone all 11 repos to `/opt/bytelyst/`, strip corporate proxy from Dockerfiles |
|
||||||
| 4. Build | ~5 min | Build all `@bytelyst/*` packages in common-plat |
|
| 4. Build | ~5 min | `pnpm install && pnpm -r build` all `@bytelyst/*` packages |
|
||||||
| 5. Publish | ~3 min | Publish all packages to local Gitea npm registry |
|
| 5. Publish | ~3 min | Publish all packages to local Gitea npm registry |
|
||||||
| 6. Env | instant | Generate `.env.ecosystem` with all required values |
|
| 6. Env | instant | Generate `.env.ecosystem` with Cosmos emulator key, Azurite key, JWT secret |
|
||||||
| 7. Deploy | ~10 min | `docker compose up --build` for 27 services |
|
| 7. Deploy | ~10 min | `docker compose up --build` for 27 services |
|
||||||
| 8. Verify | ~1 min | Health-check all services |
|
| 8. Verify | ~1 min | Health-check all services + create `/opt/bytelyst/check-health.sh` |
|
||||||
|
|
||||||
## Port Map (after deployment)
|
## Port Map (after deployment)
|
||||||
|
|
||||||
### Infrastructure
|
### Infrastructure (installed by setup.sh)
|
||||||
| Service | Port | URL |
|
| Service | Port | URL |
|
||||||
|---------|------|-----|
|
|---------|------|-----|
|
||||||
| Gitea (npm registry) | 3300 | `http://<vm-ip>:3300` |
|
| Gitea (npm registry) | 3300 | `http://<vm-ip>:3300` |
|
||||||
|
| Ollama (LLM API) | 11434 | `http://<vm-ip>:11434` |
|
||||||
| Cosmos Data Explorer | 1234 | `http://<vm-ip>:1234` |
|
| Cosmos Data Explorer | 1234 | `http://<vm-ip>:1234` |
|
||||||
| Azurite (Blob) | 10000 | — |
|
| Azurite (Blob) | 10000 | — |
|
||||||
| Mailpit UI | 8025 | `http://<vm-ip>:8025` |
|
| Mailpit UI | 8025 | `http://<vm-ip>:8025` |
|
||||||
@ -117,9 +133,25 @@ docker compose -f /opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem
|
|||||||
docker compose -f /opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml down -v
|
docker compose -f /opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml down -v
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
All optional — defaults work for most setups:
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `GITHUB_USER` | `saravanakumardb1` | GitHub org/user to clone repos from |
|
||||||
|
| `GITHUB_TOKEN` | (empty) | Set for private repos (HTTPS auth) |
|
||||||
|
| `GITEA_ADMIN` | `bytelyst-admin` | Gitea admin username |
|
||||||
|
| `GITEA_PASS` | `ByteLyst2026!` | Gitea admin password |
|
||||||
|
| `OLLAMA_MODEL` | `llama3.2:3b` | Default LLM model to pull |
|
||||||
|
| `SKIP_CLONE` | `0` | Set `1` to skip cloning (re-runs) |
|
||||||
|
| `SKIP_BUILD` | `0` | Set `1` to skip package build+publish (re-runs) |
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
- **Cosmos emulator slow:** It needs 20-30s on first boot. Services wait via health checks.
|
- **Cosmos emulator slow:** It needs 20-30s on first boot. Services wait via health checks.
|
||||||
- **Out of memory:** Use at least 32 GB RAM. The Cosmos emulator alone needs ~4 GB.
|
- **Out of memory:** Use at least 32 GB RAM. Cosmos emulator needs ~4 GB, Ollama needs ~4 GB for 3B models.
|
||||||
- **Build failures:** Check that Gitea is running (`docker ps | grep gitea`) and packages published (`curl http://localhost:3300/api/packages/bytelyst/npm/`).
|
- **Build failures:** Check Gitea is running (`docker ps | grep gitea`) and packages published (`curl http://localhost:3300/api/packages/bytelyst/npm/`).
|
||||||
|
- **Ollama not responding:** Check `systemctl status ollama` or `curl http://localhost:11434/api/version`.
|
||||||
- **Port conflicts:** Ensure nothing else runs on the listed ports before deploying.
|
- **Port conflicts:** Ensure nothing else runs on the listed ports before deploying.
|
||||||
|
- **Corporate proxy in Dockerfiles:** The script auto-strips hardcoded proxy ENVs from cloned Dockerfiles.
|
||||||
|
|||||||
@ -2,14 +2,26 @@
|
|||||||
# ═══════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════
|
||||||
# ByteLyst Single-VM Bootstrap Script
|
# ByteLyst Single-VM Bootstrap Script
|
||||||
# ═══════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════
|
||||||
# Deploys the ENTIRE ByteLyst ecosystem on a fresh Ubuntu Azure VM.
|
# Deploys the ENTIRE ByteLyst ecosystem on a **raw** Ubuntu Azure VM.
|
||||||
|
# Installs ALL dependencies from scratch — nothing pre-installed required.
|
||||||
|
#
|
||||||
|
# What gets installed:
|
||||||
|
# - Docker CE + Docker Compose + BuildKit
|
||||||
|
# - Node.js 22 LTS + pnpm 10.6.5
|
||||||
|
# - Gitea (Docker container — npm package registry on :3300)
|
||||||
|
# - Ollama (local LLM inference for LocalMemGPT on :11434)
|
||||||
|
# - All 11 ByteLyst repos (cloned from GitHub)
|
||||||
|
# - All @bytelyst/* packages (built + published to Gitea)
|
||||||
|
# - Full 27-service ecosystem (via docker-compose.ecosystem.yml)
|
||||||
#
|
#
|
||||||
# Usage: sudo ./setup.sh
|
# Usage: sudo ./setup.sh
|
||||||
|
#
|
||||||
# Optional env vars:
|
# Optional env vars:
|
||||||
# GITHUB_USER — GitHub org/user to clone from (default: saravanakumardb1)
|
# GITHUB_USER — GitHub org/user to clone from (default: saravanakumardb1)
|
||||||
# GITHUB_TOKEN — If repos are private, set this for HTTPS auth
|
# GITHUB_TOKEN — If repos are private, set this for HTTPS auth
|
||||||
# GITEA_ADMIN — Gitea admin username (default: bytelyst-admin)
|
# GITEA_ADMIN — Gitea admin username (default: bytelyst-admin)
|
||||||
# GITEA_PASS — Gitea admin password (default: ByteLyst2026!)
|
# GITEA_PASS — Gitea admin password (default: ByteLyst2026!)
|
||||||
|
# OLLAMA_MODEL — Default LLM model to pull (default: llama3.2:3b)
|
||||||
# SKIP_CLONE — Set to 1 to skip cloning (repos already exist)
|
# SKIP_CLONE — Set to 1 to skip cloning (repos already exist)
|
||||||
# SKIP_BUILD — Set to 1 to skip package build+publish
|
# SKIP_BUILD — Set to 1 to skip package build+publish
|
||||||
# ═══════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════
|
||||||
@ -24,6 +36,7 @@ GITEA_PORT=3300
|
|||||||
NODE_VERSION=22
|
NODE_VERSION=22
|
||||||
PNPM_VERSION="10.6.5"
|
PNPM_VERSION="10.6.5"
|
||||||
COMPOSE_FILE="docker-compose.ecosystem.yml"
|
COMPOSE_FILE="docker-compose.ecosystem.yml"
|
||||||
|
OLLAMA_MODEL="${OLLAMA_MODEL:-llama3.2:3b}"
|
||||||
|
|
||||||
# Well-known emulator keys (public, safe to embed)
|
# Well-known emulator keys (public, safe to embed)
|
||||||
COSMOS_EMULATOR_KEY="C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
|
COSMOS_EMULATOR_KEY="C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
|
||||||
@ -130,6 +143,34 @@ DJSON
|
|||||||
ok "pnpm already installed: $(pnpm -v)"
|
ok "pnpm already installed: $(pnpm -v)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ── Ollama (local LLM inference) ──────────────────────────────────
|
||||||
|
if ! command -v ollama &>/dev/null; then
|
||||||
|
log "Installing Ollama..."
|
||||||
|
curl -fsSL https://ollama.com/install.sh | sh
|
||||||
|
ok "Ollama installed: $(ollama --version 2>&1 || echo 'ok')"
|
||||||
|
else
|
||||||
|
ok "Ollama already installed: $(ollama --version 2>&1 || echo 'ok')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start Ollama service (systemd)
|
||||||
|
if ! systemctl is-active --quiet ollama 2>/dev/null; then
|
||||||
|
systemctl enable --now ollama 2>/dev/null || true
|
||||||
|
# Fallback: start manually if not using systemd
|
||||||
|
if ! curl -sf http://localhost:11434/api/version > /dev/null 2>&1; then
|
||||||
|
nohup ollama serve > /var/log/ollama.log 2>&1 &
|
||||||
|
sleep 3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Wait for Ollama API
|
||||||
|
log "Waiting for Ollama API..."
|
||||||
|
wait_for_url "http://localhost:11434/api/version" 30
|
||||||
|
|
||||||
|
# Pull default model
|
||||||
|
log "Pulling Ollama model: ${OLLAMA_MODEL} (this may take a few minutes)..."
|
||||||
|
ollama pull "$OLLAMA_MODEL" 2>&1 | tail -3
|
||||||
|
ok "Ollama ready with model: ${OLLAMA_MODEL}"
|
||||||
|
|
||||||
# ── Create install directory ───────────────────────────────────────
|
# ── Create install directory ───────────────────────────────────────
|
||||||
mkdir -p "$INSTALL_DIR"
|
mkdir -p "$INSTALL_DIR"
|
||||||
|
|
||||||
@ -502,6 +543,7 @@ check() {
|
|||||||
echo ""
|
echo ""
|
||||||
echo "═══ Infrastructure ═══"
|
echo "═══ Infrastructure ═══"
|
||||||
check "Gitea (npm)" "http://localhost:3300/api/v1/version"
|
check "Gitea (npm)" "http://localhost:3300/api/v1/version"
|
||||||
|
check "Ollama (LLM)" "http://localhost:11434/api/version"
|
||||||
check "Cosmos Explorer" "http://localhost:1234"
|
check "Cosmos Explorer" "http://localhost:1234"
|
||||||
check "Mailpit" "http://localhost:8025"
|
check "Mailpit" "http://localhost:8025"
|
||||||
check "Grafana" "http://localhost:3000/api/health"
|
check "Grafana" "http://localhost:3000/api/health"
|
||||||
@ -562,8 +604,8 @@ HEALTH
|
|||||||
main() {
|
main() {
|
||||||
echo ""
|
echo ""
|
||||||
echo "╔═══════════════════════════════════════════════════════════════╗"
|
echo "╔═══════════════════════════════════════════════════════════════╗"
|
||||||
echo "║ ByteLyst Single-VM Deployment ║"
|
echo "║ ByteLyst Single-VM Deployment (raw Ubuntu) ║"
|
||||||
echo "║ 27 services · 10 products · 1 VM ║"
|
echo "║ 27 services · 10 products · Ollama · Gitea · 1 VM ║"
|
||||||
echo "╚═══════════════════════════════════════════════════════════════╝"
|
echo "╚═══════════════════════════════════════════════════════════════╝"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
@ -572,6 +614,10 @@ main() {
|
|||||||
local start_time
|
local start_time
|
||||||
start_time=$(date +%s)
|
start_time=$(date +%s)
|
||||||
|
|
||||||
|
log "Target OS: $(lsb_release -ds 2>/dev/null || cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2 | tr -d '"')"
|
||||||
|
log "Target arch: $(uname -m)"
|
||||||
|
echo ""
|
||||||
|
|
||||||
phase1_system
|
phase1_system
|
||||||
phase2_gitea
|
phase2_gitea
|
||||||
phase3_clone
|
phase3_clone
|
||||||
@ -592,6 +638,7 @@ main() {
|
|||||||
echo "║ Health check: /opt/bytelyst/check-health.sh ║"
|
echo "║ Health check: /opt/bytelyst/check-health.sh ║"
|
||||||
echo "║ Compose logs: docker compose -f ${COMPOSE_FILE} logs -f ║"
|
echo "║ Compose logs: docker compose -f ${COMPOSE_FILE} logs -f ║"
|
||||||
echo "║ Gitea UI: http://localhost:3300 ║"
|
echo "║ Gitea UI: http://localhost:3300 ║"
|
||||||
|
echo "║ Ollama API: http://localhost:11434 ║"
|
||||||
echo "║ Grafana: http://localhost:3000 (admin / bytelyst) ║"
|
echo "║ Grafana: http://localhost:3000 (admin / bytelyst) ║"
|
||||||
echo "║ Mailpit: http://localhost:8025 ║"
|
echo "║ Mailpit: http://localhost:8025 ║"
|
||||||
echo "╚═══════════════════════════════════════════════════════════════╝"
|
echo "╚═══════════════════════════════════════════════════════════════╝"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user