Deploying a static site with Cloudflare Pages via GitHub

Cloudflare Pages gives you free, git-connected hosting for static sites and static-generator output (Hugo, Astro, Next.js static export, plain HTML). Push to main, get a deploy. Push to a branch, get a preview URL. This walkthrough covers the GitHub integration end to end: connecting the repo, build configuration, environment variables, custom domains, and preview deployments. Prerequisites A Cloudflare account (free tier is sufficient) Your site’s source in a GitHub repository A build command and output directory, if you’re using a static site generator (Hugo, Astro, Eleventy, etc.) — skip this if you’re deploying plain HTML/CSS/JS Step 1: connect the GitHub repository Log into the Cloudflare dashboard and select Workers & Pages from the left sidebar. Click Create application → Pages tab → Connect to Git. Authorize Cloudflare’s GitHub App if you haven’t already. You’ll be asked to grant access to either all repositories or a selected list — choose selected repositories and pick only what you need. Don’t grant blanket access to your whole GitHub account for a single site. Select the repository and branch you want to deploy from (usually main). Step 2: configure the build Cloudflare will try to auto-detect your framework. Verify or set: ...

Last updated:  · 5 min · Paul Masterson

How to make your website faster without buying anything

Work through the steps in order. Each one is small enough to do in under an hour, produces a measurable delta on PageSpeed Insights, and costs nothing beyond your own time. Step 10 covers server-level hardening — not strictly a “speed” fix, but a site getting hammered by bad bots is a slow site, so it belongs on the same list. New to the metric names below? See Core Web Vitals: what PageSpeed is actually measuring first — LCP, INP, CLS, TTFB, and TBT are explained there in plain terms. ...

Last updated:  · 9 min · Paul Masterson

Core Web Vitals: what PageSpeed is actually measuring

The fixes for everything below live in the companion piece: How to make your website faster without buying anything. The three that feed ranking Core Web Vitals are a set of standardised measurements Google uses to quantify real-world user experience on a webpage. Introduced in 2020, became a confirmed Google Search ranking signal in 2021. Three metrics: Metric What it measures Good threshold LCP Loading performance Under 2.5 s INP Interactivity Under 200 ms CLS Visual stability Under 0.1 The three that don’t (but are useful anyway) The others covered below — TTFB, FCP, TBT — are supporting metrics. They don’t affect rankings directly but they’re diagnostically useful: they tell you why your Core Web Vitals are poor. ...

Last updated:  · 8 min · Paul Masterson

Blocking countries from your website

A digital marketer I work with sent me a message last week. They were burning ad spend on traffic from regions they couldn’t sell to, getting hammered by bot requests from certain countries, and had read somewhere that you could just “add something to .htaccess” to fix it. They weren’t wrong. But they weren’t quite right either. Country blocking sounds simple. In practice, the right solution depends on your web server, whether you’re behind Cloudflare, your traffic volume, and how much maintenance overhead you’re willing to carry. This guide covers the two implementations I actually use in production, plus a few things the tutorials tend to skip. ...

Last updated:  · 9 min · Paul Masterson

tls-audit

What this script does tls-audit runs a read-only audit against a deployed HTTPS endpoint and reports on each item from the Nginx TLS 2026 guide and the nginx-tls config generator: Protocol support — TLS 1.0 and 1.1 should be rejected; TLS 1.2 and 1.3 should be accepted. Certificate — covers the hostname, not expired (and not expiring in the next 21 days), modern key algorithm, complete chain with at least one intermediate, not self-signed. OCSP stapling — the server should be stapling an OCSP response. HSTS — Strict-Transport-Security header present, max-age of at least one year, includeSubDomains directive set, preload flagged if present (informational, not a recommendation). Security headers — X-Content-Type-Options: nosniff and Referrer-Policy present; a Server header that leaks a version number is flagged. It uses only openssl s_client, curl, and standard text tools — no external scanner like testssl.sh required. Designed to run from a machine other than the host being audited, with no privilege. ...

Last updated:  · 9 min · Paul Masterson

Nginx Rate Limiting — limit_req, limit_conn, and fail2ban

Tested on: Ubuntu 24.04 LTS, Nginx 1.26.x (nginx.org stable repository). All directives are core Nginx — no third-party modules required. Why this matters A web tier with no rate limiting fails in three predictable ways: Authentication brute force. A WordPress, application, or admin-panel login form with no rate cap is one credential-stuffing tool away from compromise. Signup / forgot-password abuse. Endpoints that send email, provision accounts, or issue tokens are expensive and attractive to spammers. Single-tenant noise becomes shared-tenant outage. One misbehaving client (or one bot) hammering an endpoint can starve FPM workers, application-server threads, and database connections. Rate limiting is not DDoS protection — that lives at the CDN / WAF layer if you need it. Nginx rate limiting is for the predictable, day-to-day class of behaviour: too many requests from too few sources to too few endpoints. Get this right and your origin survives even when something at the edge fails. ...

Last updated:  · 7 min · Paul Masterson

Nginx TLS Configuration — 2026 Baseline

Tested on: Ubuntu 24.04 LTS, Nginx 1.26.x (from nginx.org stable repository), Let’s Encrypt via certbot 2.x. The same config works on RHEL 9 / AlmaLinux 9 with path adjustments noted inline. Why this matters Most Nginx TLS configurations on the internet were copy-pasted from a tutorial written three to seven years ago. That means they typically have one or more of the following problems: TLS 1.0 and 1.1 still enabled “for compatibility” with browsers that no longer exist. A hand-rolled cipher list that excludes modern AEAD suites or includes long-deprecated ones (3DES, RC4, CBC-mode without AEAD). ssl_prefer_server_ciphers on — which was correct advice once but is now the wrong default for TLS 1.3. No OCSP stapling, so every visitor’s browser does a side-channel OCSP lookup to the CA on first connection. HSTS missing, or HSTS set without includeSubDomains on a domain that has subdomains people forgot about. HTTP-only Strict-Transport-Security header (it must be served over HTTPS to be honoured at all). This guide gives you a single, opinionated baseline that addresses all of the above. It targets the Mozilla “Intermediate” profile — broad client compatibility without enabling anything embarrassing. ...

Last updated:  · 5 min · Paul Masterson