Skip to main content

Migrating from Dokku to Cloudflare Pages with Zero Trust Authentication

· 4 min read
Max Kaido
Architect

In our continuous effort to improve our infrastructure, we're migrating our static websites and React applications from Dokku to Cloudflare Pages. This migration will enhance performance, security, and simplify our deployment process.

Migration Overview

Our migration involves two key components:

  1. Mini App (React Application) - Currently deployed to Dokku using Git push
  2. Documentation Site (Docusaurus) - Currently using a custom Express server with basic authentication

By moving to Cloudflare Pages, we'll benefit from:

  • Global CDN for improved performance
  • Simplified deployment workflow
  • Enhanced security with Zero Trust authentication
  • Better scalability
  • Potentially lower costs

Migration Timeline

PhaseTaskEstimated TimeDependencies
1Set up Cloudflare Pages projects1 dayCloudflare account
2Configure GitHub workflows1 dayCloudflare API token
3Test deployments1-2 daysCompleted workflows
4Set up Zero Trust for docs1 dayDeployed docs site
5Switch DNS records1 hourSuccessful test deployments
6Decommission Dokku apps1 daySuccessful migration

Phase 1: Preparation

Cloudflare Account Setup

  1. Ensure your Cloudflare account has Pages enabled
  2. Create an API token with the necessary permissions:
    • Account > Cloudflare Pages > Edit
    • Note: You don't need Zone permissions if you'll manage custom domains through the Cloudflare UI
  3. Note your Cloudflare Account ID (found in the dashboard URL)

GitHub Repository Setup

  1. Add the following secrets to your GitHub repository:
    • CLOUDFLARE_API_TOKEN
    • CLOUDFLARE_ACCOUNT_ID

Phase 2: Mini App Migration

Create Cloudflare Pages Project

  1. Create a new Cloudflare Pages project named arcana-twa
  2. Choose "Direct Upload" as the deployment method

Configure GitHub Workflow

Create a new workflow file at .github/workflows/deploy_mini_app_cloudflare.yml:

name: 'Mini App Deploy to Cloudflare Pages'

on:
push:
branches:
- main
paths:
- 'apps/mini-app/**'
- 'packages/**'
- 'package.json'
- 'pnpm-lock.yaml'
workflow_dispatch:
inputs:
deploy_mini_app:
description: 'Deploy mini app'
required: false
default: true
type: boolean

permissions:
contents: read
deployments: write

jobs:
deploy_mini_app:
runs-on: [self-hosted, ok, 'X64', 'tiger']
name: Deploy Mini App to Cloudflare Pages
if: ${{ github.event_name == 'push' || inputs.deploy_mini_app == true }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

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

- name: Enable Corepack
run: |
corepack enable
corepack prepare pnpm@8 --activate

- name: Install dependencies
run: pnpm install

- name: Build Mini App
run: |
cd apps/mini-app
pnpm build

- name: Deploy to Cloudflare Pages
uses: cloudflare/pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: arcana-twa
directory: apps/mini-app/dist
gitHubToken: ${{ secrets.GITHUB_TOKEN }}

Verify Deployment

  1. Test the workflow by manually triggering it
  2. Check that the mini app is correctly deployed to Cloudflare Pages
  3. Test all functionality in the deployed app

Phase 3: Documentation Site Migration

Create Cloudflare Pages Project

  1. Create a new Cloudflare Pages project named ton-arcana-docs
  2. Choose "Direct Upload" as the deployment method

Configure GitHub Workflow

Create a new workflow file at .github/workflows/deploy_docs_cloudflare.yml:

name: 'Docs Deploy to Cloudflare Pages'

on:
push:
branches:
- main
paths:
- 'toma/**'
- 'package.json'
- 'pnpm-lock.yaml'
workflow_dispatch:
inputs:
deploy_docs:
description: 'Deploy docs'
required: false
default: true
type: boolean

permissions:
contents: read
deployments: write

jobs:
deploy_docs:
runs-on: [self-hosted, ok, 'tiger', 'X64']
name: Deploy Docs to Cloudflare Pages
if: ${{ github.event_name == 'push' || inputs.deploy_docs == true }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

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

- name: Enable Corepack
run: |
corepack enable
corepack prepare pnpm@8 --activate

- name: Install dependencies
run: |
pnpm config set node-linker hoisted
pnpm install --frozen-lockfile

- name: Build docs
run: |
pnpm -F @kaido/docs build

- name: Deploy to Cloudflare Pages
uses: cloudflare/pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: ton-arcana-docs
directory: toma/build
gitHubToken: ${{ secrets.GITHUB_TOKEN }}

Setting Up Zero Trust Authentication

To replace the basic authentication in our custom Express server, we'll use Cloudflare Zero Trust:

Step 1: Set Up Cloudflare Access

  1. Log in to your Cloudflare dashboard
  2. Navigate to Zero Trust > Access > Applications
  3. Click Add an application
  4. Select Self-hosted as the application type
  5. Configure the application:
    • Application name: TON Arcana Docs
    • Session duration: Choose an appropriate duration (e.g., 24 hours)
    • Application domain: Enter your documentation site domain
    • Application logo: Optional - upload your logo

Step 2: Create Access Policies

  1. In the same application setup, scroll down to Policies
  2. Click Add a policy
  3. Configure the policy:
    • Policy name: Documentation Access
    • Action: Allow
    • Rules: Configure who can access the documentation
      • Option 1 - Email domains: Allow specific email domains
      • Option 2 - Individual emails: Allow specific email addresses
      • Option 3 - One-time PIN: Allow access via email verification
  4. Click Save

Step 3: Configure Authentication Methods

  1. Navigate to Zero Trust > Settings > Authentication
  2. Enable your preferred authentication methods:
    • One-time PIN
    • Social login providers
    • Corporate identity providers (if applicable)

Benefits Over Basic Auth

  • More secure authentication with modern protocols
  • No hardcoded credentials in your codebase
  • Detailed access logs
  • Ability to revoke access instantly
  • Single sign-on capabilities
  • Customizable login experience

Phase 4: DNS Configuration

  1. Update DNS records to point to Cloudflare Pages
  2. For custom domains:
    • Configure the custom domain in Cloudflare Pages UI
    • Navigate to your project > Custom domains > Set up a custom domain
    • Follow the verification steps in the UI
  3. Ensure SSL/TLS is properly configured

Phase 5: Cutover

  1. Perform final testing on the Cloudflare-deployed applications
  2. Inform all stakeholders of the migration
  3. Monitor the new deployment for 1-2 weeks

Phase 6: Decommissioning

  1. Back up any necessary data from the Dokku apps
  2. Remove the Dokku apps:
    ssh dokku@95.216.19.225 apps:destroy arcana-twa
    ssh dokku@95.216.19.225 apps:destroy ton-arcana-docs
  3. Update internal documentation to reflect the new deployment process

Rollback Plan

In case of issues with the Cloudflare deployment:

  1. Revert DNS changes to point back to the Dokku apps
  2. Ensure Dokku apps are still operational
  3. Troubleshoot Cloudflare deployment issues
  4. Try migration again after resolving issues

Key Takeaways

  • Cloudflare Pages provides a simpler, more performant deployment solution
  • Zero Trust authentication offers better security than basic auth
  • The migration can be completed with minimal downtime
  • The new workflow reduces maintenance overhead
  • Cloudflare's global CDN improves performance for users worldwide