Free Static Sites with GCS + Cloudflare ($0/month)
You can host a fully functional static site for exactly $0/month using Google Cloud Storage (GCS) free tier and Cloudflare's free plan. No servers, no databases, no hidden costs. Just flat files served over HTTPS with global CDN caching.
GCS's free tier gives you 5GB of storage, 1GB of egress per month, and 100K operations per month — more than enough for a personal blog, landing page, or documentation site. Cloudflare adds unlimited DNS management, a global CDN, free SSL certificates, and DDoS protection at no cost. Your only recurring bill is the domain name (~$10/year).
Step 1: Set up the GCS bucket
Create a bucket named after your domain (e.g., your-domain.com). GCS bucket names are global, so yours needs to be unique. Then make objects publicly readable and configure website serving:
gsutil mb -l us-central1 gs://your-domain.com
gsutil iam ch allUsers:objectViewer gs://your-domain.com
gsutil web set -m index.html gs://your-domain.com
That's it. The bucket is now serving index.html as the default page on its storage.googleapis.com endpoint. The allUsers:objectViewer binding makes files publicly readable without authentication.
Step 2: DNS with Cloudflare
Add your domain to Cloudflare and update your registrar's nameservers to the ones Cloudflare provides. Once Cloudflare is managing DNS:
- Add a CNAME record from
@(your root domain) toc.storage.googleapis.com. - Toggle the proxy (orange cloud) — this enables Cloudflare's CDN, free SSL termination, and DDoS protection.
- Wait for DNS propagation (usually a few minutes).
A CNAME to c.storage.googleapis.com is the standard way to point a custom domain to a GCS bucket. The proxy (orange cloud) gives you a free SSL certificate — Cloudflare handles it automatically.
Step 3: Website structure
No build tools, no bundlers, no frameworks. The src/ directory is the final artifact — everything in it goes straight to production:
src/
├── index.html
├── style.css
└── posts/
└── hello-world.html
Edit a file, push, deployed. That's the entire workflow.
Step 4: GitHub Actions for deploy
Automate deploys with a simple GitHub Actions workflow. Create .github/workflows/deploy.yaml in your repository:
name: deploy to cloud storage
on:
push:
paths: ['src/**']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- id: auth
uses: google-github-actions/auth@v1
with:
credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}'
- id: upload
uses: google-github-actions/upload-cloud-storage@v1
with:
path: src
destination: your-domain.com
parent: false
Set the GOOGLE_CREDENTIALS secret in your GitHub repository settings to a GCP service account key with storage.objectAdmin permissions on the bucket. The workflow triggers only when files under src/ change. Since parent: false, the src/ directory itself is stripped during upload — your files land at the bucket root.
Step 5: Cost breakdown
| Service | Free Tier | Real Cost |
|---|---|---|
| GCS | 5GB storage, 1GB egress | $0 |
| Cloudflare | DNS, CDN, SSL | $0 |
| GitHub Actions | 2000 min/month | $0 |
| Domain | ~$10/year | $0.83/mo |
| Total | $0.83/mo |
The domain is the only line item that costs anything. You can get a .eu or .dev domain for around $10/year at most registrars. Everything else — storage, bandwidth, DNS, SSL, CI/CD — is free.
When should you upgrade?
The GCS free tier handles low-traffic sites comfortably. If you exceed 1GB of monthly egress (roughly 10-20K page views with overhead), you'll pay ~$0.12/GB after the free tier — still dirt cheap. For most personal blogs and side projects, you'll never hit the limits.
GCS + Cloudflare is the cheapest way to host a static site. No servers, no databases, no maintenance. Just write, push, done.