Skip to content

Quick Deploy

Jenkins running from scratch in under 30 minutes.

Prerequisites

  • Docker Desktop installed and running
  • Git and GitHub CLI (gh) installed
  • A GitHub account
  • A domain managed by Cloudflare (or use a temporary tunnel for testing)

Step 1 — Clone this repo

git clone https://github.com/<your-github-username>/magi.git
cd magi

Step 2 — Set up Cloudflare Tunnel

Jenkins needs a public URL for GitHub webhooks and OAuth callbacks. Do this before creating the GitHub Apps so you have the URL ready.

Full instructions: Cloudflare Tunnel

Output: a stable public URL (e.g. https://jenkins.yourdomain.com) and a tunnel token for .env.


Step 3 — Create GitHub Apps

Two separate GitHub Apps are required:

App Purpose What you get
Jenkins CI App Reads repos, posts build status, manages webhooks App ID + private key .pem + webhook secret
Jenkins Login App User login via GitHub account Client ID + Client Secret

Full instructions: GitHub Apps Setup


Step 4 — Configure .env

cp .env.example .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. Minimum required set:

# 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>

Full variable reference: Configuration


Step 5 — Add the Jenkins CI App private key

Copy the .pem file downloaded during GitHub App creation into the repo root:

cp $env:USERPROFILE\Downloads\your-app-name.pem github-app.pem
cp ~/Downloads/your-app-name.pem github-app.pem

Never commit this file

github-app.pem is gitignored. Keep it that way. Anyone with this key can authenticate as your Jenkins CI App against every repo it has access to.


Step 6 — Choose services and start the stack

Services are grouped by Docker Compose profile. Core (Jenkins + tunnel) always starts. Add optional service groups via COMPOSE_PROFILES in .env:

Profile Services When to use
(none — default) Jenkins + Cloudflare tunnel Minimal setup, CI only
reporting + Allure test reporting Rich test result history and trend graphs
full Everything All platform features
# Optional — set a profile before starting
echo "COMPOSE_PROFILES=reporting" >> .env

# Build the Jenkins image and start all configured services
docker compose up --build -d

First build

The first up --build takes a few minutes — Jenkins installs all plugins during image build. Subsequent starts are fast.

Stream logs to confirm a clean startup:

docker compose logs -f

Wait for Jenkins is fully up and running in the Jenkins container output.

If you enabled reporting, Allure is at:

http://localhost:5050/allure-docker-service/projects/default/reports/latest/index.html


Step 7 — Log in

Open http://localhost:8080 (or your public Cloudflare URL).

Log in with GitHub via the OAuth button. The account set as GITHUB_ADMIN_USERNAME is pre-configured as admin via casc.yml.


Step 8 — Create the GitHub Organization Folder job

One-time manual step. Will be automated in a future phase via seed job — until then:

  1. New Item → name it <your-github-username> → select GitHub Organization
  2. Credentials: select jenkins-ci-app
  3. Owner: <your-github-username>
  4. Behaviors: leave defaults (discovers branches and PRs)
  5. Fork PR trust — set Discover fork pull requests → Trust to match JENKINS_FORK_PR_TRUST in .env:
Value Who triggers CI on fork PRs Trade-off
nobody No one — all require manual approval Maximum security
contributors Authors with a previously merged PR Chicken-and-egg for first PRs
collaborators Explicitly added repo collaborators Recommended
organization All GitHub org members Good for trusted teams
everyone Anyone Do not use — pipelines have credential access
  1. Save — Jenkins scans your account and creates a job for every repo containing a Jenkinsfile

From here, any new repo with a Jenkinsfile is picked up automatically. If the tunnel drops, Jenkins rescans on the JENKINS_FOLDER_SCAN_INTERVAL schedule as a fallback. GitHub also retries failed webhook deliveries for up to 3 days.


Step 9 — Verify

Push a commit to any repo with a Jenkinsfile. Within seconds:

  • A build appears in Jenkins (via webhook)
  • Build status is posted back to the GitHub commit or PR

Updating Jenkins

To apply config changes (plugins, casc.yml, Dockerfile):

git pull
docker compose up --build -d

Jenkins reloads JCasC automatically on restart. Build history is preserved in the jenkins_home volume.


Teardown

Stop the stack without losing data:

docker compose down

Full wipe — irreversible

docker compose down -v permanently destroys the jenkins_home, allure_results, and allure_reports volumes. All build history and Allure trend data is gone.

Before running -v, configure publishArtifacts() with an external artifact backend (S3, Azure Blob, etc.) to preserve Allure history. See Configuration.

# Destroys everything — build history, test results, Allure trends
docker compose down -v