- JavaScript 61.7%
- CSS 32.3%
- HTML 5.4%
- Dockerfile 0.6%
|
All checks were successful
Build and Deploy to Cloud Run / deploy (push) Successful in 42s
|
||
|---|---|---|
| .claude | ||
| .forgejo/workflows | ||
| .vscode | ||
| public | ||
| src | ||
| .gcloudignore | ||
| .gitignore | ||
| bun.lock | ||
| Dockerfile | ||
| index.html | ||
| nginx.conf | ||
| package.json | ||
| README.md | ||
| vite.config.js | ||
feikowielsma.nl — personal site
Static single-page site built with React + Vite (using Bun).
Just index.html — drop it anywhere that serves files over HTTP.
Before going live
1. Add your photo
Drop a photo (e.g. avatar.png) into the same folder as index.html.
Then in index.html, find:
<div className="avatar-placeholder">
Replace that whole block with:
<img src="avatar.png" alt="Feiko Wielsma"
style={{ width: 240, height: 280, borderRadius: 20, objectFit: "cover" }} />
2. Wire up the contact form (Formspree — free, no backend needed)
- Go to formspree.io and create a free account
- Click New Form, name it anything, copy your form ID (looks like
xrgvkpqz) - In
index.html, find:
Replacefetch("https://formspree.io/f/YOUR_FORM_ID"YOUR_FORM_IDwith your actual ID. - Done. Formspree handles delivery, spam filtering, and optional reCAPTCHA from their dashboard.
Free tier = 50 submissions/month — more than enough for a personal site.
3. Check your social links
Search index.html for these and confirm they're correct:
linkedin.com/in/feikowielsmagithub.com/feikowielsmafeiko@feikowielsma.nl(assembled in JS, search forfeikowielsma)
Hosting options
Option A — Cloudflare Pages (recommended, free, ~5 min setup)
Best option: free, fast, SSL included, custom domain trivial.
- Push
index.html(+ your photo) to a GitHub repo - Go to pages.cloudflare.com
- Connect your GitHub repo, no build command, output directory =
/(root) - Deploy → you get a
.pages.devURL immediately - Go to Custom Domains → add
feikowielsma.nl - Point your domain's nameservers to Cloudflare (your registrar's DNS settings), or add a CNAME record:
CNAME @ <your-site>.pages.dev
Cost: €0/month
Option B — GCP Cloud Storage (static, cheap, slightly more manual)
Good if you already use GCP and want everything in one place.
- Create a bucket named exactly
feikowielsma.nlin Cloud Console - Upload
index.htmland your photo - Make the bucket public: IAM → add
allUserswith roleStorage Object Viewer - Enable Static website hosting on the bucket (index page =
index.html) - Point your domain DNS:
- Add a
CNAMErecord:www→c.storage.googleapis.com - For the apex (
@), use aArecord pointing to216.239.32.21(GCP load balancer) — requires setting up a Cloud Load Balancer + SSL cert (more involved) - Easier: just redirect
feikowielsma.nl→www.feikowielsma.nlat your registrar
- Add a
Cost: ~€0.02/month (storage) + negligible egress
Option C — GCP Cloud Run (Docker, if you want a tiny backend later)
Use this if you eventually want a real backend (e.g. your own contact form endpoint instead of Formspree).
Dockerfile
FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
COPY avatar.png /usr/share/nginx/html/avatar.png
EXPOSE 8080
CMD ["nginx", "-g", "daemon off;"]
Note: Cloud Run expects port 8080 — add this to your nginx config or use the env var
PORT.
nginx.conf (save next to Dockerfile)
server {
listen 8080;
server_name _;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
Deploy
# Build and push
gcloud builds submit --tag gcr.io/YOUR_PROJECT_ID/feiko-site
# Deploy to Cloud Run
gcloud run deploy feiko-site \
--image gcr.io/YOUR_PROJECT_ID/feiko-site \
--platform managed \
--region europe-west4 \
--allow-unauthenticated \
--port 8080
# Map your domain (Cloud Run console → Custom Domains)
Cost: €0/month when idle (scales to zero). You pay only for actual requests — essentially free for a personal site.
DNS quick reference (wherever your domain is registered)
For Cloudflare Pages (simplest):
CNAME @ <yoursite>.pages.dev
CNAME www <yoursite>.pages.dev
For Cloud Run / Cloud Storage with a load balancer:
A @ <load-balancer-IP>
CNAME www <load-balancer-IP or ghs.google.com>
SSL/TLS is handled automatically by Cloudflare Pages and Cloud Run.
Cloud Storage requires setting up a Google-managed cert on a load balancer if you want HTTPS on the apex domain.
Files in this project
src/ — React source files
public/ — static assets (icons, fonts)
bun.lock — Bun lockfile
package.json — project configuration
Dockerfile — container build instructions
README.md — this file