Skip to content

Cloudflare Tunnel

Jenkins needs a stable public HTTPS URL for two things: - GitHub webhooks — so GitHub can notify Jenkins of pushes and PRs - GitHub OAuth callback — so GitHub can redirect users back after login

Cloudflare Tunnel creates a secure outbound-only connection from your machine to Cloudflare's edge — no open firewall ports required.


Prerequisites

  • A domain managed by Cloudflare (free plan works)
  • cloudflared installed
winget install Cloudflare.cloudflared
brew install cloudflare/cloudflare/cloudflared
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb

Step 1 — Authenticate

cloudflared tunnel login

This opens a browser to authorize cloudflared against your Cloudflare account. Select the domain you want to use.


Step 2 — Create a named tunnel

cloudflared tunnel create jenkins

Note the tunnel ID in the output (UUID format). You'll need it in the next step.


Step 3 — Create the config file

Create the config file at the platform-specific location:

%USERPROFILE%\.cloudflared\config.yml

~/.cloudflared/config.yml

tunnel: <your-tunnel-id>
credentials-file: <credentials-path>

ingress:
  - hostname: jenkins.yourdomain.com
    service: http://localhost:8080
  - service: http_status:404

Set credentials-file to the path of your tunnel credentials JSON:

C:\Users\<your-username>\.cloudflared\<tunnel-id>.json
~/.cloudflared/<tunnel-id>.json

Replace jenkins.yourdomain.com with your actual subdomain.


Step 4 — Create the DNS record

cloudflared tunnel route dns jenkins jenkins.yourdomain.com

This creates a CNAME in Cloudflare DNS pointing your subdomain at the tunnel. Takes effect immediately.


Step 5 — Run as a service

For Jenkins to always be reachable without manually starting the tunnel:

cloudflared service install
net start cloudflared
sudo cloudflared service install
sudo launchctl start com.cloudflare.cloudflared
sudo cloudflared service install
sudo systemctl enable --now cloudflared

Verify the tunnel is active in the Cloudflare dashboard under Zero Trust → Access → Tunnels.


Step 6 — Update .env

Set JENKINS_URL in your .env to the full public URL:

JENKINS_URL=https://jenkins.yourdomain.com

This value is used by: - casc.yml to tell Jenkins its own address (for webhook URL construction) - The Jenkins CI App webhook URL: https://jenkins.yourdomain.com/github-webhook/ - The Jenkins Login App callback URL: https://jenkins.yourdomain.com/securityRealm/finishLogin


Temporary tunnel (testing only)

If you don't have a domain yet, use a temporary tunnel:

cloudflared tunnel --url http://localhost:8080

This gives a random *.trycloudflare.com URL that lasts for the session. You'll need to update the Jenkins CI App webhook URL, OAuth callback URL, and JENKINS_URL in .env every time you restart it. Not suitable for permanent use.


Troubleshooting

Tunnel shows as inactive in dashboard: Check the service is running:

sc query cloudflared
sudo launchctl list | grep cloudflared
sudo systemctl status cloudflared

502/503 from the tunnel URL: Jenkins may not be running yet. Check: docker compose ps

OAuth callback mismatch error: The URL in your Jenkins Login App settings must exactly match JENKINS_URL/securityRealm/finishLogin including the protocol.


Cloudflare Pages (docs hosting)

This documentation is hosted on Cloudflare Pages, deployed automatically on every push to main. Setup is a one-time manual step in the Cloudflare dashboard.

Step 1 — Create a Pages project

  1. Go to Cloudflare dashboard → Workers & Pages → Create
  2. Select Pages → Connect to Git
  3. Authorise Cloudflare to access GitHub and select the jenkins-config repo

Step 2 — Configure the build

Setting Value
Production branch main
Build command pip install -r requirements-docs.txt && mkdocs build
Build output directory site
Root directory /

Leave all other settings as defaults and click Save and Deploy.

Step 3 — Set the custom domain (optional)

In the Pages project settings → Custom domains → add a subdomain, e.g. jenkins-docs.yourdomain.com. Cloudflare creates the DNS record automatically.

How deployments work

  • Every push to main triggers a new build and deployment automatically
  • Every pull request gets a unique preview URL — useful for reviewing doc changes before merging
  • No Jenkins involvement — Cloudflare builds directly from GitHub

Updating the docs URL in this repo

Once the Pages project is live, update the site_url in mkdocs.yml:

site_url: https://jenkins-docs.yourdomain.com