Complete Phase 4: Polish, Docker, CI/CD, and deployment readiness

- Fix responsive issues: Card/detail panel use p-4 md:p-8, larger
  progress dots, tighter mobile gaps in Contact section
- Fix lint errors: remove unused vars in BentoCard, AnimatedSection;
  fix explicit-any in ExpandableServiceCard test
- Fix zod-validation-error v4 dependency for eslint-plugin-react-hooks
- Add type-check script to package.json
- Create multi-stage Dockerfile (node:20-alpine build, nginx:alpine serve)
- Create .dockerignore to exclude dev files from build context
- Create nginx.conf with SPA routing, gzip, caching, security headers
- Update docker-compose.yml: build context replaces volume mount,
  preserve Traefik labels, add healthcheck
- Rewrite CI/CD pipeline: Node.js setup, npm ci, type-check, lint,
  test, build, rsync + docker compose build on server
- Add AI-generated images for all placeholder locations
- Archive original index.html as index.html.original

All checks pass: tsc --noEmit, eslint, 222/222 tests, vite build

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-06 00:56:07 -07:00
parent 2a59beeac8
commit eccaf8a60d
26 changed files with 229 additions and 824 deletions

View File

@ -1,82 +1,104 @@
name: Deploy Website
name: Build and Deploy Website
run-name: Deploying website changes by ${{ github.actor }}
on:
push:
branches: [ main ]
paths:
- '*.html'
- 'assets/**'
- 'css/**'
- 'js/**'
- 'images/**'
paths:
- 'src/**'
- 'public/**'
- 'package*.json'
- 'vite.config.ts'
- 'tailwind.config.ts'
- 'tsconfig*.json'
- 'index.html'
- 'Dockerfile'
- 'nginx.conf'
- 'docker-compose.yml'
workflow_dispatch:
jobs:
deploy:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Validate HTML
run: |
apt-get update && apt-get install -y tidy
find . -name "*.html" -exec tidy -q -e {} \;
echo "✅ HTML validation passed"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Type check
run: npm run type-check
- name: Lint
run: npm run lint
- name: Run tests
run: npm run test -- --run
- name: Build production
run: npm run build
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
echo "Host *" > ~/.ssh/config
echo " StrictHostKeyChecking no" >> ~/.ssh/config
echo " UserKnownHostsFile /dev/null" >> ~/.ssh/config
chmod 600 ~/.ssh/config
- name: Deploy website
- name: Deploy to server
run: |
# Install rsync
echo "📦 Installing rsync..."
apt-get update && apt-get install -y rsync
SERVER_IP="192.168.4.56"
DEPLOY_USER="deploy"
WEBSITE_DIR="/media/stephen/Storage_Linux/infrastructure/services/websites/maverickApplications"
echo "📁 Syncing website files to server..."
echo "Syncing project files to server..."
rsync -avz --delete \
--no-times \
--no-perms \
--exclude='.git' \
--exclude='node_modules' \
--exclude='.gitea' \
--exclude='README.md' \
--exclude='docker-compose.yml' \
--exclude='plan' \
--exclude='.claude' \
-e "ssh -i ~/.ssh/deploy_key" \
./ $DEPLOY_USER@$SERVER_IP:$WEBSITE_DIR/
echo "🔄 Restarting website container..."
echo "Building Docker image on server..."
ssh -i ~/.ssh/deploy_key $DEPLOY_USER@$SERVER_IP \
"cd $WEBSITE_DIR && docker compose restart maverick-website"
"cd $WEBSITE_DIR && docker compose build --no-cache"
echo "Starting updated container..."
ssh -i ~/.ssh/deploy_key $DEPLOY_USER@$SERVER_IP \
"cd $WEBSITE_DIR && docker compose up -d"
- name: Health check
run: |
echo "🏥 Waiting for container to restart..."
sleep 15
echo "Waiting for container to be healthy..."
sleep 20
for i in {1..5}; do
if curl -f --connect-timeout 10 https://maverickapplications.com; then
echo "✅ Website is responding correctly!"
echo "Website is responding correctly!"
exit 0
fi
echo "⏳ Attempt $i failed, retrying in 10 seconds..."
echo "Attempt $i failed, retrying in 10 seconds..."
sleep 10
done
echo "❌ Website health check failed"
echo "Website health check failed"
exit 1
- name: Cleanup
if: always()
run: rm -f ~/.ssh/deploy_key
run: rm -f ~/.ssh/deploy_key