Jenkins instellen op Windows 11
We kunnen Jenkins eenvoudig installeren op Linux en macOS. Installeren op Windows vereist echter meerdere stappen. Deze stappen omvatten het installeren van de Java Development Kit, het instellen van het lokale beveiligingsbeleid, Jenkins installeren met een domeingebruiker en de Jenkins-server starten.
OpenJDK installeren
Laten we beginnen met het installeren van Java. Ga naar de website van Adoptium en download de nieuwste LTS-release voor Windows 11.
Waarom moeten we OpenJDK installeren? Jenkins is een op Java gebaseerde applicatie die een Java Runtime Environment (JRE) of Java Development Kit (JDK) nodig heeft om te draaien.

Beeldbron: Adoptium
Installeer OpenJDK met de standaardwaarden, behalve dat je het vinkje bij “Set or override JAVA_HOME variable” moet zetten.

Na de installatie kun je controleren of alles goed is geïnstalleerd door java -version in het terminalvenster te typen:

Een gebruikersaccount instellen voor “Log on as service”
Om Jenkins te installeren, moet je het “Local Security Policy”-beleid aanpassen om gebruikersaanmelding voor de installer toe te staan. Druk hiervoor op Win + R, typ “secpol.msc” en druk op Enter. Navigeer vervolgens naar “Local Policies” > “User Rights Assignments” > “Log on as a service”.

Er wordt een nieuw venster geopend. Typ daar je Windows-gebruikersnaam en klik op de knop “Check Names”. Klik daarna op “OK” en sluit het venster “Local Security Policy”.

Jenkins installeren
Ga naar de website jenkins.io en download het Windows Installer-pakket voor Jenkins.

Beeldbron: jenkins.io
Wanneer je het venster bereikt met "Run service as a local or domain user", voer je je Windows-gebruikersnaam en -wachtwoord in en klik je op de knop “Test Credentials”. Als dit is goedgekeurd, klik je op “Next”.

Laat de rest op standaardinstellingen staan en voltooi de installatie. Het kan enkele minuten duren om alles in te richten.

De Jenkins-server starten
De Jenkins-server starten is eenvoudig. Druk op de Windows-toets en zoek op "Services". Zoek in het venster Services naar Jenkins en klik bovenaan op de afspeelknop.

Standaard draait Jenkins op https://localhost:8080/. Plak die URL in een browser om naar het dashboard te gaan. Om het Jenkins-dashboard te openen, moet je het beheerderswachtwoord invoeren.

Om het standaard beheerderswachtwoord te verkrijgen, ga je naar de Jenkins-map en zoek je het bestand Jenkins.err.log op en open je het.

Scroll omlaag in het Jenkins-errorbestand om het gegenereerde wachtwoord te vinden. Kopieer dit en plak het in het invoerveld voor het beheerderswachtwoord.

Daarna heeft de server enkele minuten nodig om de benodigde tools en extensies te installeren.

Zodra de server is ingericht, vraagt hij ons een nieuwe gebruiker aan te maken. Voer alle benodigde informatie in en klik op de knop "Save and Continue".

We worden doorgestuurd naar het dashboard, waar we verschillende Jenkins-pipelines kunnen maken, bekijken en uitvoeren.

Een agent aanmaken in Jenkins
Agents, ook wel nodes genoemd, zijn machines die zijn ingesteld om jobs uit te voeren die door de Jenkins-masterserver worden verzonden. Deze agents bieden de omgeving en rekenkracht om pipelines te draaien. Een Windows 11-agent is standaard beschikbaar, maar we kunnen altijd onze eigen agent met aangepaste opties maken.
Agents instellen
Klik op het hoofd-dashboard op “Manage Jenkins” en vervolgens op de knop “Set up agent”, zoals hieronder weergegeven. Je kunt ook op de knop “Nodes” klikken om agents te maken en te beheren.

Geef de naam van de agent op en selecteer het type “Permanent Agent”.

Zorg dat je een map voor de agent opgeeft waar alle bestanden en logs worden opgeslagen. Voeg een label toe en laat de rest van de instellingen standaard. Bij het maken van de pipeline gebruiken we het agentlabel om de taken uit te voeren.

De agent lokaal draaien
Wanneer je op “Save” klikt, verschijnt er een prompt met de instructie om het juiste commando, afhankelijk van je besturingssysteem, te kopiëren en in de terminal te plakken.
curl.exe -sO http://localhost:8080/jnlpJars/agent.jar & java -jar agent.jar -url http://localhost:8080/ -secret 1a30c62de92630dbcc1e2f19aaf482057e6170ced6835355447bc4ba4eefb76a -name "DC Agent 1" -webSocket -workDir "/home/Jenkins"
Na het plakken en uitvoeren van het commando in de terminal zien we een succesmelding die aangeeft dat onze agent, in mijn geval DC Agent 1, op de achtergrond draait.

Om te controleren of de agent draait en klaar is om een job uit te voeren, ga je naar het Jenkins-dashboard, klik je op “Manage Jenkins” en vervolgens op de knop “Nodes” om de status van de agent te bekijken.

Een eenvoudige Jenkins-pipeline maken
Een Jenkins-pipeline is een reeks geautomatiseerde stappen die helpen bij het trainen, evalueren en uitrollen van modellen. Deze processen worden gedefinieerd met een eenvoudige script-taal, waardoor het beheren en automatiseren van projectworkflows makkelijker wordt.
In dit gedeelte maken we een voorbeeldpipeline in Jenkins en gebruiken we onze zojuist gemaakte agent als pipeline-executor.
Een Jenkins-pipeline instellen
Klik op het dashboard op de knop “New Item”, typ de naam van het item, selecteer de optie “Pipeline” en klik op “OK”.

Daarna verschijnt een prompt om de pipeline te configureren. Scroll naar beneden naar het gedeelte “Pipeline”, waar we het Jenkins-pipelinescript moeten schrijven.

In het Jenkins-pipelinescript beginnen we met het instellen van de omgeving en de agent. In ons geval stellen we de agent in door het label van de agent op te geven dat we eerder hebben gedefinieerd.
Daarna schrijven we een sectie stages waarin alle verschillende stappen van de pipeline (Build, Test, Deploy) worden toegevoegd. In ons voorbeeld printen we met het echo-commando en voeren we terminalcommando's uit met het bat-commando.
batwordt gebruikt voor Windows 11shis voor Linux
Dat is alles. Zo simpel is het. Hier is de scriptcode:
pipeline {
agent {
label 'MLAgent' // Ensure this label matches your Windows 11 agent
}
stages {
stage('Build') {
steps {
echo 'Building...'
// Add your Windows build commands here
bat 'echo Running build commands'
}
}
stage('Test') {
steps {
echo 'Testing...'
// Add your Windows test commands here
bat 'echo Running test commands'
}
}
stage('Deploy') {
steps {
echo 'Deploying...'
// Add your Windows deploy commands here
bat 'echo Running deploy commands'
}
}
}
}
Klik na het toevoegen van het script op de knoppen “Apply” en “Save”.
De Jenkins-pipeline uitvoeren
Klik op de knop “Build Now” om de pipeline te testen en uit te voeren. Klik op de knop “Status” om de status te bekijken.

Na het voltooien van de run kunnen we de logs bekijken door in het menu "Status" op de specifieke run te klikken.
Klik op de link "Last build (#2)" en vervolgens op de knop "Console Output". Dit brengt ons naar het console-uitvoervenster, waar we de logs en resultaten van de pipeline kunnen vinden.

We kunnen zelfs op de knop “Pipeline Console” klikken om elke stap in de pipeline in detail te bekijken. Dit omvat de output, de tijd die het kostte om te starten en te eindigen, pipeline-commando's en logs.

Na het afronden van de Jenkins-installatie was het aanmaken en draaien van pipelines eenvoudig en snel. Het kostte me minder dan een uur om het script te begrijpen en mijn eigen te maken. Ik ga Jenkins gebruiken in plaats van GitHub Actions omdat het me meer flexibiliteit biedt.
Een Jenkins-pipeline maken voor een MLOps-project
Na de eerste kennismaking met Jenkins is het tijd om serieus aan de slag te gaan met het MLOps-project.
We maken twee pipelines: De eerste pipeline is CI, die de data laadt en verwerkt, het model traint, het model evalueert en vervolgens de modelserver test. Daarna start deze de CD-pipeline, die de model-inference-server opstart.
Wil je het proces in detail begrijpen? Volg dan de cursus CI/CD for Machine Learning, waarin je leert hoe je machinelearningontwikkelprocessen stroomlijnt.
Projectbestanden
Zoals bij elk project moeten we de projectbestanden maken, inclusief de Python-bestanden voor dataladen, modeltraining, modelevaluatie en modelserving. We hebben ook een requirements .txt-bestand nodig om de benodigde Python-pakketten te installeren.
data_loading.py:
In dit script laden we een scikit-learn-dataset, de Wine-dataset, en zetten deze om naar een pandas DataFrame. Vervolgens splitsen we de dataset in trainings- en testsets. Tot slot slaan we de verwerkte data op als een pickle-bestand.
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
import pandas as pd
import joblib
def load_data():
# Load the wine dataset
wine = load_wine(as_frame=True)
data = pd.DataFrame(data=wine.data, columns=wine.feature_names)
data["target"] = wine.target
print(data.head())
return data
def split_data(data, target_column="target"):
X = data.drop(columns=[target_column])
y = data[target_column]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
return X_train, X_test, y_train, y_test
def save_preprocessed_data(X_train, X_test, y_train, y_test, file_path):
joblib.dump((X_train, X_test, y_train, y_test), file_path)
if __name__ == "__main__":
data = load_data()
X_train, X_test, y_train, y_test = split_data(data)
save_preprocessed_data(X_train, X_test, y_train, y_test, "preprocessed_data.pkl")
model_training.py:
In dit bestand laden we de verwerkte data, trainen we een random forest-classifier en slaan we het model op als een pickle-bestand.
from sklearn.ensemble import RandomForestClassifier
import joblib
def load_preprocessed_data(file_path):
return joblib.load(file_path)
def train_model(X_train, y_train):
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
return model
def save_model(model, file_path):
joblib.dump(model, file_path)
if __name__ == "__main__":
X_train, X_test, y_train, y_test = load_preprocessed_data("preprocessed_data.pkl")
model = train_model(X_train, y_train)
save_model(model, "model.pkl")
model_evaluation.py:
Om het model te evalueren, laden we zowel het model als de voorbewerkte dataset, genereren we een classificatierapport en printen we de nauwkeurigheidsscore.
import joblib
from sklearn.metrics import accuracy_score, classification_report
def load_model(file_path):
return joblib.load(file_path)
def load_preprocessed_data(file_path):
return joblib.load(file_path)
def evaluate_model(model, X_test, y_test):
predictions = model.predict(X_test)
accuracy = accuracy_score(y_test, predictions)
report = classification_report(y_test, predictions)
return accuracy, report
if __name__ == "__main__":
X_train, X_test, y_train, y_test = load_preprocessed_data("preprocessed_data.pkl")
model = load_model("model.pkl")
accuracy, report = evaluate_model(model, X_test, y_test)
print(f"Model Accuracy: {accuracy}")
print(f"Classification Report:\n{report}")
model_serving.py:
Voor modelserving gebruiken we FastAPI om een REST API te maken waar gebruikers features kunnen invoeren en voorspellingen kunnen genereren. Normaal zijn de labels generiek. Om het leuker te maken, veranderen we de wijncategorieën in Verdante, Rubresco en Floralis.
Wanneer we dit bestand draaien, starten we de FastAPI-server, die we kunnen benaderen via het curl-commando of met de requests-bibliotheek in Python.
from typing import List
import joblib
import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
# Define the labels corresponding to the target classes
LABELS = [
"Verdante", # A vibrant and fresh wine, inspired by its balanced acidity and crisp flavors.
"Rubresco", # A rich and robust wine, named for its deep, ruby color and bold taste profile.
"Floralis", # A fragrant and elegant wine, known for its floral notes and smooth finish.
]
class Features(BaseModel):
features: List[float]
def load_model(file_path):
return joblib.load(file_path)
model = load_model("model.pkl")
@app.post("/predict")
def predict(features: Features):
# Get the numerical prediction
prediction_index = model.predict([features.features])[0]
# Map the numerical prediction to the label
prediction_label = LABELS[prediction_index]
return {"prediction": prediction_label}
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=9000)
requirements.txt:
Dit bestand helpt ons alle pakketten te downloaden en te installeren die nodig zijn om de bovenstaande Python-bestanden te draaien.
scikit-learn
pandas
fastapi
uvicorn
Hoofd-MLOps (CI)-pipeline
We maken nu continuous integration-pipelines in Jenkins. Net zoals we een eenvoudige pipeline hebben gemaakt, maken we een “MLOps-pipe” en schrijven we het script dat alles dekt van dataverwerking tot modelevaluatie.

Het MLOps-pipelinescript bestaat uit:
- De
agentinitialiseren met hetlabel“MLAgent”. - De werkmap instellen waar al onze Python-bestanden staan.
- Stages maken voor elke stap in de machinelearningpipeline:
- Alle benodigde Python-pakketten installeren (
Initialize). - De geladen dataset verwerken (
Load and Preprocess Data). - Het model trainen op een verwerkte dataset (
Train Model). - Het model evalueren en het rapport genereren (
Evaluate Model). - De modelserver testen met het
curl-commando (Test Serve Model). - Na het slagen van de servertest wordt een andere pipeline getriggerd om de server te deployen. Dat behandelen we in de volgende sectie.
- In de post-node verwerken we data en slaan we die op als artifact door de pickle-bestandsextensie op te geven.
Let op: Het commando start /B start een nieuw terminalvenster op de achtergrond en draait het model-serving-script. Dit Jenkins-pipelinescript werkt bovendien alleen op Windows; voor Linux of andere besturingssystemen moeten we de commando's aanpassen.
pipeline {
agent {
node {
label 'MLAgent'
customWorkspace 'C:\\Repository\\GitHub\\MLOps-Jenkins'
}
}
stages {
stage('Initialize') {
steps {
script {
// Install necessary Python packages
bat "pip install -r requirements.txt"
}
}
}
stage('Load and Preprocess Data') {
steps {
script {
// Run data loading script
bat "python data_loading.py"
}
}
}
stage('Train Model') {
steps {
script {
// Run model training script
bat "python model_training.py"
}
}
}
stage('Evaluate Model') {
steps {
script {
// Run model evaluation script
bat "python model_evaluation.py"
}
}
}
stage('Serve Model') {
steps {
script {
// Start FastAPI server in the background
bat 'start /B python model_serving.py'
// Wait for the server to start
sleep time: 10, unit: 'SECONDS'
}
}
}
stage('Test Serve Model') {
steps {
script {
// Test the server with sample values
bat '''
curl -X POST "http://127.0.0.1:9000/predict" ^
-H "Content-Type: application/json" ^
-d "{\\"features\\": [13.2, 2.77, 2.51, 18.5, 103.0, 1.15, 2.61, 0.26, 1.46, 3.0, 1.05, 3.33, 820.0]}"
'''
}
}
}
stage('Deploy Model') {
steps {
script {
// Trigger another Jenkins job for model serving
build job: 'ModelServingPipeline', wait: false
}
}
}
}
post {
always {
archiveArtifacts artifacts: '**.pkl', fingerprint: true
echo 'Pipeline execution complete.'
}
}
}
Modelserving (CD)-pipeline
Nu maken we een continuous deployment-pipeline om de server lokaal te deployen en te draaien.
Het pipelinescript is eenvoudig. We beginnen met het definiëren van de agent en veranderen de werkmap naar ons project. Daarna draaien we de server onbeperkt.
Let op: Een server onbeperkt in Jenkins laten draaien wordt niet aanbevolen, omdat pipelines een gedefinieerde start en einde moeten hebben. Voor dit voorbeeld gaan we ervan uit dat we de app hebben gedeployed, maar in de praktijk kun je beter Docker integreren en de app op een Docker-server draaien.
Als je wilt leren denken als een machine learning engineer, overweeg dan de cursus Developing Machine Learning Models for Production with an MLOps Mindset, waarmee je je modellen optimaal leert trainen, documenteren, onderhouden en opschalen.
pipeline {
agent {
node {
label 'MLAgent'
customWorkspace 'C:/Repository/GitHub/MLOps-Jenkins/'
}
}
stages {
stage('Start FastAPI Server') {
steps {
script {
// Start the FastAPI server
bat 'python model_serving.py'
}
}
}
}
}
De CI/CD-pipelines draaien
Ga naar de pipeline “MLOps-pipe” en klik op de knop “Build Now” om de CI/CD-pipeline te starten.
Zodra de pipeline succesvol is uitgevoerd, worden twee artifacts gegenereerd: één voor het model en één voor de verwerkte dataset.

Klik op de knop “Stages” op het Jenkins-dashboard om de pipeline te visualiseren en alle stappen te bekijken.

Bekijk de gedetailleerde logs van elke stap via het menu "Pipeline Console".

We kunnen ook de “ModelServingPipeline” controleren om te verifiëren dat onze server draait op de lokale URL http://127.0.0.1:9000.

De FastAPI-applicatie in de browser proberen
FastAPI wordt geleverd met Swagger UI, dat toegankelijk is door /docs toe te voegen aan de lokale URL: http://127.0.0.1:9000/docs.
Met Swagger UI kunnen we de FastAPI-app in de browser testen. Het is eenvoudig, en we zien dat onze modelserver prima werkt. De voorspelde voorbeeldwaarden geven aan dat het wijntype Rubresco is.

Zorg er altijd voor dat je de modelserver uitschakelt nadat je klaar bent met experimenteren. Dat kan via het menu “Status” in het Jenkins-dashboard en dan op het kruisje klikken, zoals hieronder:

Alle code, datasets, modellen en metafiles in deze tutorial zijn beschikbaar in de GitHub-repository om te proberen: kingabzpro/MLOps-with-Jenkins.
Conclusie
Jenkins is een geweldige automation server voor allerlei MLOps-taken. Het is een uitstekend alternatief voor GitHub Actions dankzij meer features, meer controle en betere privacy.
Een van de aantrekkelijkste aspecten van Jenkins is hoe simpel het is om pipelines te maken en uit te voeren, waardoor het toegankelijk is voor zowel beginners als gevorderden.
Ben je benieuwd naar vergelijkbare mogelijkheden met GitHub Actions? Mis dan de tutorial A Beginner's Guide to CI/CD for Machine Learning niet. Wil je je begrip van MLOps verdiepen, dan is de cursus Fully Automated MLOps een fantastische bron. Die biedt uitgebreide inzichten in MLOps-architectuur, CI/CD/CM/CT-technieken en automatiseringspatronen om ML-systemen te deployen die consistent waarde leveren in de tijd.
Als gecertificeerd data scientist haal ik met passie het maximale uit de nieuwste technologie om innovatieve machinelearning-toepassingen te bouwen. Met een sterke achtergrond in spraakherkenning, data-analyse en -rapportage, MLOps, conversationele AI en NLP heb ik mijn vaardigheden aangescherpt in het ontwikkelen van intelligente systemen die echt impact maken. Naast mijn technische expertise ben ik ook een sterke communicator met een talent om complexe concepten terug te brengen tot heldere, beknopte taal. Daardoor ben ik uitgegroeid tot een veelgelezen blogger over data science, waar ik mijn inzichten en ervaringen deel met een groeiende community van data-professionals. Op dit moment richt ik me op contentcreatie en redactie, waarbij ik met large language models werk aan krachtige en aansprekende content die zowel bedrijven als individuen helpt het beste uit hun data te halen.


In deze tutorial leren we hoe je Jenkins installeert en gebruikt, en hoe je agents en pipelines aanmaakt en uitvoert.
Specifiek gaan we:
Moet je je kennis opfrissen? Volg dan de korte en duidelijke cursus MLOps Concepts om te leren hoe je machinelearningmodellen van Jupyter-notebooks naar werkende productiemodellen brengt die echte businesswaarde leveren.
Wat is Jenkins?
Jenkins is een open-source automation server die een belangrijke rol speelt in het machinelearningontwikkelproces door continuous integration (CI) en continuous deployment (CD) te faciliteren.
Jenkins is geschreven in Java en helpt bij het automatiseren van dataverwerking, training, evaluatie en uitrol van machinelearningprojecten. Daarmee is het een essentieel hulpmiddel voor MLOps-praktijken.
Kenmerken van Jenkins:
Taakautomatisering met Jenkins is slechts één onderdeel van het MLOps-ecosysteem. Over andere taken leer je meer in de blog 25 Top MLOps Tools You Need to Know in 2024. Die bevat tools voor het tracken van experimenten, modelmetadata, workfloworkestratie, versiebeheer van data en pipelines, modeldeployment en -serving en modelmonitoring in productie.