- README.md: Add comprehensive build system section explaining TypeScript backend/frontend compilation, esbuild usage, and development commands - CLAUDE.md: Update architecture documentation to reflect TypeScript frontend with shared components and esbuild compilation - scripts/deploy.sh: Update deployment instructions to use new unified build command 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
204 lines
6.6 KiB
Bash
204 lines
6.6 KiB
Bash
#!/bin/bash
|
|
|
|
# Great Lakes Ice Report Deployment Script for Debian 12 (ARM64/x86_64)
|
|
# Supports both ARM64 and x86_64 architectures
|
|
#
|
|
# Usage:
|
|
# ./deploy.sh # Downloads from default S3 bucket (ice-puremichigan-lol)
|
|
# S3_BUCKET_NAME=mybucket ./deploy.sh # Downloads from custom S3 bucket
|
|
# S3_BUCKET_NAME=none ./deploy.sh # Uses local files from repository
|
|
#
|
|
# When using S3, expects files at:
|
|
# https://{bucket}.s3.amazonaws.com/scripts/icewatch.service
|
|
# https://{bucket}.s3.amazonaws.com/scripts/Caddyfile
|
|
|
|
set -e
|
|
|
|
echo "🚀 Starting Great Lakes Ice Report deployment..."
|
|
|
|
# Detect architecture
|
|
ARCH=$(uname -m)
|
|
echo "🔍 Raw architecture from uname -m: $ARCH"
|
|
|
|
# Also check dpkg architecture as fallback
|
|
DPKG_ARCH=$(dpkg --print-architecture 2>/dev/null || echo "unknown")
|
|
echo "🔍 dpkg architecture: $DPKG_ARCH"
|
|
|
|
case $ARCH in
|
|
x86_64|amd64)
|
|
GO_ARCH="amd64"
|
|
echo "📋 Detected x86_64 architecture"
|
|
;;
|
|
aarch64|arm64)
|
|
GO_ARCH="arm64"
|
|
echo "📋 Detected ARM64 architecture"
|
|
;;
|
|
armv7l|armhf)
|
|
echo "❌ Detected 32-bit ARM architecture"
|
|
echo "This script requires 64-bit architecture (x86_64 or ARM64)."
|
|
exit 1
|
|
;;
|
|
*)
|
|
echo "❌ Unsupported architecture: $ARCH"
|
|
echo "This script supports x86_64 and ARM64 only."
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# Update system
|
|
echo "📦 Updating system packages..."
|
|
sudo apt update && sudo apt upgrade -y
|
|
|
|
# Install Node.js and Git
|
|
echo "📦 Installing Node.js and Git..."
|
|
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
|
sudo apt install -y nodejs build-essential git
|
|
|
|
# Install Go (required for xcaddy)
|
|
echo "📦 Installing Go for $GO_ARCH architecture..."
|
|
GO_VERSION="1.21.5"
|
|
GO_TARBALL="go${GO_VERSION}.linux-${GO_ARCH}.tar.gz"
|
|
wget -q "https://go.dev/dl/${GO_TARBALL}"
|
|
sudo rm -rf /usr/local/go
|
|
sudo tar -C /usr/local -xzf "${GO_TARBALL}"
|
|
export PATH=$PATH:/usr/local/go/bin
|
|
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
|
|
|
|
# Install xcaddy to build Caddy with plugins
|
|
echo "📦 Installing xcaddy..."
|
|
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
|
|
export PATH=$PATH:$(go env GOPATH)/bin
|
|
|
|
# Build Caddy with rate limiting plugin
|
|
echo "🔧 Building Caddy with rate limiting plugin..."
|
|
xcaddy build --with github.com/mholt/caddy-ratelimit
|
|
|
|
# Install the custom Caddy binary
|
|
echo "📦 Installing custom Caddy..."
|
|
sudo mv caddy /usr/local/bin/caddy
|
|
sudo chmod +x /usr/local/bin/caddy
|
|
|
|
# Create Caddy user and directories
|
|
sudo groupadd --system caddy
|
|
sudo useradd --system --gid caddy --create-home --home-dir /var/lib/caddy --shell /usr/sbin/nologin caddy
|
|
sudo mkdir -p /etc/caddy /var/log/caddy
|
|
sudo chown -R caddy:caddy /var/log/caddy
|
|
|
|
# Create systemd service for custom Caddy
|
|
echo "⚙️ Creating Caddy systemd service..."
|
|
sudo tee /etc/systemd/system/caddy.service > /dev/null <<EOF
|
|
[Unit]
|
|
Description=Caddy
|
|
Documentation=https://caddyserver.com/docs/
|
|
After=network.target network-online.target
|
|
Requires=network-online.target
|
|
|
|
[Service]
|
|
Type=notify
|
|
User=caddy
|
|
Group=caddy
|
|
ExecStart=/usr/local/bin/caddy run --environ --config /etc/caddy/Caddyfile
|
|
ExecReload=/usr/local/bin/caddy reload --config /etc/caddy/Caddyfile --force
|
|
TimeoutStopSec=5s
|
|
LimitNOFILE=1048576
|
|
LimitNPROC=1048576
|
|
PrivateTmp=true
|
|
ProtectSystem=full
|
|
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
# Clean up Go archive
|
|
rm -f "${GO_TARBALL}"
|
|
|
|
echo "✅ Caddy with rate limiting plugin installed successfully!"
|
|
|
|
# Create app directory
|
|
echo "📁 Setting up app directory..."
|
|
sudo mkdir -p /opt/icewatch
|
|
sudo chown $USER:$USER /opt/icewatch
|
|
|
|
# Navigate to app directory
|
|
cd /opt/icewatch
|
|
|
|
# Create icewatch user for security
|
|
echo "👤 Creating icewatch user..."
|
|
sudo useradd --system --shell /bin/false --home /opt/icewatch --create-home icewatch
|
|
|
|
# Download or copy configuration files
|
|
# Use provided S3_BUCKET_NAME or fall back to ice-puremichigan-lol
|
|
S3_BUCKET_NAME="${S3_BUCKET_NAME:-ice-puremichigan-lol}"
|
|
|
|
if [ "$S3_BUCKET_NAME" != "none" ]; then
|
|
echo "📥 Downloading configuration files from S3 bucket: $S3_BUCKET_NAME"
|
|
S3_BASE_URL="https://${S3_BUCKET_NAME}.s3.amazonaws.com/scripts"
|
|
|
|
# Download systemd service file
|
|
echo "📥 Downloading systemd service..."
|
|
curl -sSL "$S3_BASE_URL/icewatch.service" -o /tmp/icewatch.service
|
|
if [ $? -eq 0 ]; then
|
|
sudo mv /tmp/icewatch.service /etc/systemd/system/icewatch.service
|
|
echo "✅ Downloaded icewatch.service from S3"
|
|
else
|
|
echo "❌ Failed to download icewatch.service from S3"
|
|
exit 1
|
|
fi
|
|
|
|
# Download Caddyfile
|
|
echo "📥 Downloading Caddy configuration..."
|
|
curl -sSL "$S3_BASE_URL/Caddyfile" -o /tmp/Caddyfile
|
|
if [ $? -eq 0 ]; then
|
|
sudo mv /tmp/Caddyfile /etc/caddy/Caddyfile
|
|
echo "✅ Downloaded Caddyfile from S3"
|
|
else
|
|
echo "❌ Failed to download Caddyfile from S3"
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "📋 Note: S3 downloads disabled (S3_BUCKET_NAME=none). Configuration files will be copied from the repository after cloning."
|
|
echo " The systemd service file and Caddyfile are located in the scripts/ directory."
|
|
fi
|
|
|
|
echo "✅ Server setup complete!"
|
|
echo ""
|
|
echo "🚀 Next steps to deploy Great Lakes Ice Report:"
|
|
echo ""
|
|
echo "1. Clone your repository:"
|
|
echo " git clone https://git.deco.sh/deco/ice.git /opt/icewatch"
|
|
echo ""
|
|
if [ "$S3_BUCKET_NAME" = "none" ]; then
|
|
echo "2. Copy configuration files:"
|
|
echo " sudo cp /opt/icewatch/scripts/icewatch.service /etc/systemd/system/"
|
|
echo " sudo cp /opt/icewatch/scripts/Caddyfile /etc/caddy/Caddyfile"
|
|
echo ""
|
|
else
|
|
echo "2. Configuration files already downloaded from S3"
|
|
echo ""
|
|
fi
|
|
echo "3. Set up the application:"
|
|
echo " cd /opt/icewatch"
|
|
echo " npm install"
|
|
echo " npm run build # Build everything: TypeScript backend + frontend + CSS + i18n"
|
|
echo " cp .env.example .env"
|
|
echo " nano .env # Add your MapBox token and admin password"
|
|
echo ""
|
|
echo "4. Configure domain in Caddyfile (if needed):"
|
|
echo " sudo nano /etc/caddy/Caddyfile"
|
|
echo " # The default is configured for ice.puremichigan.lol"
|
|
echo ""
|
|
echo "5. Set permissions:"
|
|
echo " sudo chown -R icewatch:icewatch /opt/icewatch"
|
|
echo " sudo chmod 660 /opt/icewatch/.env"
|
|
echo ""
|
|
echo "6. Start services:"
|
|
echo " sudo systemctl daemon-reload"
|
|
echo " sudo systemctl enable icewatch caddy"
|
|
echo " sudo systemctl start icewatch caddy"
|
|
echo ""
|
|
echo "7. Check status:"
|
|
echo " sudo systemctl status icewatch"
|
|
echo " sudo systemctl status caddy"
|
|
echo ""
|
|
echo "🌐 Your Great Lakes Ice Report app will be available at: https://ice.puremichigan.lol"
|