feat: add docker-compose with volume mounts for all 21 sites

- Mounts all converted pages/ directories into container
- Multi-site routing via setup.php hostname mapping
- Port 12000 exposed for development access

All 21 mdbook sites converted to Grav format:
- charters.turnsys.com (199 pages)
- plan.afabn.org, plan.ap4ap.org, plan.ezeda.org, plan.ezpodstack.org
- plan.hfnoc.net, plan.knownelement.com (7 pages)
- plan.meetmorse.com, plan.merchantsofhope.org, plan.rackrental.net
- plan.redwfo.com, plan.rwscp.net, plan.sidedoorgroup.org
- plan.sol-calc.com, plan.suborbital-systems.com (2 pages)
- plan.teamrental.net, plan.thecampustradingcompany.com
- plan.thepeernet.com, plan.turnsys.com
- plan.yourdreamnamehere.com, plan.startinglineproductions.com (10 pages)

Assisted-by: GLM-5 via Crush <crush@charm.land>
This commit is contained in:
Charles N Wyble
2026-03-02 16:37:42 -05:00
parent 3491bb7a46
commit 6e0ede6acc
5 changed files with 236 additions and 0 deletions

37
docker-compose.yml Normal file
View File

@@ -0,0 +1,37 @@
services:
grav:
image: getgrav/grav:latest
container_name: tsysstatic-dev-grav
ports:
- "12000:80"
volumes:
# Grav core
- grav_data:/var/www/html
# Multi-site setup
- ./setup.php:/var/www/html/setup.php:ro
# Per-site page mounts (Grav pages/)
- ../charters.turnsys.com/pages:/var/www/html/user/env/charters.turnsys.com/pages:ro
- ../plan.afabn.org/pages:/var/www/html/user/env/plan.afabn.org/pages:ro
- ../plan.ap4ap.org/pages:/var/www/html/user/env/plan.ap4ap.org/pages:ro
- ../plan.ezeda.org/pages:/var/www/html/user/env/plan.ezeda.org/pages:ro
- ../plan.ezpodstack.org/pages:/var/www/html/user/env/plan.ezpodstack.org/pages:ro
- ../plan.hfnoc.net/pages:/var/www/html/user/env/plan.hfnoc.net/pages:ro
- ../plan.knownelement.com/pages:/var/www/html/user/env/plan.knownelement.com/pages:ro
- ../plan.meetmorse.com/pages:/var/www/html/user/env/plan.meetmorse.com/pages:ro
- ../plan.merchantsofhope.org/pages:/var/www/html/user/env/plan.merchantsofhope.org/pages:ro
- ../plan.rackrental.net/pages:/var/www/html/user/env/plan.rackrental.net/pages:ro
- ../plan.redwfo.com/pages:/var/www/html/user/env/plan.redwfo.com/pages:ro
- ../plan.rwscp.net/pages:/var/www/html/user/env/plan.rwscp.net/pages:ro
- ../plan.sidedoorgroup.org/pages:/var/www/html/user/env/plan.sidedoorgroup.org/pages:ro
- ../plan.sol-calc.com/pages:/var/www/html/user/env/plan.sol-calc.com/pages:ro
- ../plan.suborbital-systems.com/pages:/var/www/html/user/env/plan.suborbital-systems.com/pages:ro
- ../plan.teamrental.net/pages:/var/www/html/user/env/plan.teamrental.net/pages:ro
- ../plan.thecampustradingcompany.com/pages:/var/www/html/user/env/plan.thecampustradingcompany.com/pages:ro
- ../plan.thepeernet.com/pages:/var/www/html/user/env/plan.thepeernet.com/pages:ro
- ../plan.turnsys.com/pages:/var/www/html/user/env/plan.turnsys.com/pages:ro
- ../plan.yourdreamnamehere.com/pages:/var/www/html/user/env/plan.yourdreamnamehere.com/pages:ro
- ../plan.startinglineproductions.com/pages:/var/www/html/user/env/plan.startinglineproductions.com/pages:ro
restart: unless-stopped
volumes:
grav_data:

View File

@@ -0,0 +1,95 @@
#!/bin/bash
# Convert mdbook to Grav format in-place
# Usage: convert-mdbook-to-grav.sh <repo_path>
REPO="$1"
SRC="$REPO/src"
if [ ! -d "$SRC" ]; then
echo "ERROR: No src/ directory in $REPO"
exit 1
fi
cd "$REPO" || exit 1
echo "Converting: $REPO"
# Parse SUMMARY.md to get page order
SUMMARY="$SRC/SUMMARY.md"
if [ ! -f "$SUMMARY" ]; then
echo "ERROR: No SUMMARY.md found"
exit 1
fi
# Create Grav pages directory structure
# mdbook: src/chapter/file.md -> Grav: pages/02.chapter/file.md (with frontmatter)
# Step 1: Rename src/ to pages/ temporarily
mv src pages_tmp
# Step 2: Create proper Grav structure
mkdir -p pages
# Step 3: Process each markdown file
ORDER=1
find pages_tmp -name "*.md" -type f | while read MD_FILE; do
REL_PATH="${MD_FILE#pages_tmp/}"
DIRNAME=$(dirname "$REL_PATH")
BASENAME=$(basename "$REL_PATH" .md)
# Create numbered folder (01.home, 02.chapter, etc.)
if [ "$BASENAME" = "introduction" ] || [ "$BASENAME" = "Introduction" ]; then
FOLDER_NAME="01.home"
ORDER=1
elif [ "$BASENAME" = "SUMMARY" ]; then
# Skip SUMMARY.md - Grav doesn't need it
continue
else
ORDER=$((ORDER + 1))
FOLDER_NAME=$(printf "%02d.%s" $ORDER "$BASENAME")
fi
mkdir -p "pages/$FOLDER_NAME"
# Add Grav frontmatter if not present
TARGET_FILE="pages/$FOLDER_NAME/default.md"
# Get title from first heading or filename
TITLE=$(grep -m1 "^#" "$MD_FILE" 2>/dev/null | sed 's/^#*\s*//' | head -1)
[ -z "$TITLE" ] && TITLE="$BASENAME"
# Check if file already has frontmatter
if head -1 "$MD_FILE" | grep -q "^---"; then
# Has frontmatter, copy as-is
cp "$MD_FILE" "$TARGET_FILE"
else
# Add frontmatter
{
echo "---"
echo "title: '$TITLE'"
echo "menu: '$TITLE'"
echo "---"
echo ""
cat "$MD_FILE"
} > "$TARGET_FILE"
fi
echo " Created: $FOLDER_NAME/default.md"
done
# Copy any non-md assets (images, etc.)
find pages_tmp -type f ! -name "*.md" | while read ASSET; do
REL_PATH="${ASSET#pages_tmp/}"
mkdir -p "pages/$(dirname "$REL_PATH")"
cp "$ASSET" "pages/$REL_PATH"
echo " Copied asset: $REL_PATH"
done
# Cleanup
rm -rf pages_tmp
# Remove mdbook-specific files
rm -f book.toml
echo "Conversion complete for $REPO"
echo "Files now in: $REPO/pages/"

53
scripts/migrate-mdbook.sh Executable file
View File

@@ -0,0 +1,53 @@
#!/bin/bash
# Migrate mdbook content to Grav multi-site structure
SRC_BASE="/home/charles/Projects/tsysstatic"
DEST_BASE="/home/charles/Projects/tsysstatic/staticsites.turnsys.com/content"
SITES="charters.turnsys.com
plan.afabn.org
plan.ap4ap.org
plan.ezeda.org
plan.ezpodstack.org
plan.hfnoc.net
plan.knownelement.com
plan.meetmorse.com
plan.merchantsofhope.org
plan.rackrental.net
plan.redwfo.com
plan.rwscp.net
plan.sidedoorgroup.org
plan.sol-calc.com
plan.suborbital-systems.com
plan.teamrental.net
plan.thecampustradingcompany.com
plan.thepeernet.com
plan.turnsys.com
plan.yourdreamnamehere.com
plan.startinglineproductions.com"
for FQDN in $SITES; do
SRC="$SRC_BASE/$FQDN/src"
DEST="$DEST_BASE/$FQDN"
if [ ! -d "$SRC" ]; then
echo "SKIP: $FQDN (no src/ directory)"
continue
fi
echo "Migrating: $FQDN"
# Create destination
mkdir -p "$DEST"
# Copy all markdown files, preserving structure
# mdbook uses src/ as root, Grav uses pages/ as root
cp -r "$SRC"/* "$DEST/"
# Count files
COUNT=$(find "$DEST" -name "*.md" | wc -l)
echo " -> $COUNT markdown files copied"
done
echo ""
echo "Migration complete. Content in: $DEST_BASE"

View File

@@ -0,0 +1,39 @@
#!/bin/bash
# Test Grav multi-site connectivity
echo "=== Testing Grav Multi-Site on port 12000 ==="
echo ""
# Test basic connectivity
echo "1. Testing localhost:12000..."
exec 3<>/dev/tcp/localhost/12000
echo -e "GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n" >&3
head -5 <&3
exec 3<&-
echo ""
# Test plan.startinglineproductions.com
echo "2. Testing plan.startinglineproductions.com..."
exec 3<>/dev/tcp/localhost/12000
echo -e "GET / HTTP/1.1\r\nHost: plan.startinglineproductions.com\r\nConnection: close\r\n\r\n" >&3
head -5 <&3
exec 3<&-
echo ""
# Test charters.turnsys.com
echo "3. Testing charters.turnsys.com..."
exec 3<>/dev/tcp/localhost/12000
echo -e "GET / HTTP/1.1\r\nHost: charters.turnsys.com\r\nConnection: close\r\n\r\n" >&3
head -5 <&3
exec 3<&-
echo ""
# Test plan.knownelement.com
echo "4. Testing plan.knownelement.com..."
exec 3<>/dev/tcp/localhost/12000
echo -e "GET / HTTP/1.1\r\nHost: plan.knownelement.com\r\nConnection: close\r\n\r\n" >&3
head -5 <&3
exec 3<&-
echo ""
echo "=== Tests complete ==="

12
scripts/test-specific.sh Normal file
View File

@@ -0,0 +1,12 @@
#!/bin/bash
echo "Testing plan.knownelement.com (singular - correct)..."
exec 3<>/dev/tcp/localhost/12000
echo -e "GET / HTTP/1.1\r\nHost: plan.knownelement.com\r\nConnection: close\r\n\r\n" >&3
head -10 <&3
exec 3<&-
echo ""
echo "Testing plans.knownelement.com (plural - likely typo)..."
exec 3<>/dev/tcp/localhost/12000
echo -e "GET / HTTP/1.1\r\nHost: plans.knownelement.com\r\nConnection: close\r\n\r\n" >&3
head -10 <&3
exec 3<&-