Jenkins Nedir: Kurulum ve İlk Yapılandırma
Yazılım geliştirme dünyasında “benim makinemde çalışıyor” klasiği hepimizin başına gelmiştir. Bir geliştirici kodu commit eder, başka bir ortamda her şey dağılır. İşte tam bu noktada CI/CD araçları devreye girer ve Jenkins bu alanın en köklü, en yaygın kullanılan temsilcilerinden biridir. Bugün Jenkins’i sıfırdan kurup yapılandıracağız; teoride boğulmadan, doğrudan çalışan bir sisteme kavuşacağız.
Jenkins Nedir?
Jenkins, Java ile yazılmış açık kaynaklı bir otomasyon sunucusudur. Temel görevi yazılım geliştirme süreçlerini otomatize etmektir: kod derleme, test çalıştırma, paketleme ve dağıtım adımlarını insan müdahalesi olmadan arka arkaya koşturmak.
2004 yılında Sun Microsystems bünyesinde “Hudson” adıyla başlayan proje, Oracle’ın Sun’ı satın almasının ardından topluluk fork’u olarak Jenkins adını aldı. O günden bu yana 1800’den fazla eklenti ve devasa bir toplulukla büyüdü.
Jenkins’in çözdüğü temel problem şudur: Bir ekipte 5 geliştirici çalışıyor olsun. Her biri farklı bir branch’e kod yazıyor. Bu kodların birleştirilmesi, test edilmesi ve production’a çıkarılması elle yapıldığında kabus olur. Jenkins bu süreci şöyle tanımlar:
- Sürekli Entegrasyon (CI): Her commit sonrası otomatik build ve test
- Sürekli Teslimat (CD): Başarılı build’lerin otomatik olarak staging veya production’a gönderilmesi
- Pipeline: Bu adımların kod olarak tanımlanması (Pipeline as Code)
Gerçek dünya senaryosu olarak düşünelim: Bir e-ticaret şirketinde çalışıyorsunuz. Geliştirme ekibi günde 10-15 kez kodu main branch’e merge ediyor. Jenkins her merge sonrası unit testleri koşuyor, Docker image oluşturuyor, staging ortamına deploy ediyor ve test ekibine bildirim gönderiyor. Siz uyurken bile sistem çalışıyor.
Sistem Gereksinimleri
Jenkins’i kurmadan önce donanım ve yazılım gereksinimlerini netleştirelim. Küçük bir ekip için minimum gereksinimler oldukça mütevazıdır.
Donanım tarafında:
- RAM: Minimum 256 MB, önerilen 1 GB (eklentiler ve build sayısına göre 4-8 GB’a kadar çıkabilir)
- Disk: Minimum 1 GB, önerilen 10 GB+
- CPU: Minimum 1 çekirdek, yoğun kullanım için 2-4 çekirdek
Yazılım gereksinimleri:
- Java: Jenkins LTS için Java 11 veya Java 17 (Java 8 desteği 2.346+ sürümüyle kalktı)
- İşletim Sistemi: Linux (Debian/Ubuntu/RHEL/CentOS), Windows, macOS veya Docker
Bu yazıda Ubuntu 22.04 LTS üzerinde kurulum yapacağız. Ancak RHEL/CentOS için de gerekli adımları paylaşacağım.
Java Kurulumu
Jenkins’in çalışması için önce Java gerekiyor. Ubuntu üzerinde OpenJDK 17 kurulumunu yapalım.
sudo apt update && sudo apt upgrade -y
sudo apt install -y openjdk-17-jdk
# Kurulumu doğrula
java -version
# Beklenen çıktı: openjdk version "17.x.x"
# JAVA_HOME ortam değişkenini ayarla
echo 'JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64"' | sudo tee -a /etc/environment
source /etc/environment
echo $JAVA_HOME
RHEL/CentOS 8+ kullanıcıları için:
sudo dnf install -y java-17-openjdk-devel
java -version
Jenkins Kurulumu (Ubuntu/Debian)
Jenkins’i resmi repository üzerinden kurmak en temiz yöntemdir. Bu sayede apt upgrade ile Jenkins’i kolayca güncelleyebilirsiniz.
# Jenkins GPG anahtarını ekle
sudo wget -O /usr/share/keyrings/jenkins-keyring.asc
https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
# Jenkins repository'sini sources.list'e ekle
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]"
https://pkg.jenkins.io/debian-stable binary/ |
sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null
# Paket listesini güncelle ve Jenkins'i kur
sudo apt update
sudo apt install -y jenkins
# Jenkins servisini başlat ve sistem açılışında otomatik başlamasını sağla
sudo systemctl enable jenkins
sudo systemctl start jenkins
# Servis durumunu kontrol et
sudo systemctl status jenkins
Çıktıda active (running) görüyorsanız Jenkins başarıyla çalışıyor demektir.
Firewall Ayarları
Eğer ufw aktifse 8080 portunu açmanız gerekiyor:
sudo ufw allow 8080
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status
İlk Kurulum Sihirbazı
Jenkins varsayılan olarak 8080 portunda çalışır. Tarayıcıdan http://sunucu-ip:8080 adresine gidin.
Karşınıza “Unlock Jenkins” ekranı çıkacak. Başlangıç şifresini almak için:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
Bu komut size 32 karakterlik bir hash verecek. Bunu kopyalayıp web arayüzüne yapıştırın.
Bundan sonra iki seçenek sunulur:
- Install suggested plugins: Topluluk tarafından en çok kullanılan eklentileri otomatik kurar. Yeni başlayanlar için önerilir.
- Select plugins to install: Tam kontrol isterseniz. Ama ne istediğinizi bilmiyorsanız ilk seçenekle devam edin.
“Install suggested plugins” seçeneğiyle devam edin. Kurulum biraz zaman alacak, eklentiler indirilip kurulacak.
Kurulum tamamlandıktan sonra admin kullanıcısı oluşturma ekranı gelir. Güçlü bir parola seçin ve sakın unutmayın. Test ortamı bile olsa basit parola koymak alışkanlık yaratır, production’da başınızı yakabilir.
Son adımda Jenkins URL’ini konfirme edin. Arkasında reverse proxy varsa burayı doğru ayarlamak önemlidir.
Jenkins Servis Yapılandırması
Jenkins’in çalışma parametrelerini değiştirmek için servis konfigürasyon dosyasını düzenliyoruz:
# Jenkins servis konfigürasyonunu görüntüle
sudo systemctl cat jenkins
# Override dosyası oluştur (doğrudan servis dosyasını düzenleme)
sudo systemctl edit jenkins
Açılan editörde aşağıdaki gibi değişiklik yapabilirsiniz. Örneğin portu 8080’den 9090’a almak veya Java heap size ayarlamak için:
# /etc/default/jenkins dosyasını düzenle
sudo nano /etc/default/jenkins
# Şu satırları ekle veya düzenle:
JENKINS_PORT=8080
JAVA_ARGS="-Djava.awt.headless=true -Xmx2048m -Xms512m"
Değişikliklerden sonra servisi yeniden başlatın:
sudo systemctl daemon-reload
sudo systemctl restart jenkins
sudo systemctl status jenkins
Nginx ile Reverse Proxy Kurulumu
Production ortamında Jenkins’i doğrudan 8080’de açık bırakmak iyi bir pratik değil. Nginx arkasına alıp 443 (HTTPS) üzerinden servis etmek çok daha güvenli.
sudo apt install -y nginx
# Jenkins için Nginx yapılandırması oluştur
sudo nano /etc/nginx/sites-available/jenkins
Aşağıdaki yapılandırmayı dosyaya yapıştırın:
upstream jenkins {
keepalive 32;
server 127.0.0.1:8080 fail_timeout=0;
}
server {
listen 80;
server_name jenkins.ornekdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name jenkins.ornekdomain.com;
ssl_certificate /etc/ssl/certs/jenkins.crt;
ssl_certificate_key /etc/ssl/private/jenkins.key;
# Güvenlik başlıkları
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
location / {
proxy_pass http://jenkins;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_max_temp_file_size 0;
# Büyük dosya yükleme için
client_max_body_size 100m;
}
}
# Konfigürasyonu aktif et
sudo ln -s /etc/nginx/sites-available/jenkins /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Jenkins tarafında da reverse proxy’ye uyum sağlaması için /var/lib/jenkins/jenkins.model.JenkinsLocationConfiguration.xml dosyasındaki URL’i güncelleyin veya Jenkins arayüzünden Manage Jenkins > System > Jenkins URL kısmından düzeltin.
İlk Job Oluşturma: Freestyle Project
Teoriden pratiğe geçelim. Basit bir “Hello World” job’u oluşturalım.
Jenkins ana sayfasından “New Item” seçeneğine tıklayın. Job adı olarak ilk-test-job yazın ve “Freestyle project” seçeneğini işaretleyip OK’e basın.
Karşınıza gelecek ekranda:
Build Steps bölümüne gelin, “Add build step” > “Execute shell” seçin ve şunu yazın:
#!/bin/bash
echo "Merhaba Jenkins!"
echo "Build Numarasi: ${BUILD_NUMBER}"
echo "Job Adi: ${JOB_NAME}"
echo "Calisma Dizini: ${WORKSPACE}"
date
whoami
“Save” butonuna basın ve “Build Now” ile job’u tetikleyin. Sol taraftaki Build History bölümünden build’e tıklayıp Console Output‘u görüntülediğinizde yukarıdaki çıktıları göreceksiniz.
Pipeline Job ile Gerçekçi Senaryo
Freestyle project’ler başlangıç için iyidir ama modern Jenkins kullanımı Pipeline üzerine kurulu. Pipeline’lar Jenkinsfile adlı dosyayla kod olarak tanımlanır ve Git repository’sinde saklanır.
Gerçek bir senaryo: Bir Python uygulamanız var, her commit sonrası lint kontrolü, unit test ve Docker build yapmak istiyorsunuz.
Jenkins arayüzünden “New Item” > “Pipeline” seçin. Pipeline bölümüne gelin ve “Pipeline script” seçeneğiyle şu Jenkinsfile’ı yapıştırın:
pipeline {
agent any
environment {
DOCKER_IMAGE = "ornekuygulama"
DOCKER_TAG = "${BUILD_NUMBER}"
PYTHON_VERSION = "3.11"
}
stages {
stage('Checkout') {
steps {
echo "Kod repository'den cekiliyor..."
// git url: 'https://github.com/ornek/uygulama.git', branch: 'main'
echo "Checkout tamamlandi: ${env.GIT_COMMIT}"
}
}
stage('Lint Kontrolu') {
steps {
echo "Python lint kontrolu basliyor..."
sh '''
python3 -m pip install flake8 --quiet
flake8 --max-line-length=120 . || true
echo "Lint kontrolu tamamlandi"
'''
}
}
stage('Unit Testler') {
steps {
echo "Unit testler calistiriliyor..."
sh '''
python3 -m pip install pytest --quiet
python3 -m pytest tests/ -v --tb=short || true
echo "Test sureci tamamlandi"
'''
}
}
stage('Docker Build') {
when {
branch 'main'
}
steps {
echo "Docker image olusturuluyor: ${DOCKER_IMAGE}:${DOCKER_TAG}"
sh '''
echo "Docker build simulasyonu"
# docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .
'''
}
}
stage('Deploy Staging') {
when {
branch 'main'
}
steps {
echo "Staging ortamina deploy basliyor..."
sh 'echo "Deploy tamamlandi"'
}
}
}
post {
success {
echo "Pipeline basariyla tamamlandi! Build: ${BUILD_NUMBER}"
}
failure {
echo "Pipeline basarisiz oldu! Loglari kontrol edin."
// mail to: '[email protected]', subject: "Build ${BUILD_NUMBER} basarisiz"
}
always {
echo "Pipeline sureci sona erdi. Durum: ${currentBuild.currentResult}"
}
}
}
Bu Jenkinsfile size birkaç kritik konsepti gösteriyor:
- stages/stage: Pipeline’ı mantıksal adımlara böler
- environment: Global ortam değişkenleri tanımlar
- when: Koşullu adım çalıştırma (sadece main branch’te Docker build yap)
- post: Build sonucu ne olursa olsun, başarılı ya da başarısız çalışacak aksiyonlar
Önemli Eklentiler ve Konfigürasyonları
Jenkins’in gücü eklentilerinden gelir. Manage Jenkins > Plugins üzerinden yönetilir. Kurulu olmasını önerdiğim eklentiler:
- Git Plugin: Git repository entegrasyonu için zorunlu
- Pipeline: Jenkinsfile desteği
- Blue Ocean: Modern ve görsel pipeline arayüzü
- Credentials: Şifre ve API anahtarı yönetimi
- Docker Pipeline: Docker komutlarını pipeline içinde kullanmak için
- Slack Notification: Build sonuçlarını Slack’e göndermek için
- Role-based Authorization Strategy: Kullanıcı yetki yönetimi
Eklenti kurulumu için:
# Jenkins CLI ile eklenti kurulumu da yapılabilir
# Önce CLI jar'ı indir
wget http://localhost:8080/jnlpJars/jenkins-cli.jar
# Eklenti kur
java -jar jenkins-cli.jar -s http://localhost:8080/
-auth admin:ADMIN_SIFRE
install-plugin git pipeline-stage-view blueocean
# Jenkins'i yeniden başlat
java -jar jenkins-cli.jar -s http://localhost:8080/
-auth admin:ADMIN_SIFRE
safe-restart
Güvenlik Yapılandırması
Yeni kurulan Jenkins’te mutlaka yapmanız gereken güvenlik ayarları var.
Manage Jenkins > Security altında:
- Security Realm: “Jenkins’ own user database” ile başlayın, ileride LDAP/Active Directory entegrasyonu ekleyebilirsiniz
- Authorization: Küçük ekipler için “Matrix-based security”, büyük organizasyonlar için “Role-Based Strategy” eklentisi
- CSRF Protection: Mutlaka aktif bırakın
Bir de Jenkins’in çalıştığı jenkins kullanıcısının yetkilerini sınırlandırmak iyi bir pratiktir:
# Jenkins kullanıcısının sudo yetkilerini kontrol et
sudo -l -U jenkins
# Jenkins kullanıcısını incele
id jenkins
cat /etc/passwd | grep jenkins
# Jenkins home dizini
ls -la /var/lib/jenkins/
# Jenkins log dosyaları
sudo journalctl -u jenkins -n 50 --no-pager
sudo tail -f /var/log/jenkins/jenkins.log
Yedekleme Stratejisi
Jenkins konfigürasyonunu yedeklemek kritik önem taşır. Tüm kritik veriler /var/lib/jenkins/ altında bulunur.
#!/bin/bash
# jenkins_backup.sh
BACKUP_DIR="/opt/jenkins-backups"
JENKINS_HOME="/var/lib/jenkins"
TARIH=$(date +%Y%m%d_%H%M%S)
YEDEK_ADI="jenkins_backup_${TARIH}.tar.gz"
# Yedek dizini oluştur
mkdir -p ${BACKUP_DIR}
# Jenkins'i yedekle (jobs, plugins, config dosyaları)
sudo tar -czf ${BACKUP_DIR}/${YEDEK_ADI}
--exclude="${JENKINS_HOME}/workspace"
--exclude="${JENKINS_HOME}/cache"
--exclude="${JENKINS_HOME}/logs"
${JENKINS_HOME}
echo "Yedek olusturuldu: ${BACKUP_DIR}/${YEDEK_ADI}"
echo "Boyut: $(du -sh ${BACKUP_DIR}/${YEDEK_ADI} | cut -f1)"
# 30 gunden eski yedekleri sil
find ${BACKUP_DIR} -name "jenkins_backup_*.tar.gz" -mtime +30 -delete
echo "Eski yedekler temizlendi"
Bu scripti crontab’a ekleyin:
# Her gece 02:00'de yedek al
sudo crontab -e
# Şu satırı ekle:
0 2 * * * /opt/scripts/jenkins_backup.sh >> /var/log/jenkins_backup.log 2>&1
Sık Karşılaşılan Sorunlar ve Çözümleri
Sorun 1: Jenkins başlamıyor, “insufficient memory” hatası
Java heap space yetersiz. /etc/default/jenkins dosyasında:
JAVA_ARGS="-Djava.awt.headless=true -Xmx2048m -Xms512m -XX:+UseG1GC"
Sorun 2: Build workspace’i doldu
Eski build artifact’leri disk dolduruyor olabilir. Job konfigürasyonunda “Discard old builds” seçeneğini aktif edip maksimum sayı belirleyin. Veya elle temizlemek için:
# Workspace'leri temizle
sudo find /var/lib/jenkins/workspace -maxdepth 1 -type d -mtime +7 -exec rm -rf {} ;
# Eski build loglarını temizle
sudo find /var/lib/jenkins/jobs -name "*.log" -mtime +30 -delete
Sorun 3: Plugin güncellemesi sonrası Jenkins açılmıyor
# Sorunlu eklentiyi devre dışı bırak
sudo mv /var/lib/jenkins/plugins/sorunlu-plugin.jpi
/var/lib/jenkins/plugins/sorunlu-plugin.jpi.bak
sudo systemctl restart jenkins
Sorun 4: “Permission denied” hataları build sırasında
Jenkins kullanıcısının ilgili dosya/dizine erişim izni olmayabilir:
# Docker socket erişimi için Jenkins kullanıcısını docker grubuna ekle
sudo usermod -aG docker jenkins
sudo systemctl restart jenkins
# Belirli bir dizin için izin ver
sudo chown -R jenkins:jenkins /opt/uygulama-dizini
Sonuç
Jenkins’i sıfırdan kurup çalışır hale getirdik. Java kurulumundan başlayıp resmi repository üzerinden Jenkins kurulumuna, Nginx reverse proxy konfigürasyonuna, ilk Freestyle ve Pipeline job’larına kadar oldukça geniş bir yelpazeyi kapsadık.
Burada öğrendikleriniz size sağlam bir temel verdi ama Jenkins’in derinliği çok daha büyük. Bir sonraki adımlarda bakmanızı önerdiğim konular şunlar:
- Jenkins Agent/Node yapısı: Build yükünü dağıtık makinelere yaymak için master-agent mimarisi
- Shared Libraries: Pipeline kodunu tekrar kullanılabilir kütüphanelere dönüştürmek
- Multibranch Pipeline: Git’teki her branch için otomatik pipeline oluşturma
- Jenkins X: Kubernetes native CI/CD için Jenkins’in modern kardeşi
- GitOps entegrasyonu: ArgoCD veya Flux ile birlikte kullanım
Jenkins bir araçtır ve her araç gibi amaca uygun kullanıldığında değer yaratır. Küçük bir ekip için bazen GitHub Actions veya GitLab CI daha pratik olabilir. Ancak büyük, kompleks iş akışları ve kurumsal entegrasyonlar söz konusu olduğunda Jenkins’in esnekliği ve eklenti ekosistemi hala rakipsiz. Hangi ortamda olursanız olun, CI/CD kültürünü benimsemek yazılım kalitesine ve ekip verimliliğine yapabileceğiniz en iyi yatırımlardan biridir.
