Lesson 07 · Hosting and deployment

Move the frontend to Cloudflare Pages.

Keep GitHub as the source of truth, publish the existing static site through Cloudflare's edge network, connect the custom domain, and learn from the build configuration that failed first.

Read this lesson online. Sign in or create an account to download the PDF.

What we wanted to accomplish

The Become SWE frontend already worked as a static HTML, CSS, and JavaScript site. We wanted Cloudflare Pages to become the production host without creating another repository, introducing a framework, or changing the public hostname.

Core lesson: GitHub stores and versions the source. Cloudflare deploys and serves it. DNS connects the human-readable hostname to the deployment.

Learning objectives

  • Separate source control, hosting, DNS, and backend responsibilities.
  • Configure Cloudflare Pages for a repository that has no build step.
  • Connect and verify swe.tickerbell.biz.
  • Diagnose a missing package.json error.
  • Retire the previous GitHub Pages setup safely.
  • Test deployment, navigation, downloads, accessibility, and security.

The final architecture

GitHub
source + history
Cloudflare Pages
deployment + CDN
Cloudflare DNS
custom domain
Visitor
swe.tickerbell.biz

A push to main triggers the production deployment. Future protected features can call a separate Google Cloud Run API; private logic and credentials do not belong in the frontend.

Why we changed

Cloudflare provides automatic Git deployments, global static delivery, HTTPS, custom-domain integration, and room for future edge security controls.

What stayed the same

The repository, branch, static files, public URL, and simple HTML/CSS/JavaScript architecture remained intact.

Cloudflare Pages configuration

SettingValue
Projectswe-tickerbell
Production branchmain
Framework presetNone
Build commandEmpty
Build output directory.
Root directoryEmpty

Implementation steps

  1. Open Cloudflare → Workers & Pages and create a Pages project.
  2. Connect the GitHub repository tickerbell-biz/swe-tickerbell.
  3. Select main as the production branch.
  4. Use the exact static-site settings shown above.
  5. Deploy and first verify the generated swe-tickerbell.pages.dev address.
  6. Open the Pages project's Custom domains area and add swe.tickerbell.biz.
  7. Verify the DNS CNAME and then test the HTTPS site.

The build that failed

The first attempt used a common JavaScript build command:

npm run build

Cloudflare could not find the file that npm requires:

ENOENT: no such file or directory, open '/repo/package.json'

The repository was not broken. The deployment configuration was wrong for the repository. The site already contained browser-ready files, so it did not need npm, Astro, React, or a compilation step.

Correction: Framework None, empty build command, output directory ., and empty root directory.

Custom domain and DNS

Cloudflare DNS manages the tickerbell.biz zone. The verified frontend record is:

TypeNameTargetStatus
CNAMEswe.tickerbell.bizswe-tickerbell.pages.devProxied, TTL Auto

Add the custom domain inside the Pages project before relying on a manual DNS record. Cloudflare must associate the hostname and certificate with the correct project.

A separate email-DNS observation

The DNS review also showed mail and DKIM CNAME records using the orange-cloud proxy. Mail-related records normally need DNS-only resolution. We did not modify them during this deployment lesson; they remain a separate follow-up that should be checked against the email provider's instructions.

Retire GitHub Pages safely

  1. Confirm the Cloudflare custom domain is active and the production site works.
  2. In the GitHub repository, open Settings → Pages.
  3. Change the publishing source to None or choose GitHub's unpublish option.
  4. Confirm the custom domain still works through Cloudflare.
  5. Remove the repository CNAME file only after that verification.

Verification note: the repository still contained a CNAME file when this lesson was prepared, while the connected integration could not read the GitHub Pages settings endpoint. Treat this cleanup as pending until independently confirmed.

Security and privacy

  • Never commit Cloudflare or GitHub tokens, passwords, service-account keys, or environment files.
  • Treat every browser-delivered file as public, regardless of repository visibility.
  • Keep customer data and protected documents out of the frontend.
  • Enforce authentication and authorization in a trusted backend.
  • Grant integrations only the repository access they require.
  • Use multifactor authentication and keep a documented rollback path.

Testing and verification

curl -I https://swe.tickerbell.biz/
curl -I https://swe.tickerbell.biz/lesson7/
curl -I https://swe.tickerbell.biz/lesson7/Lesson-7-Moving-Frontend-Hosting-to-Cloudflare-Pages.pdf
  • The homepage shows Lesson 7 and opens this page.
  • Lesson 6 links forward and Lesson 7 links back.
  • The public PDF opens over HTTPS.
  • The page remains readable on desktop, tablet, and mobile.
  • Keyboard focus is visible and links have clear labels.
  • The deployment corresponds to the intended Git commit.

Key takeaways

  • Inspect the repository before choosing deployment commands.
  • GitHub and Cloudflare serve different, complementary roles.
  • A custom domain is routing configuration, not the website itself.
  • Git, deployment, DNS, TLS, and browser behavior require separate checks.
  • Make unrelated DNS changes in separate, reviewable steps.

Continue to Lesson 8

Connect Auth0 to Cloudflare Pages: configure login, three roles, permissions and branding. The current phase uses Cloudflare for the planned backend; Google Cloud is deferred.

Keep GitHub as the source. Let Cloudflare publish the frontend.

The migration succeeded by matching the hosting configuration to the repository that actually existed: a static site with no build step.

Download the complete PDF →

Contact · Budapest

Let’s build a conversation.

Collaborations, partnerships, or a question about the journey.

info@tickerbell.biz

Népfürdő u. 22B · 1138 Budapest, Hungary
Monday–Friday, 9:00–17:00 CET / CEST

Find our office