# jnss-web Static Site Deployment Guide ## Overview This document describes the deployment process for jnss-web, a SvelteKit-based static website serving as the primary entrypoint for jnss.me. ## Architecture - **Technology**: SvelteKit v2 with static adapter - **Build Tool**: Bun - **Deployment**: Ansible playbook with git-based artifact deployment - **Web Server**: Caddy (direct file serving) - **Repository**: git.jnss.me/joakim/jnss-web - **Branch Strategy**: - `main` - Source code - `deploy` - Build artifacts only ## Server Architecture ``` /opt/jnss-web-repo/ # Git clone of deploy branch /var/www/jnss-web/ # Synced build artifacts (served by Caddy) /etc/caddy/sites-enabled/ └── jnss-web.caddy # Site config with www redirect /var/log/caddy/jnss-web.log # Access logs ``` ## Development Workflow ### 1. Local Development (main branch) ```bash cd ~/dev/jnss-web git checkout main # Make changes to source code # ... # Test locally bun run dev # Build to verify bun run build ``` ### 2. Prepare Deploy Branch ```bash # Build production version bun run build # Switch to deploy branch git checkout deploy # Merge changes from main git merge main --no-commit # Rebuild to ensure fresh build bun run build # Add only build artifacts git add build/ # Commit with descriptive message git commit -m "Deploy: Add new feature X" # Push to Gitea git push origin deploy ``` ### 3. Deploy to Server ```bash cd ~/rick-infra # Run deployment playbook ansible-playbook -i inventory/hosts.yml playbooks/deploy-jnss-web.yml # Watch logs (optional) ssh root@arch-vps 'tail -f /var/log/caddy/jnss-web.log' ``` ## Playbook Details ### Variables Located in `playbooks/deploy-jnss-web.yml`: - `jnss_web_repo_owner`: Your Gitea username (default: "joakim") - `jnss_web_branch`: Branch to deploy (default: "deploy") - `jnss_web_domain`: Primary domain (default: "jnss.me") ### Tags - `jnss-web` - All jnss-web tasks - `deploy` - Git clone/sync tasks - `caddy` - Caddy configuration tasks ### Example Usage ```bash # Full deployment ansible-playbook -i inventory/hosts.yml playbooks/deploy-jnss-web.yml # Only update Caddy config (no git pull) ansible-playbook -i inventory/hosts.yml playbooks/deploy-jnss-web.yml --tags caddy # Only sync files (skip Caddy reload) ansible-playbook -i inventory/hosts.yml playbooks/deploy-jnss-web.yml --tags deploy ``` ## Initial Setup ### jnss-web Project Configuration The following changes need to be made in the jnss-web project: #### 1. Install Static Adapter ```bash cd ~/dev/jnss-web bun add -D @sveltejs/adapter-static ``` #### 2. Update svelte.config.js ```javascript import adapter from '@sveltejs/adapter-static'; /** @type {import('@sveltejs/kit').Config} */ const config = { kit: { adapter: adapter({ pages: 'build', assets: 'build', fallback: undefined, precompress: false, strict: true }) } }; export default config; ``` #### 3. Create src/routes/+layout.js ```javascript export const prerender = true; ``` #### 4. Update .gitignore Comment out or remove the build directory from .gitignore: ```gitignore # build/ <- Comment this out or remove it ``` #### 5. Create Deploy Branch ```bash # Build the site first bun run build # Create and switch to deploy branch git checkout -b deploy # Remove source files (keep only build artifacts) git rm -r src static *.config.js package.json bun.lock jsconfig.json .npmrc # Keep only build/ and documentation git add build/ README.md # Commit git commit -m "Initial deploy branch with build artifacts" # Push to Gitea git push -u origin deploy # Switch back to main git checkout main ``` ## Troubleshooting ### Build Directory Not Found **Error**: "Build directory not found in repository" **Solution**: Ensure you pushed the build artifacts to the deploy branch: ```bash git checkout deploy ls -la build/ # Should exist git log --oneline -1 # Verify latest commit ``` ### Caddy Not Serving New Content **Solution**: ```bash # SSH to server ssh root@arch-vps # Check Caddy status systemctl status caddy # Reload Caddy manually systemctl reload caddy # Check logs journalctl -u caddy -f ``` ### Permission Issues **Solution**: ```bash # SSH to server ssh root@arch-vps # Fix ownership chown -R caddy:caddy /var/www/jnss-web # Verify ls -la /var/www/jnss-web ``` ### Git Clone Fails **Error**: Unable to clone from git.jnss.me **Solution**: - Verify repository is public in Gitea - Test clone manually: `git clone https://git.jnss.me/joakim/jnss-web.git /tmp/test` - Check Gitea service status ## Rollback Procedure ### Option 1: Rollback Deploy Branch ```bash # In jnss-web repository git checkout deploy # Find previous commit git log --oneline # Reset to previous commit git reset --hard # Force push git push -f origin deploy # Re-run deployment cd ~/rick-infra ansible-playbook -i inventory/hosts.yml playbooks/deploy-jnss-web.yml ``` ### Option 2: Quick Server-Side Rollback ```bash # SSH to server ssh root@arch-vps # Go to repo directory cd /opt/jnss-web-repo # Reset to previous commit git reset --hard HEAD~1 # Re-sync rsync -av --delete build/ /var/www/jnss-web/ # Reload Caddy systemctl reload caddy ``` ## Security Considerations - Repository is public (contains only build artifacts) - No secrets in build output - Caddy serves only /var/www/jnss-web (no parent directory access) - Security headers configured in Caddy - HTTPS enforced via Caddy with Let's Encrypt ## Performance Optimizations - Static assets cached for 1 year (immutable) - HTML cached for 1 hour with revalidation - Gzip compression enabled - No server-side processing required ## Monitoring ### Check Deployment Status ```bash # From control machine ansible homelab -i inventory/hosts.yml -m shell -a "ls -lh /var/www/jnss-web" ``` ### View Access Logs ```bash ssh root@arch-vps 'tail -100 /var/log/caddy/jnss-web.log | jq .' ``` ### Check Site Health ```bash curl -I https://jnss.me curl -I https://www.jnss.me # Should redirect to jnss.me ``` ## Files Created This deployment adds the following files to rick-infra: - `playbooks/deploy-jnss-web.yml` - Main deployment playbook - `playbooks/templates/jnss-web.caddy.j2` - Caddy configuration template - `docs/jnss-web-deployment.md` - This documentation And modifies: - `roles/caddy/templates/Caddyfile.j2` - Removed default site section