Quick Deploy¶
Deploy Jenkins from scratch in under 30 minutes.
Prerequisites¶
- Docker Desktop installed and running
- Git and GitHub CLI (
gh) installed - A GitHub account (
<your-github-username>) - A domain managed by Cloudflare (or use a temporary tunnel for testing)
Step 1 — Clone this repo¶
# Clone the repository and move into the project directory
git clone https://github.com/<your-github-username>/jenkins-config.git
cd jenkins-config
Step 2 — Set up Cloudflare Tunnel¶
Jenkins needs a public URL for GitHub webhooks and OAuth callbacks. Do this before creating the Jenkins CI Apps so you have the URL ready.
Full instructions: docs/cloudflare.md
Output: a stable public URL (e.g. https://jenkins.yourdomain.com) and a tunnel token to paste into .env.
Step 3 — Create Jenkins CI Apps¶
You need two separate GitHub Apps:
| App | Purpose | What you get |
|---|---|---|
| Jenkins CI App | Jenkins reads repos, posts build status, manages webhooks | App ID + private key .pem + webhook secret |
| Jenkins Login App | Jenkins user login via GitHub account | Client ID + Client Secret |
Full instructions: docs/github-apps.md
Step 4 — Configure .env¶
Open .env and fill in the required values. Every variable is documented with a comment explaining its purpose, valid values, and when to change it. The minimum required set to start the platform:
# Core Jenkins credentials and public URL
JENKINS_ADMIN_PASSWORD=<strong-random-password>
JENKINS_URL=https://jenkins.yourdomain.com
# Cloudflare Tunnel token from Step 2
CLOUDFLARE_TUNNEL_TOKEN=<your-tunnel-token>
# GitHub identity
GITHUB_USERNAME=<your-github-username>
GITHUB_ADMIN_USERNAME=<your-github-username>
GITHUB_ORG=<your-github-org-or-username>
# Jenkins CI App from Step 3
GITHUB_APP_ID=<numeric-app-id>
GITHUB_WEBHOOK_SECRET=<random-secret-matching-app-settings>
# Jenkins Login App from Step 3
GITHUB_OAUTH_CLIENT_ID=<oauth-client-id>
GITHUB_OAUTH_CLIENT_SECRET=<oauth-client-secret>
A fully filled example with every variable configured is available in docs/configuration.md.
Step 5 — Add the Jenkins CI App private key¶
Copy the .pem file downloaded during Jenkins CI App creation into the repo root:
github-app.pem is gitignored and never committed.
Step 6 — Choose your services and start the stack¶
The platform uses Docker Compose profiles to control which services start. The core platform — Jenkins and the Cloudflare tunnel — always starts. Optional service groups are activated via COMPOSE_PROFILES in your .env.
| Profile | Services | When to use |
|---|---|---|
| (none — default) | Jenkins + Cloudflare tunnel | Minimal setup, CI only |
reporting |
+ Allure test reporting | When you want rich test result dashboards |
full |
Everything above + future services | Maximum platform features |
Set your preferred profile in .env before starting:
Then start the stack:
# Build the Jenkins image and start all configured services in the background
docker compose up --build -d
First build takes a few minutes — it installs all plugins. Subsequent starts are fast.
Verify all services are running:
Wait for Jenkins is fully up and running in the Jenkins log output.
If you started the reporting profile, Allure is available at:
Step 7 — Log in¶
Open http://localhost:8080 (or your public Cloudflare URL).
Log in with your GitHub account via the GitHub OAuth button. Your <your-github-username> account is pre-configured as admin via casc.yml.
Step 8 — Create the GitHub Organization Folder job¶
This is a one-time manual step. It will be automated in Phase 2 via a seed job — until then, follow these steps.
- New Item → name it
<your-github-username>→ select GitHub Organization - Credentials: select
jenkins-ci-app - Owner:
<your-github-username> - Behaviors: leave defaults (discovers branches and PRs)
- Fork PR trust (security-critical): In Behaviors → Discover fork pull requests → set Trust to match your
JENKINS_FORK_PR_TRUSTsetting in.env:
| Trust value | Who can trigger CI on fork PRs | When to use |
|---|---|---|
nobody |
No one — all require manual approval | Maximum security |
contributors |
Authors with a previously merged PR | Causes a chicken-and-egg problem for first PRs |
collaborators |
Users explicitly added as repo collaborators | Recommended — deliberate per-person trust grant |
organization |
All GitHub org members | For teams with trusted org membership |
everyone |
Anyone | Not recommended — pipelines have credential access |
- Save — Jenkins scans your account and creates a job for every repo containing a
Jenkinsfile
From this point, any new repo with a Jenkinsfile is picked up automatically. If the Cloudflare tunnel drops, Jenkins rescans the org every JENKINS_FOLDER_SCAN_INTERVAL minutes as a fallback. GitHub also retries failed webhook deliveries for up to 3 days — both mechanisms work together to ensure no build is permanently missed.
Step 9 — Verify¶
Push a commit to any repo that has a Jenkinsfile. You should see:
- A build appear in Jenkins within seconds (via webhook)
- Build status posted back to the GitHub commit or PR
Updating Jenkins¶
To apply config changes (plugins, casc.yml, Dockerfile):
Jenkins reloads JCasC config automatically on restart without losing build history (stored in the jenkins_home volume).
Teardown¶
Stop the stack without losing any data:
Warning — Allure history: Running
docker compose down -vpermanently destroys theallure_resultsandallure_reportsvolumes, which contain all Allure test trend history. Before running-v, configurepublishArtifacts()with an artifact backend (S3, Azure Blob, etc.) to preserve history externally. See docs/configuration.md for artifact storage options.
Full wipe including all build history and Allure data: