//Technology

Deploy Static Sites on Cloudflare Pages with GitHub Actions

Deploy static sites with Cloudflare Pages, GitHub Actions, and a custom subdomain for automated, secure, global hosting.

5 min read
Deploy Static Sites on Cloudflare Pages with GitHub Actions

Static sites are lightweight, secure, and inexpensive to host. They work well for blogs, portfolios, documentation, or marketing pages. Cloudflare Pages removes the operational burden by offering a global CDN, automatic builds, and built‑in SSL. GitHub Actions can be used to automate the entire deployment pipeline. This guide shows how to create a repository for a static site, set up a Cloudflare Pages project, configure a GitHub Actions workflow for continuous deployment, and map a custom subdomain such as blog.example.com to the site.

1. Prepare Your Static Site Repository

Start with a GitHub repository that contains the files you want to serve. If you already have a project, skip to the next step. Otherwise, use the commands below to create a new repository from a starter template.

# Clone a starter template (example uses a Jekyll site)
git clone https://github.com/cloudflare/pages-jekyll-template.git my-static-site
cd my-static-site

# Initialise a new repo (if you prefer a fresh start)
git init
git remote add origin https://github.com/your‑username/your‑repo.git
git add .
git commit -m "Initial commit"
git push -u origin main

Ensure the repository’s default branch is main (or master if you prefer). Cloudflare Pages pulls the source from this branch.

2. Create a Cloudflare Pages Project

  1. Log in to your Cloudflare dashboard and select the account where you want the site.
  2. Navigate to Pages → Create a Project.
  3. Choose Connect to Git and select GitHub. Authorise Cloudflare to access your repositories if prompted.
  4. Select the repository you created in step 1.
  5. Configure the build settings:
    • Production branch: main (or your chosen branch)
    • Build command: depends on your static‑site generator (e.g., jekyll build, npm run build, or leave blank for plain HTML).
    • Build output directory: the folder that contains the final HTML files (commonly _site, dist, or public).
  6. Click Save and Deploy. Cloudflare will run the first build and publish a preview URL.

At this point your site is live on a Cloudflare‑provided subdomain like your-project.pages.dev. The next sections show how to automate future builds and attach a custom subdomain.

3. Automate Deployments with GitHub Actions

Cloudflare Pages triggers a build on every push, but a GitHub Actions workflow gives you additional control. You can run tests, linting, or generate assets before the Pages build starts.

3.1 Create the Workflow File

Add a file named .github/workflows/pages-deploy.yml to your repository:

name: Deploy to Cloudflare Pages

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm ci

      - name: Run lint
        run: npm run lint

      - name: Build site
        run: npm run build

      - name: Deploy to Cloudflare Pages
        uses: cloudflare/pages-action@v1
        with:
          apiToken: ${{ secrets.CF_PAGES_TOKEN }}
          accountId: ${{ secrets.CF_ACCOUNT_ID }}
          projectName: your-project-name
          directory: ./dist

3.2 Store Secrets Securely

In your GitHub repository go to Settings → Secrets → Actions and add:

  • CF_PAGES_TOKEN – a Cloudflare API token with the Pages:Edit permission.
  • CF_ACCOUNT_ID – your Cloudflare account identifier (visible in the dashboard URL).
  • CF_PROJECT_NAME – the exact name of the Pages project (optional if hard‑coded in the workflow).

These secrets are encrypted and never appear in logs.

3.3 Verify the Pipeline

Push a change to main. GitHub Actions will run the workflow, and you’ll see a successful “Deploy to Cloudflare Pages” step. The Pages project will receive the new build automatically.

4. Configure a Custom Subdomain (e.g., blog.example.com)

Because DNS is managed by Cloudflare, mapping a subdomain is straightforward.

  1. In the Cloudflare dashboard, select the domain you own (e.g., example.com).
  2. Go to DNS → Records and click Add record.
  3. Choose Type: CNAME.
  4. Set Name: the subdomain you want (e.g., blog).
  5. Set Target: the Pages domain you received earlier (e.g., your-project.pages.dev).
  6. Leave TTL at Auto and ensure the proxy status is Proxied (orange cloud) so Cloudflare’s CDN and SSL are applied.
  7. Save the record.

Cloudflare provisions an SSL certificate for the new subdomain automatically. After DNS propagation, blog.example.com serves the same content as the default your-project.pages.dev URL.

5. Optional Enhancements

5.1 Add a Custom 404 Page

Place a 404.html file in your build output directory. Cloudflare Pages will serve it for requests that do not match an existing file.

5.2 Enable Redirects or Rewrite Rules

Create a _redirects file (Netlify‑style) or a _headers file for fine‑grained control. For example, to redirect /old‑path to /new‑path:

/old-path  /new-path  301

These files are processed during the build step and work seamlessly with the GitHub Actions workflow.

5.3 Integrate Form Handling

Static sites cannot process forms server‑side. Cloudflare Forms (available on certain plans) captures submissions without code. Add the attribute data-cfemail to your form element and configure the destination email in the Cloudflare dashboard.

6. Monitoring and Troubleshooting

  • Build logs: In Cloudflare Pages, open the latest deployment to view the build output. Errors from your static‑site generator appear here.
  • GitHub Actions logs: In the Actions tab of your repo, inspect step‑by‑step results. Look for failed commands or missing secrets.
  • DNS checks: Run dig blog.example.com CNAME or use an online DNS checker to confirm the CNAME points to *.pages.dev.
  • SSL verification: Visit https://blog.example.com and inspect the certificate; it should be issued by “Cloudflare Inc ECC CA‑3”.

Conclusion

Combining Cloudflare Pages, GitHub Actions, and a custom subdomain gives you a fully automated, globally distributed hosting solution for static sites. The workflow scales from a personal blog to a corporate documentation portal, and Cloudflare’s edge network handles performance and security. Keep your repository updated, let GitHub Actions run the build, and enjoy smooth deployments every time you push a change.

static sitescloudflare pagesgithub actionscontinuous deploymentcustom subdomaindns configurationbuild automationweb hosting

Try it on your own server

Follow along on a Cloud VPS with full root access, or read the step-by-step knowledge base guides.

Guides: VPS for WordPress · Node.js hosting · VPS or dedicated server · Paying by UPI