Xshell Pro

2026-05-02 08:47:50

Deploying a Full-Stack Next.js App to Cloudflare Workers with GitHub Actions CI/CD: A Step-by-Step Guide

A comprehensive guide to deploying a full-stack Next.js 14 (App Router) + Supabase app on Cloudflare Workers using @opennextjs/cloudflare, including local setup, secrets management, and GitHub Actions CI/CD pipeline. Covers benefits over Vercel, step-by-step instructions with code, and common pitfalls.

Overview

Every developer wants a fast, cost-effective deployment for their Next.js projects. While Vercel remains the go-to platform for many, Cloudflare Workers offers a compelling alternative with near-zero cold starts, a generous free tier, and edge distribution across 300+ locations. With the arrival of @opennextjs/cloudflare, deploying a standard Next.js 14 app (App Router) with SSR, ISR, middleware, and the Image component is finally straightforward — no more fighting with workarounds.

Deploying a Full-Stack Next.js App to Cloudflare Workers with GitHub Actions CI/CD: A Step-by-Step Guide
Source: www.freecodecamp.org

In this tutorial, we will walk through deploying a full-stack Next.js + Supabase application to Cloudflare Workers, complete with a continuous deployment pipeline using GitHub Actions. By the end, you’ll have your own runbook for a smooth, repeatable deployment process.

Prerequisites

Before you begin, ensure you have the following ready:

  • A Next.js 14 project using the App Router (with or without Supabase).
  • Node.js 18+ installed locally.
  • A Cloudflare account (free tier works).
  • Your Cloudflare API token with Workers and Pages permissions.
  • A GitHub repository for your project.
  • Supabase project credentials (if using Supabase).

Familiarity with basic Git, command line, and GitHub Actions is helpful but not required; we will cover every command.

The Stack

We’re using Next.js 14 (App Router) for the frontend, Supabase for authentication and Postgres database, @opennextjs/cloudflare as the adapter, and Cloudflare Workers as the runtime. CI/CD is handled by GitHub Actions.

Step-by-Step Instructions

Step 1 — Install the Cloudflare Adapter

Inside your Next.js project root, install the required package:

npm install @opennextjs/cloudflare

This adapter compiles your Next.js application into a format compatible with Cloudflare Workers. It supports SSR, ISR, middleware, and — through the IMAGES binding — image optimization.

Step 2 — Wire OpenNext into next dev

To use the same runtime during local development, add a custom script in your package.json:

"scripts": {
  "dev": "opennextjs-cloudflare",
  "build": "opennextjs-cloudflare build",
  "start": "wrangler pages dev"
}

This replaces the standard Next.js dev server with OpenNext’s local Cloudflare Workers simulation. Run npm run dev to test locally.

Step 3 — Local Environment Setup with .dev.vars

In the root of your project, create a file named .dev.vars to store local environment variables (e.g., Supabase URL and anon key). Format:

SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-key

Add .dev.vars to your .gitignore so secrets never leak.

Step 4 — Deploy Your App from Your Local Machine

First, build the worker bundle:

npm run build

Then deploy using Wrangler (Cloudflare’s CLI tool). Ensure you have logged in:

npx wrangler login
npx wrangler pages deploy .open-next --project-name my-next-app

This uploads the compiled output to Cloudflare Pages (which runs on Workers). You’ll get a preview URL like https://my-next-app.pages.dev.

Step 5 — Push Your Secrets to the Worker

Production secrets (Supabase credentials, etc.) must be added separately via Wrangler:

npx wrangler pages secret put SUPABASE_URL
npx wrangler pages secret put SUPABASE_ANON_KEY

You’ll be prompted to enter the values. These are now encrypted and available to your Worker at runtime.

Step 6 — Set Up Continuous Deployment with GitHub Actions

Create a file .github/workflows/deploy.yml in your repository:

name: Deploy to Cloudflare Workers

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 18
      - run: npm ci
      - run: npm run build
      - name: Deploy to Cloudflare Pages
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CF_API_TOKEN }}
          command: pages deploy .open-next --project-name my-next-app

Add your Cloudflare API token as a secret named CF_API_TOKEN in your GitHub repository settings. Now every push to main triggers a build and deploy.

Step 7 — Updating the Project (The Daily Workflow)

Your daily routine becomes:

  1. Make changes locally.
  2. Test with npm run dev (uses OpenNext simulation).
  3. Commit and push to main.
  4. GitHub Actions builds and deploys automatically.
  5. Check deployment logs in the Actions tab.

For environment variable changes, update them via wrangler pages secret put or in the Cloudflare dashboard, then redeploy.

Common Mistakes

  • Forgetting to add .dev.vars to .gitignore: This exposes sensitive data. Always ignore it.
  • Using Node.js native modules: Cloudflare Workers run on V8 isolates, not Node.js. Avoid fs, crypto (use Web Crypto API), and child_process.
  • Missing API token permissions: Your Cloudflare token must have Workers and Pages write permissions for the deploy action to succeed.
  • Not running opennextjs-cloudflare build before deploy: The standard next build won’t produce a Worker‑compatible bundle.
  • Using relative paths for environment variables inside wrangler.toml: Prefer Wrangler CLI commands or secrets dashboard to set variables for Workers.

Summary

We have deployed a full-stack Next.js + Supabase application to Cloudflare Workers using the @opennextjs/cloudflare adapter, with a GitHub Actions CI/CD pipeline. The process is simple: install the adapter, adjust your dev script, configure local variables, build and deploy manually once, then let automation handle future releases.

The benefits are tangible: lower latency thanks to Cloudflare’s global edge, near‑zero cold starts, and a free tier that can handle millions of requests per month. The trade-off — a different runtime environment with limited Node.js APIs — is manageable for most modern Next.js apps.

Now you have a reproducible runbook. Deploy with confidence and explore the edge.