feat: make version deployable

This commit is contained in:
nobody 2025-11-29 13:56:55 -08:00
commit 49bd94cda2
Signed by: GrocerPublishAgent
GPG key ID: D460CD54A9E3AB86
22 changed files with 7785 additions and 10962 deletions

124
frontend/deploy.sh Executable file
View file

@ -0,0 +1,124 @@
#!/bin/sh
set -eu
# Deployment topology with Nomad
#
# Directory structure on remote:
# $base/$project/
# releases/{stamp}_{hash}/
# dist/ - static assets served by nginx
# server/ - node server (entry.express.js)
# package.json - dependencies
# node_modules/ - installed dependencies
# job.nomad.hcl - nomad job definition for this release
# current -> releases/{latest}
#
# Zero-downtime deployment with Nomad:
# 1. rsync new release (dist/ + server/)
# 2. yarn install dependencies
# 3. generate job file with release path
# 4. nomad job run (triggers blue-green deployment)
# 5. nomad waits for health checks to pass
# 6. nomad auto-promotes new allocation
# 7. old allocation enters graceful shutdown (30s kill_timeout)
# 8. consul-template updates nginx config (via service tags)
# 9. cleanup old releases (keep 5 most recent)
ssh=deploy-peoplesgrocers-website
base=/home/peoplesgrocers
project=salience-editor-qwik-city
test -d dist || { echo 'no dist/'; exit 1; }
test -d server || { echo 'no server/'; exit 1; }
# git diff-index --quiet HEAD || { echo 'git repo dirty'; exit 1; }
hash=$(git rev-parse --short=8 HEAD)
stamp=$(date +%Y-%b-%d-%a-%I_%M%p | tr 'APM' 'apm')
release="${stamp}-${hash}"
echo "deploying: $project @ $release"
printf "continue? [y/n] "
read ans
test "$ans" = "y" || exit 1
# prepare remote directories
ssh $ssh "mkdir -p $base/$project/releases/$release"
# sync all files using rclone (handles poor network connections better)
echo "syncing release files (dist/, server/, package.json)..."
temp_dir=$(mktemp -d)
trap "rm -rf $temp_dir" EXIT INT TERM
# Copy files to temp directory for single rclone transfer
cp -r dist server package.json .yarnrc.yml "$temp_dir/"
rclone copy "$temp_dir/" "${ssh}:$base/$project/releases/$release/" \
--progress --retries 10 --checksum
rm -rf "$temp_dir"
echo "installing server dependencies..."
ssh $ssh "source ~/.nvm/nvm.sh && cd $base/$project/releases/$release && yarn install"
# generate nomad job file with release path
echo "generating nomad job file..."
release_path="$base/$project/releases/$release"
job_file="$base/$project/releases/$release/job.nomad.hcl"
# Use envsubst with whitelist to only replace our variables, not Nomad runtime variables
export RELEASE_PLACEHOLDER="$release"
export RELEASE_PATH="$release_path"
envsubst '$RELEASE_PLACEHOLDER $RELEASE_PATH' < salience-editor-qwik-city.nomad.hcl | ssh $ssh "cat > $job_file"
echo ""
echo "nomad job file created at: $job_file"
echo ""
# submit job to nomad
echo "submitting job to nomad..."
deployment_id=$(ssh $ssh "source ~/.local/bin/env && nomad job run $job_file | grep -oE 'Deployment ID = [a-f0-9-]+' | awk '{print \$4}'" )
if [ -n "$deployment_id" ]; then
echo "deployment started: $deployment_id"
echo ""
echo "monitoring deployment..."
# Monitor deployment status
ssh $ssh "source ~/.local/bin/env && nomad deployment status $deployment_id"
echo ""
printf "watch deployment progress? [y/n] "
read ans
if [ "$ans" = "y" ]; then
ssh $ssh "source ~/.local/bin/env && watch -n 2 'nomad deployment status $deployment_id'"
fi
else
echo "warning: could not extract deployment ID"
echo "check deployment status manually with: nomad job status $project"
fi
# update current symlink
echo ""
printf "update current symlink? [y/n] "
read ans
if [ "$ans" = "y" ]; then
ssh $ssh "ln -sfn releases/$release $base/$project/current"
echo "current -> $release"
fi
echo ""
echo "done: $release"
echo ""
echo "Next steps:"
echo "- Nomad will automatically promote the deployment after health checks pass"
echo "- Consul-template will update nginx config based on healthy service instances"
echo "- Old allocation will gracefully shutdown (30s timeout for in-flight requests)"
echo "- Run ./cleanup-old-releases.sh to remove old releases (keeps 5 most recent)"
echo ""
if [ -n "$deployment_id" ]; then
echo "Monitor deployment:"
echo " nomad deployment status $deployment_id"
echo " watch -n 2 'nomad deployment status $deployment_id'"
echo " nomad job allocs $project"
echo ""
fi
echo "Check service health:"
echo " curl http://localhost:15500/v1/health/service/$project | jq"