Run these first. They tell you exactly what you have before touching anything.
In OSGeoLive 17 (Lubuntu): right-click the desktop → Open Terminal, or press Ctrl+Alt+T.
# Confirm user and OS version
whoami
lsb_release -a
# See every disk and partition — find your nvme or usb
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,LABEL,FSTYPE
# Confirm network is up
ping -c 3 github.com
# Is Docker already running?
docker ps
This applies when booting on the i7 with nvme0n1p4. Skip to Phase 2 on machines without this drive.
# Only needed once per boot session
sudo mkdir -p /mnt/p4
# Replace nvme0n1p4 with whatever lsblk showed your ext4 partition as
sudo mount /dev/nvme0n1p4 /mnt/p4
# Should show vcap/ and any prior work
ls -la /mnt/p4/
# Allow the live user to write to p4 without sudo every time
sudo chown -R user:user /mnt/p4
ONE TIME PER BOOT These install into RAM. Must re-run on each fresh boot unless using a persistent layer.
sudo apt-get update -y
sudo apt-get install -y git curl wget
# Install Docker from the official convenience script
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Add live user to docker group (no sudo needed for docker commands)
sudo usermod -aG docker user
# Apply group change in current shell
newgrp docker
docker run hello-world
# Single-node swarm — required for Portainer stack deployment
docker swarm init
# Create Portainer persistent volume
docker volume create portainer_data
# Deploy Portainer CE as a swarm service
docker stack deploy -c - portainer <<'PORTAINER_STACK'
version: '3.8'
services:
portainer:
image: portainer/portainer-ce:latest
ports:
- "9000:9000"
- "9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
deploy:
placement:
constraints:
- node.role == manager
volumes:
portainer_data:
external: true
PORTAINER_STACK
# Open in your browser — first boot will ask you to set admin password
http://localhost:9000
This repo will hold: setup scripts, Docker Compose stack files, PostGIS seed data, MapProxy config, Portainer stack exports, and this runbook HTML.
# Git needs a name and email to make commits — use your GitHub info
git config --global user.name "Kenneth Wyrick"
git config --global user.email "your-github-email@example.com"
# Clone to /mnt/p4/vcap/osgeo17-vcap (persistent) or ~/vcap (RAM only)
git clone https://github.com/calteknet/osgeo17-vcap.git /mnt/p4/vcap/osgeo17-vcap
# Create the directory structure
mkdir -p /mnt/p4/vcap/osgeo17-vcap/{scripts,stacks,config,docs,data}
cd /mnt/p4/vcap/osgeo17-vcap
# Initialize git
git init
git branch -M main
# Create a README
cat > README.md <<'EOF'
# OSGeoLive 17 VCAP Nomadic Classroom
CalTekNet distro customization runbook and setup scripts.
Boots reproducibly from any machine running OSGeoLive 17.
## Structure
- scripts/ — shell setup scripts
- stacks/ — Docker Compose / Portainer stack definitions
- config/ — MapProxy, GeoServer, PostGIS config files
- docs/ — Runbook HTML and reference docs
- data/ — PostGIS seed SQL dumps
## Quick Start
Boot OSGeoLive 17. Open terminal. Run:
curl -fsSL https://raw.githubusercontent.com/calteknet/osgeo17-vcap/main/scripts/vcap_17_setup.sh | bash
EOF
git add .
git commit -m "init: VCAP nomadic classroom repo structure"
This single script rebuilds the entire VCAP classroom stack on any fresh OSGeoLive 17 boot. Save it to scripts/vcap_17_setup.sh in your repo.
# Make sure you're in the repo
cd /mnt/p4/vcap/osgeo17-vcap
# Write the master setup script
cat > scripts/vcap_17_setup.sh <<'SETUPSCRIPT'
#!/usr/bin/env bash
# =============================================================
# vcap_17_setup.sh
# OSGeoLive 17 · VCAP Nomadic Classroom Bootstrap
# CalTekNet · github.com/calteknet/osgeo17-vcap
# Run as: bash scripts/vcap_17_setup.sh
# =============================================================
set -e
VCAP_DIR="${1:-/mnt/p4/vcap}"
REPO_DIR="$VCAP_DIR/osgeo17-vcap"
LOG="$VCAP_DIR/setup_$(date +%Y%m%d_%H%M%S).log"
echo "=== VCAP 17 Setup Starting ===" | tee "$LOG"
echo "Target dir: $VCAP_DIR" | tee -a "$LOG"
# --- 1. System update ---
echo "[1/7] Updating apt..." | tee -a "$LOG"
sudo apt-get update -y >> "$LOG" 2>&1
# --- 2. Install git, curl, wget ---
echo "[2/7] Installing git curl wget..." | tee -a "$LOG"
sudo apt-get install -y git curl wget >> "$LOG" 2>&1
# --- 3. Install Docker ---
echo "[3/7] Installing Docker..." | tee -a "$LOG"
if ! command -v docker &> /dev/null; then
curl -fsSL https://get.docker.com -o /tmp/get-docker.sh
sudo sh /tmp/get-docker.sh >> "$LOG" 2>&1
sudo usermod -aG docker user
echo "Docker installed." | tee -a "$LOG"
else
echo "Docker already present." | tee -a "$LOG"
fi
# --- 4. Start Docker swarm ---
echo "[4/7] Initializing Docker swarm..." | tee -a "$LOG"
if ! docker info 2>/dev/null | grep -q "Swarm: active"; then
newgrp docker <> "$LOG" 2>&1
INNEREOF
echo "Swarm initialized." | tee -a "$LOG"
else
echo "Swarm already active." | tee -a "$LOG"
fi
# --- 5. Deploy Portainer ---
echo "[5/7] Deploying Portainer..." | tee -a "$LOG"
docker volume create portainer_data >> "$LOG" 2>&1 || true
docker stack deploy -c "$REPO_DIR/stacks/portainer.yml" portainer >> "$LOG" 2>&1
echo "Portainer → http://localhost:9000" | tee -a "$LOG"
# --- 6. Deploy VCAP classroom stack ---
echo "[6/7] Deploying VCAP classroom stack..." | tee -a "$LOG"
docker stack deploy -c "$REPO_DIR/stacks/vcap-classroom.yml" vcap >> "$LOG" 2>&1
echo "VCAP stack deployed." | tee -a "$LOG"
# --- 7. Done ---
echo "" | tee -a "$LOG"
echo "=== Setup Complete ===" | tee -a "$LOG"
echo "Portainer: http://localhost:9000" | tee -a "$LOG"
echo "GeoServer: http://localhost:8080/geoserver" | tee -a "$LOG"
echo "MapProxy: http://localhost:8070" | tee -a "$LOG"
echo "Jupyter: http://localhost:8888" | tee -a "$LOG"
echo "Log saved: $LOG" | tee -a "$LOG"
SETUPSCRIPT
# Make it executable
chmod +x scripts/vcap_17_setup.sh
cd /mnt/p4/vcap/osgeo17-vcap
git add scripts/vcap_17_setup.sh
git commit -m "feat: add vcap_17_setup.sh master bootstrap script"
Two YAML files. These define all services. Portainer reads them. Save both to stacks/.
cat > /mnt/p4/vcap/osgeo17-vcap/stacks/portainer.yml <<'EOF'
version: '3.8'
services:
portainer:
image: portainer/portainer-ce:latest
ports:
- "9000:9000"
- "9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
deploy:
placement:
constraints:
- node.role == manager
volumes:
portainer_data:
external: true
EOF
cat > /mnt/p4/vcap/osgeo17-vcap/stacks/vcap-classroom.yml <<'EOF'
version: '3.8'
# VCAP Nomadic Classroom Stack
# CalTekNet · OSGeoLive 17
# Services: PostGIS · GeoServer · MapProxy · Jupyter · GeoNetwork
networks:
vcap_net:
driver: overlay
attachable: true
volumes:
postgis_data:
geoserver_data:
mapproxy_cache:
jupyter_work:
services:
postgis:
image: postgis/postgis:17-3.5
environment:
POSTGRES_USER: vcap
POSTGRES_PASSWORD: vcap2026
POSTGRES_DB: vcap_classroom
volumes:
- postgis_data:/var/lib/postgresql/data
ports:
- "5432:5432"
networks:
- vcap_net
deploy:
replicas: 1
geoserver:
image: kartoza/geoserver:2.27.1
environment:
GEOSERVER_ADMIN_USER: admin
GEOSERVER_ADMIN_PASSWORD: geoserver
GEOWEBCACHE_CACHE_DIR: /opt/geoserver/data_dir/gwc
volumes:
- geoserver_data:/opt/geoserver/data_dir
ports:
- "8080:8080"
networks:
- vcap_net
depends_on:
- postgis
deploy:
replicas: 1
mapproxy:
image: kartoza/mapproxy:latest
volumes:
- mapproxy_cache:/mapproxy/cache_data
ports:
- "8070:8080"
networks:
- vcap_net
deploy:
replicas: 1
jupyter:
image: jupyter/scipy-notebook:latest
environment:
JUPYTER_ENABLE_LAB: "yes"
JUPYTER_TOKEN: "vcap2026"
volumes:
- jupyter_work:/home/jovyan/work
ports:
- "8888:8888"
networks:
- vcap_net
deploy:
replicas: 1
EOF
cd /mnt/p4/vcap/osgeo17-vcap
git add stacks/
git commit -m "feat: add portainer and vcap-classroom stack definitions"
No SSH key configured. Use a Personal Access Token (PAT) via HTTPS. One-time setup per machine per session.
osgeo17-vcap live sessioncd /mnt/p4/vcap/osgeo17-vcap
# Add GitHub as remote — use your actual token where TOKEN appears
git remote add origin https://TOKEN@github.com/calteknet/osgeo17-vcap.git
# Push everything
git push -u origin main
https://ghp_abc123xyz@github.com/...Open github.com/calteknet/osgeo17-vcap — you should see your files: README.md, scripts/, stacks/, docs/, data/.
# Copy this runbook HTML into the repo docs folder
cp /path/to/osgeo17-vcap-runbook.html /mnt/p4/vcap/osgeo17-vcap/docs/
cd /mnt/p4/vcap/osgeo17-vcap
git add docs/
git commit -m "docs: add distro customization runbook HTML"
git push
Once the repo is on GitHub, any machine booted on OSGeoLive 17 can run the full stack in three commands.
# Step 1: Install git (may already be present)
sudo apt-get install -y git
# Step 2: Clone the runbook repo to RAM (no persistent drive needed)
git clone https://github.com/calteknet/osgeo17-vcap.git ~/vcap
# Step 3: Run the setup script
bash ~/vcap/scripts/vcap_17_setup.sh ~/vcap
http://localhost:9000 # Portainer (set admin password on first boot)
http://localhost:8080/geoserver # GeoServer (admin / geoserver)
http://localhost:8070 # MapProxy tile cache
http://localhost:8888 # Jupyter Lab (token: vcap2026)
localhost:5432 # PostGIS (vcap / vcap2026 / vcap_classroom)
# Export PostGIS databases before shutting down
docker exec $(docker ps -q -f name=postgis) \
pg_dumpall -U vcap > ~/vcap/data/postgis_dump_$(date +%Y%m%d).sql
# Commit and push the dump to GitHub
cd ~/vcap
git add data/
git commit -m "data: postgis dump $(date +%Y%m%d)"
git push