Skip to content

michaelalbertshofer/Homepage

Repository files navigation

Portfolio Website - Cloudflare Workers Deployment

Modern portfolio website deployed on Cloudflare Workers with SvelteKit. Features dynamic content from self-hosted Directus CMS, smooth animations, and global CDN delivery.

Technology Stack

  • Frontend Framework: SvelteKit 2.x with Svelte 5
  • Deployment: Cloudflare Workers (via Cloudflare Pages)
  • CMS: Self-hosted Directus v11 at cms.albertshofer.net
  • Language: TypeScript
  • Build Tool: Vite 7
  • CI/CD: GitLab CI

Project Structure

/
├── src/
│   ├── lib/
│   │   ├── components/      # Svelte components
│   │   ├── stores/          # State management
│   │   ├── types.ts         # TypeScript types
│   │   └── api.ts           # API calls to Directus
│   ├── routes/              # SvelteKit routes
│   │   ├── +layout.svelte   # Main layout
│   │   ├── +page.svelte     # Homepage
│   │   ├── architektur/     # Architecture projects
│   │   ├── fotografie/      # Photography projects
│   │   └── kontakt/         # Contact page
│   ├── app.html             # HTML template
│   └── app.css              # Global styles
├── static/                  # Static assets
├── wrangler.toml            # Cloudflare Workers config
├── .gitlab-ci.yml           # CI/CD pipeline
└── package.json             # Dependencies

Prerequisites

  • Node.js 20+ and npm
  • Cloudflare account (free tier works)
  • Wrangler CLI: npm install -g wrangler
  • GitLab account (for CI/CD)

Local Development

1. Install Dependencies

npm install

2. Configure Environment (Optional)

Create .env if you need environment-specific variables:

# Example: Override CMS URL for local testing
PUBLIC_CMS_URL=https://cms.albertshofer.net

3. Start Development Server

npm run dev

Visit http://localhost:5173

4. Build for Production

npm run build

Output will be in .svelte-kit/cloudflare

Cloudflare Workers Setup

1. Authenticate Wrangler

wrangler login

This opens a browser to authenticate with your Cloudflare account.

2. Create Cloudflare Pages Project

Option A: Via Dashboard

  1. Go to Cloudflare Dashboard
  2. Navigate to Workers & Pages
  3. Create a new Pages project
  4. Name it portfolio-albertshofer (matches wrangler.toml)

Option B: Via CLI (first deployment will auto-create)

npm run deploy

3. Configure Custom Domains

In Cloudflare Dashboard under your Pages project:

  1. Go to "Custom domains"
  2. Add albertshofer.net
  3. Add www.albertshofer.net (optional)
  4. Cloudflare will automatically provision SSL certificates

4. Environment Variables (if needed)

If you need runtime variables:

wrangler pages secret put CMS_URL
# Enter: https://cms.albertshofer.net

Deployment

Manual Deployment

# Build and deploy
npm run build
wrangler pages deploy .svelte-kit/cloudflare --project-name=portfolio-albertshofer

GitLab CI/CD Deployment

1. Set up GitLab CI Variables

In your GitLab project, go to Settings > CI/CD > Variables and add:

2. Pipeline Configuration

The pipeline has two stages:

Build Stage (automatic on push):

  • Runs npm ci && npm run build
  • Creates artifact with built files
  • Runs on main and develop branches

Deploy Stages (manual trigger):

  • Production (main branch): Deploys to albertshofer.net
  • Preview (develop branch): Deploys to preview URL

3. Triggering Deployments

  1. Push to main or develop
  2. Wait for build to complete
  3. Go to GitLab CI/CD > Pipelines
  4. Click "Play" button on deploy job
  5. Deployment will start automatically

4. Environment URLs

Directus CMS Configuration

Required CORS Settings

In your Directus .env:

CORS_ENABLED=true
CORS_ORIGIN=https://albertshofer.net,https://www.albertshofer.net,https://*.pages.dev

Public API Permissions

Ensure the Public role has read access to:

  • projects collection (all fields)
  • directus_files (for images)

Architecture Decisions

Why Cloudflare Workers?

  1. Future-proof: Cloudflare is investing in Workers, not Pages
  2. Global Performance: Edge computing with <50ms response times
  3. Zero Infrastructure: No servers, containers, or orchestration
  4. Free Tier: Unlimited requests and bandwidth
  5. Automatic Scaling: Handles traffic spikes effortlessly

SSR vs Static

This setup uses hybrid rendering:

  • Static pages are pre-rendered at build time
  • Dynamic routes can use SSR if needed
  • API routes run on Workers edge

CMS Separation

The CMS remains self-hosted because:

  • Full control over data and backups
  • No vendor lock-in for content
  • Directus can be updated independently
  • Frontend can be rebuilt without touching CMS

Performance

Expected metrics:

  • TTFB: <100ms (Cloudflare edge)
  • FCP: <1s (optimized bundle)
  • LCP: <2s (image optimization)
  • CLS: <0.1 (stable layouts)

Troubleshooting

Build Fails

Check Node.js version:

node --version  # Should be 20+

Clear cache and reinstall:

rm -rf node_modules .svelte-kit
npm install

Deployment Fails

Verify Wrangler authentication:

wrangler whoami

Check project name matches wrangler.toml:

cat wrangler.toml | grep name

CMS Connection Issues

  1. Check CMS is accessible: curl https://cms.albertshofer.net
  2. Verify CORS settings in Directus
  3. Check browser console for CORS errors
  4. Ensure API permissions are set correctly

SSL/Domain Issues

  1. Wait 5-10 minutes after adding custom domain (DNS propagation)
  2. Check DNS records point to Cloudflare
  3. Verify SSL certificate status in Cloudflare Dashboard
  4. Try clearing browser cache

Development Workflow

Typical Development Cycle

  1. Make changes locally
  2. Test with npm run dev
  3. Commit and push to develop branch
  4. GitLab CI builds automatically
  5. Manually trigger preview deployment
  6. Review at preview URL
  7. Merge to main when ready
  8. Manually trigger production deployment

Local Testing with Wrangler

# Start local Cloudflare Workers environment
npm run build
wrangler pages dev .svelte-kit/cloudflare

This simulates the Cloudflare Workers runtime locally.

Maintenance

Updating Dependencies

npm update
npm audit fix

Monitoring

  • Analytics: Cloudflare Dashboard > Analytics
  • Logs: wrangler pages deployment tail
  • Performance: Cloudflare Web Analytics (free)

Rollback

If a deployment has issues:

# List deployments
wrangler pages deployment list --project-name=portfolio-albertshofer

# Rollback to specific deployment
wrangler pages deployment rollback [deployment-id] --project-name=portfolio-albertshofer

Or use Cloudflare Dashboard > Deployments > Rollback

Security

Content Security Policy

Configured in app.html or via Cloudflare Workers:

  • Restricts resource loading
  • Prevents XSS attacks
  • Configured for Directus CMS domain

Secrets Management

Never commit secrets! Use:

  • GitLab CI/CD Variables (masked)
  • Wrangler secrets for runtime

Rate Limiting

Consider adding rate limiting via Cloudflare:

  1. Go to Security > WAF
  2. Set rate limiting rules
  3. Protect against DDoS

Migration from Docker/Nginx

What Changed

Removed:

  • ❌ Nginx configuration
  • ❌ Docker containers for frontend
  • ❌ Traefik reverse proxy
  • ❌ Server maintenance

Kept:

  • ✅ Same SvelteKit codebase
  • ✅ Same Directus CMS (self-hosted)
  • ✅ Same domain names
  • ✅ Same content structure

Benefits

  • Cost: $0 for frontend hosting
  • Performance: Global CDN vs single server
  • Maintenance: No server updates or patches
  • Scalability: Unlimited concurrent users
  • Reliability: Cloudflare's 100% uptime SLA

Support

Documentation Links

GitLab Repository

  • Remote: (Set up your GitLab remote URL)
  • Branch: main (production), develop (staging)

Last Updated: 2025-01-13 Version: 1.0.0 Author: Michael Albertshofer

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •