A starter template for building a static site with Astro and managing its content with Decap CMS, all deployed on Cloudflare Pages. This setup includes a Cloudflare Worker acting as a custom GitHub OAuth proxy, allowing you to authenticate via GitHub without relying on Netlify Identity or Git Gateway. Additionally, you can use Cloudflare Zero Trust (Access) to add an extra layer of security to your /admin page.
- Astro for building fast, content-focused static sites.
- Decap CMS for an editor-friendly content management UI.
- Cloudflare Pages for fast, globally-distributed static hosting.
- Cloudflare Worker (OAuth Proxy) for handling GitHub OAuth without external services.
- GitHub Backend for storing and versioning content as Markdown files directly in your repo.
- (Optional) Cloudflare Zero Trust for restricting access to the
/admininterface to authorized users only.
- Node.js and npm installed locally.
- A GitHub account with a repository set up for your site’s content.
- A Cloudflare account with a domain configured (optional but recommended for custom domains).
- A GitHub OAuth application for authentication.
You can either use this repository as a boilerplate to get started quickly or follow the manual setup instructions to configure each component individually.
-
Clone the Repository
git clone https://github.com/jshuntley/astro-decap-cloudflare-starter.git cd astro-decap-cloudflare-starter -
Install Dependencies
npm i
-
Configure GitHub OAuth Proxy
- Follow step 4 in the manual setup section below to set up and deploy the Cloudflare Worker.
-
Set Up Cloudflare Zero Trust
- Follow step 5 in the manual setup section below to secure your
/adminpage.
- Follow step 5 in the manual setup section below to secure your
-
Deploy to Cloudflare Pages
- Follow step 6 in the manual setup section below to deploy your site.
-
Access the CMS
- Navigate to
https://your-domain.com/adminand log in with GitHub to start managing your content.
- Navigate to
Follow these steps to manually set up each component of the stack.
-
Install Node.js and npm Ensure you have Node.js installed on your machine. Verify installation:
node -v npm -v
-
Create a New Astro Project
npm create astro@latest my-astro-site cd my-astro-site npm install -
Build the Project as Desired
Customize your Astro project by adding pages, components, styles, and other assets.
- Example: Create a simple homepage by editing
src/pages/index.astro:--- title: "Home" --- <html> <head> <title>{title}</title> </head> <body> <h1>Welcome to My Astro Site</h1> </body> </html>
- Example: Create a simple homepage by editing
-
Test the Project Locally
npm run dev
Open your browser and navigate to
http://localhost:4321to view your site.
-
Add Decap CMS Configuration
-
Create the Admin Directory:
mkdir -p public/admin
-
Create
config.yml: Inpublic/admin/, create a file namedconfig.ymlwith the following content. Replace placeholders with your actual GitHub repository details.backend: name: github repo: "your-username/your-repo" # Replace with your GitHub username/repo branch: main base_url: "https://decap.your-domain.com" # This subdomainis for the OAuth proxy auth_endpoint: "auth" # Default path for authentication site_url: "https://your-domain.com" media_folder: "public/images/uploads" public_folder: "/images/uploads" collections: - name: "pages" label: "Pages" folder: "src/pages" create: true slug: "{{slug}}" fields: - { label: "Title", name: "title", widget: "string" } - { label: "Body", name: "body", widget: "markdown" }
-
-
Add Decap CMS Interface
-
Create
index.html:In
public/admin/, create anindex.htmlfile with the following content:<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Content Manager</title> </head> <body> <!-- Include the Decap CMS script --> <script src="https://unpkg.com/decap-cms@latest/dist/decap-cms.js"></script> </body> </html>
-
-
Verify Decap CMS Integration
- Run the Development Server:
npm run dev
- Access the CMS Interface:
Navigate to
http://localhost:4321/adminin your browser. You should see the Decap CMS interface with the "Login with GitHub" button.
- Run the Development Server:
-
Navigate to GitHub Developer Settings
- Go to GitHub Developer Settings.
-
Register a New OAuth App
-
Click on "New OAuth App".
-
Fill in the Application Details:
- Application name:
Decap CMS OAuth Proxy(or any name you prefer). - Homepage URL:
https://your-domain.com(your main site). - Authorization callback URL:
https://decap.your-domain.com/callback(the subdomain specifically for the OAuth proxy).
- Application name:
-
-
Save the OAuth App
- Click "Register application".
- Note the Client ID and Client Secret:
You can save these to
decap-proxy/.envfile for local development. You'll need these credentials later when configuring the Cloudflare Worker.
- This is intended to operate on a subdomain of your domain. eg
decap.your-domain.com
-
Clone the decap-proxy Repository
git clone https://github.com/sterlingwes/decap-proxy.git cd decap-proxy cp wrangler.toml.sample wrangler.toml -
Configure
decap-proxy/wrangler.toml-
Edit
decap-proxy/wrangler.toml:
Opendecap-proxy/wrangler.tomlin your preferred editor and make the following changes:name = "decap-proxy" main = "src/index.ts" compatibility_date = "2024-04-19" # Update as needed compatibility_flags = ["nodejs_compat"] workers_dev = false route = { pattern = "decap.your-domain.com", zone_name = "your-domain.com" } # Replace with your domain
- Explanation:
workers_dev = false: Disables the defaultworkers.devsubdomain.route:pattern: The subdomain where the OAuth proxy will be accessible (e.g.,decap.your-domain.com).zone_name: Your main domain managed in Cloudflare (e.g.,your-domain.com).
- Explanation:
-
Ensure the Worker Requests the Correct Scopes:
If your repository is private, you need to request thereposcope. This allows Decap CMS to access and modify private repositories.In your
decap-proxy/src/index.tsfile, line 30,you can see thescopeparameter is set to'public_repo,user'. This is the default scope for public repositories.const authorizationUri = oauth2.authorizeURL({ redirect_uri: `https://${url.hostname}/callback?provider=github`, scope: "public_repo,user", // change this to 'repo' if your repository is private state: randomBytes(4).toString("hex"), });
-
While still in the decap-proxy directory, deploy the worker to Cloudflare.
-
Login to Cloudflare via Wrangler
npx wrangler login
- This command will open a browser window prompting you to authenticate with Cloudflare.
-
Deploy the Worker
npm run deploy
-
Navigate to the Cloudflare Dashboard
- Go to Cloudflare Dashboard.
-
Access Workers Settings
- Click on "Workers & Pages" in the sidebar.
- Select "Workers" and then choose your deployed worker (
decap-proxy).
-
Add Environment Variables
- Go to "Settings" > "Variables".
- Under "Environment Variables", add the following Secret Variables:
GITHUB_OAUTH_ID: Your GitHub OAuth application's Client ID.GITHUB_OAUTH_SECRET: Your GitHub OAuth application's Client Secret.
-
Save the Variables
- Ensure both variables are saved correctly as secrets.
-
Navigate to Cloudflare Zero Trust Dashboard
- Go to Cloudflare Zero Trust dashboard.
-
Set Up an Access Policy
-
Go to "Access" > "Applications":
- Click on "Add an application".
-
Choose "Self-hosted":
- Select "Self-hosted" as the application type.
-
Configure Application Settings:
- Application Name:
Decap CMS(or any name you prefer). - Application Domain:
https://your-domain.com/admin/*- This ensures that any access to the
/adminpath is protected.
- This ensures that any access to the
- Session Duration: Choose as per your preference (e.g., 1 hour).
- Application Name:
-
Set Up Access Policies:
- Policy Name:
Allow Only Team Members - Action:
Allow - Include:
- Email Domains: e.g.,
@yourcompany.comto restrict access to specific email domains. - Individuals or Groups: Specify individual emails or Cloudflare Access groups.
- Email Domains: e.g.,
- Exclude: (Optional) Define any exclusions if needed.
- Policy Name:
-
Save the Application
- Review the settings and click "Save".
-
-
Push Your Astro Project to GitHub
- Initialize a Git repository if you haven't already:
git init git add . git commit -m "Initial commit" git branch -M main git remote add origin https://github.com/your-username/your-repo.git # Replace with your repo URL git push -u origin main
- Initialize a Git repository if you haven't already:
-
Connect to Cloudflare Pages
-
Navigate to Cloudflare Dashboard:
- Go to Cloudflare Dashboard.
-
Access Pages:
- Click on "Pages" in the sidebar.
-
Create a New Project:
- Click "Create a project".
- Connect to Git Provider:
Select GitHub and authorize Cloudflare to access your repositories. - Select Repository:
Choose youryour-username/your-reporepository.
-
-
Configure Build Settings
-
Framework Preset:
Select Astro if available. If not, choose None. -
Build Command:
npm run build
-
Build Output Directory:
dist
- Astro outputs built files to the
distdirectory by default.
- Astro outputs built files to the
-
-
Set Environment Variables (If Needed)
- If your Astro project requires environment variables (e.g., API keys), set them in the Cloudflare Pages project settings under "Environment Variables".
-
Deploy the Project
- Click "Save and Deploy".
- Monitor the Build Process:
- Cloudflare Pages will automatically build and deploy your site. Monitor the deployment logs for any issues.
-
Configure Custom Domain (Optional but Recommended)
- Add a Custom Domain:
- After deployment, navigate to your Pages project settings.
- Click "Add Custom Domain" and follow the prompts to link
https://your-domain.comto your Cloudflare Pages site.
- Update DNS Records:
- Ensure that your domain's DNS settings in Cloudflare point to the correct Cloudflare Pages endpoints.
- Add a Custom Domain:
-
Verify Deployment
- Visit
https://your-domain.comto ensure your site is live. - Navigate to
https://your-domain.com/adminto access the Decap CMS interface (now secured by Cloudflare Zero Trust).
- Visit
-
Open
public/admin/config.yml-
Ensure the
backendsection includes the correctbase_urlandauth_endpoint:backend: name: github repo: "your-username/your-repo" # Your GitHub username/repo branch: main base_url: "https://decap.your-domain.com" # Your OAuth proxy domain auth_endpoint: "auth" # Path to the auth endpoint site_url: "https://your-domain.com" media_folder: "public/images/uploads" public_folder: "/images/uploads" collections: - name: "pages" label: "Pages" folder: "src/pages" create: true slug: "{{slug}}" fields: - { label: "Title", name: "title", widget: "string" } - { label: "Body", name: "body", widget: "markdown" }
-
-
Verify OAuth Proxy Scope
-
Since your repository is private, ensure that the OAuth flow requests the
reposcope. This is handled in youroauth.tsby setting thescopeparameter to'repo'. -
In
decap-proxy/src/index.ts:const authorizationUri = oauth2.authorizeURL({ redirect_uri: `https://${url.hostname}/callback?provider=github`, scope: "repo", // Ensure 'repo' scope for private repos state: randomBytes(4).toString("hex"), });
-
-
Redeploy the Worker After Changes
- If you made changes to the worker code, deploy the worker again:
npm run deploy
- If you made changes to the worker code, deploy the worker again:
-
Access the CMS Interface
- Navigate to
https://your-domain.com/adminin your browser. - Cloudflare Zero Trust:
- You should be prompted by Cloudflare Access to authenticate (e.g., via SSO, email, etc.).
- Only authorized users can proceed.
- Navigate to
-
Initiate GitHub Login
- Click on "Login with GitHub".
- OAuth Proxy Flow:
- A popup should appear directing you to
https://decap.your-domain.com/auth. - You’ll be redirected to GitHub’s OAuth authorization page.
- A popup should appear directing you to
-
Authorize the Application
- Log in to GitHub (if not already logged in).
- Authorize the OAuth application to access your repository with the required scopes.
-
Complete the Authentication
- After authorization, you should be redirected back to
https://decap.your-domain.com/callbackwhere the OAuth proxy exchanges the code for an access token and communicates it back to Decap CMS. - The popup should close automatically, and you should now have access to the CMS interface.
- After authorization, you should be redirected back to
-
Verify CMS Functionality
- Try creating or editing a page to ensure that Decap CMS can commit changes to your GitHub repository.
- Check your GitHub repo to confirm that the changes reflect correctly.
If you encounter any issues during setup, consider the following troubleshooting steps:
-
Possible Causes:
- Incorrect
repofield inpublic/admin/config.yml. - OAuth token lacks necessary permissions. Line 30 in
decap-proxy/src/index.tsis not set to'repo'for private repositories.
- Incorrect
-
Solutions:
-
Verify Repository Details:
- Ensure the
repofield follows the formatusername/repo-name. - Double-check spelling and case sensitivity.
- Ensure the
-
Check OAuth Scopes:
- Ensure the OAuth flow requests the
reposcope for private repositories. - Confirm that the OAuth token has the
repopermission.
- Ensure the OAuth flow requests the
-
User Permissions:
- Ensure the GitHub user authenticating has access to the private repository.
- If the repo is within an organization, ensure the OAuth app has access to the organization's repositories.
-
-
Cause:
The GitHub OAuth Client ID is not correctly set in the environment variables. -
Solution:
-
Verify Environment Variable Names:
- Ensure that in Cloudflare Workers settings, the variables are named exactly as referenced in the worker code (
GITHUB_OAUTH_IDandGITHUB_OAUTH_SECRET).
- Ensure that in Cloudflare Workers settings, the variables are named exactly as referenced in the worker code (
-
Redeploy the Worker:
- After setting or correcting environment variables, redeploy the worker to apply changes:
npm run deploy
- After setting or correcting environment variables, redeploy the worker to apply changes:
-
-
Symptoms:
- Popup does not close automatically.
- Unable to access CMS after login.
-
Solutions:
-
Check OAuth Callback Logic:
- Ensure the worker's callback script correctly sends the token back to Decap CMS and closes the popup.
-
Browser Console Errors:
- Open developer tools in your browser and check for any JavaScript errors or failed network requests during the authentication process.
-
Popup Blockers:
- Ensure that your browser is not blocking popups from your site.
-
-
Symptoms:
- Unable to access
/admineven after authentication.
- Unable to access
-
Solutions:
-
Review Access Policies:
- Ensure that your Zero Trust policies correctly include the users who should have access.
-
Check DNS Settings:
- Ensure that
decap.your-domain.comis correctly pointed in your DNS settings and that the worker is deployed properly.
- Ensure that
-
Test Without Zero Trust:
- Temporarily disable Zero Trust to determine if it’s the source of the issue. If access works without it, review your Zero Trust configuration.
-
This template is provided as-is, with no warranties. Please refer to the individual licenses of Astro, Decap CMS, and Cloudflare for their respective terms and conditions.
- Astro Documentation: https://docs.astro.build/
- Decap CMS Documentation: https://decapcms.org/docs/
- decap-proxy Documentation: https://github.com/sterlingwes/decap-proxy
- Cloudflare Workers Documentation: https://developers.cloudflare.com/workers/
- Cloudflare Zero Trust Documentation: https://developers.cloudflare.com/cloudflare-one/
- GitHub OAuth Documentation: https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps
Feel free to customize this template further to fit your project's specific needs. If you encounter any challenges or have questions about specific steps, don't hesitate to reach out for assistance!