GitHub Actions ve Jenkins ile Apinizer CI/CD Entegrasyonu
Genel Bakış
Bu kılavuz, modern bir CI/CD pipeline'ı kullanarak API'lerinizi otomatik olarak Apinizer'a nasıl deploy edeceğinizi gösterir. Örnek senaryo, GitHub Actions ile Docker image oluşturma, Jenkins ile Kubernetes deployment ve Apinizer üzerinde API proxy yönetimini kapsar.
Kullanılan Teknolojiler ve Versiyonlar
| Teknoloji | Versiyon |
|---|---|
| Jenkins | jenkins/jenkins:lts |
| Apinizer | v2026.01.5 |
| GitHub Actions | — |
| Kubernetes | Ortamınıza bağlı |
Pipeline Akışı
GitHub Push → GitHub Actions (Build & Tag) → Jenkins Trigger →
Kubernetes Deploy → Health Check → Apinizer API Proxy Sync → Apinizer Deploy
Mimari Genel Bakış
Bu entegrasyon senaryosu şu bileşenleri kullanır:
- GitHub Actions: Docker image build ve versiyonlama işlemleri GitHub tarafında yürütülür.
- Jenkins: Orchestration ve deployment yönetimi Jenkins sunucunuzda gerçekleşir.
- Kubernetes: Container orchestration cluster'ınızda çalışır.
- Apinizer: API Gateway ve API proxy yönetimi Apinizer instance'ınız üzerinden yapılır.
1. GitHub Actions Workflow
GitHub Actions, her main branch'e push işleminde otomatik olarak:
- Yeni bir semantic version oluşturur
- Docker image build eder ve Docker Hub'a push eder
- Jenkins pipeline'ını tetikler
Workflow Dosyası
Workflow dosyası, projenizin GitHub reposunda yer almalıdır. Yerel geliştirme ortamınızda (IDE veya metin editörü) aşağıdaki dosya yolunda oluşturun ve reponuza push edin:
.github/workflows/docker-build-push.yml
name: Docker Build & Push
on:
push:
branches: [ "main" ]
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: '0'
# Otomatik versiyon oluşturma
- name: Bump version and push tag
id: tag_version
uses: anothrNick/github-tag-action@1.64.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WITH_V: true
DEFAULT_BUMP: patch
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# Docker build ve push
- name: Build and Push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/YOUR_IMAGE_NAME:latest
${{ secrets.DOCKERHUB_USERNAME }}/YOUR_IMAGE_NAME:${{ steps.tag_version.outputs.new_tag }}
# Jenkins tetikleme
- name: Trigger Jenkins Pipeline
run: |
curl -X POST ${{ secrets.JENKINS_URL }}/job/${{ secrets.JENKINS_JOB_NAME }}/buildWithParameters \
--user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} \
--data IMAGE_TAG=${{ steps.tag_version.outputs.new_tag }}
GitHub Secrets Yapılandırması
Repository Settings > Secrets and Variables > Actions bölümünden şu secret'ları ekleyin:
| Secret | Açıklama |
|---|---|
DOCKERHUB_USERNAME | Docker Hub kullanıcı adınız |
DOCKERHUB_TOKEN | Docker Hub access token |
JENKINS_URL | Jenkins instance URL'iniz |
JENKINS_JOB_NAME | Jenkins job adı |
JENKINS_USER | Jenkins kullanıcı adı |
JENKINS_TOKEN | Jenkins API token |
2. Jenkins Pipeline Yapılandırması
Jenkins pipeline, aşağıdaki aşamaları gerçekleştirir:
- K8s Deploy: Yeni Docker image'ı Kubernetes'e deploy eder
- Health Check: API'nin sağlıklı çalıştığını doğrular
- Sync Apinizer API Proxy: API Proxy'yi günceller veya oluşturur
- Deploy to Apinizer: Proxy'yi belirtilen environment'a deploy eder
Jenkinsfile
Jenkins pipeline'ı, Jenkins arayüzünden yeni bir Pipeline job oluşturularak tanımlanabilir. Aşağıdaki içeriği Jenkins UI'daki Pipeline script alanında kullanabilirsiniz.
Jenkinsfile
pipeline {
agent any
parameters {
string(name: 'IMAGE_TAG', defaultValue: 'latest', description: 'Docker image tag from GitHub Actions')
}
environment {
// Kubernetes yapılandırması
NAMESPACE = "YOUR_NAMESPACE"
DEPLOYMENT_NAME = "YOUR_DEPLOYMENT_NAME"
CONTAINER_NAME = "YOUR_CONTAINER_NAME"
DOCKER_IMAGE = "YOUR_DOCKERHUB_USERNAME/YOUR_IMAGE_NAME"
KUBECTL_PATH = "/usr/local/bin/kubectl"
// API bilgileri
API_BACKEND_URL = "YOUR_BACKEND_URL"
API_HEALTH_ENDPOINT = "${API_BACKEND_URL}/health"
API_SPEC_URL = "${API_BACKEND_URL}/api/v1/openapi.json"
// Apinizer yapılandırması
APINIZER_BASE_URL = "YOUR_APINIZER_URL"
APINIZER_GATEWAY_URL = "YOUR_APINIZER_GATEWAY_URL"
APINIZER_PROJECT = "YOUR_PROJECT_NAME"
APINIZER_ENVIRONMENT = "YOUR_ENVIRONMENT_NAME"
APINIZER_PROXY_NAME = "YOUR_PROXY_NAME"
APINIZER_PROXY_PATH = "YOUR_PROXY_RELATIVE_PATH"
}
stages {
stage('K8s Deploy') {
steps {
echo "Deploying ${DOCKER_IMAGE}:${params.IMAGE_TAG} to K8s..."
sh """
${KUBECTL_PATH} set image deployment/${DEPLOYMENT_NAME} \
${CONTAINER_NAME}=${DOCKER_IMAGE}:${params.IMAGE_TAG} \
-n ${NAMESPACE}
${KUBECTL_PATH} rollout status deployment/${DEPLOYMENT_NAME} -n ${NAMESPACE}
"""
}
}
stage('Health Check') {
steps {
echo "Checking API health at ${API_HEALTH_ENDPOINT}..."
sh """
sleep 10
curl -f ${API_HEALTH_ENDPOINT}
"""
}
}
stage('Sync Apinizer API Proxy') {
steps {
withCredentials([string(credentialsId: 'APINIZER_TOKEN', variable: 'TOKEN')]) {
script {
echo "Checking if API proxy exists..."
def proxyCheckCode = sh(
script: """
curl -s -o /dev/null -w '%{http_code}' \
-H 'Authorization: Bearer ${TOKEN}' \
'${APINIZER_BASE_URL}/apiops/projects/${APINIZER_PROJECT}/apiProxies/${APINIZER_PROXY_NAME}/'
""",
returnStdout: true
).trim()
echo "Proxy check returned: ${proxyCheckCode}"
def proxyExists = (proxyCheckCode == '200')
if (proxyExists) {
echo "API proxy exists, updating spec..."
sh """
curl -X PUT \
'${APINIZER_BASE_URL}/apiops/projects/${APINIZER_PROJECT}/apiProxies/url/' \
-H 'Authorization: Bearer ${TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
"apiProxyName": "${APINIZER_PROXY_NAME}",
"apiProxyCreationType": "OPEN_API",
"specUrl": "${API_SPEC_URL}",
"clientRoute": {
"relativePathList": ["${APINIZER_PROXY_PATH}"]
},
"reParse": true,
"deploy": false
}'
"""
} else {
echo "API proxy doesn't exist, creating..."
sh """
curl -X POST \
'${APINIZER_BASE_URL}/apiops/projects/${APINIZER_PROJECT}/apiProxies/url/' \
-H 'Authorization: Bearer ${TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
"apiProxyName": "${APINIZER_PROXY_NAME}",
"apiProxyDescription": "Auto-generated proxy",
"apiProxyCreationType": "OPEN_API",
"specUrl": "${API_SPEC_URL}",
"clientRoute": {
"relativePathList": ["${APINIZER_PROXY_PATH}"]
},
"routingInfo": {
"routingAddressList": [
{
"address": "${API_BACKEND_URL}",
"weight": 100
}
]
},
"deploy": false,
"reParse": false
}'
"""
}
}
}
}
}
stage('Deploy to Apinizer') {
steps {
withCredentials([string(credentialsId: 'APINIZER_TOKEN', variable: 'TOKEN')]) {
echo "Deploying API proxy to Apinizer ${APINIZER_ENVIRONMENT}..."
sh """
curl -X POST \
'${APINIZER_BASE_URL}/apiops/projects/${APINIZER_PROJECT}/apiProxies/${APINIZER_PROXY_NAME}/environments/${APINIZER_ENVIRONMENT}/' \
-H 'Authorization: Bearer ${TOKEN}'
"""
}
}
}
}
post {
success {
echo "✅ Pipeline completed! API deployed to K8s and Apinizer successfully."
}
failure {
echo "❌ Pipeline failed! Check logs above."
}
}
}
Jenkins Credentials Yapılandırması
Jenkins'de Manage Jenkins > Credentials bölümünden şu credential'ı ekleyin:
| Credential ID | Tip | Açıklama |
|---|---|---|
APINIZER_TOKEN | Secret text | Apinizer API token |
Apinizer API token oluşturma hakkında detaylı bilgi için Token Alma Yöntemleri dokümanını inceleyebilirsiniz.
3. Pipeline Aşamalarının Detayları
Stage 1: Kubernetes Deployment
Bu aşama Jenkins sunucusunda çalışır. GitHub Actions tarafından oluşturulan Docker image Kubernetes cluster'ına deploy edilir. kubectl set image komutu kullanılarak deployment güncellenir ve rollout durumu kontrol edilir.
${KUBECTL_PATH} set image deployment/${DEPLOYMENT_NAME} \
${CONTAINER_NAME}=${DOCKER_IMAGE}:${params.IMAGE_TAG} \
-n ${NAMESPACE}
${KUBECTL_PATH} rollout status deployment/${DEPLOYMENT_NAME} -n ${NAMESPACE}
Stage 2: Health Check
API'nin başarıyla deploy edildiğini doğrulamak için health endpoint'i kontrol edilir. Bu adım, Apinizer'a deploy etmeden önce API'nin çalışır durumda olduğundan emin olmak için kritiktir.
API_HEALTH_ENDPOINT değişkeni, pipeline'ı uyguladığınız uygulamanın health check endpoint'ini belirtir. Bu adres uygulamanıza özgüdür; örnek:
https://YOUR_BACKEND_URL/health
Uygulamanızın farklı bir health check endpoint'i varsa API_HEALTH_ENDPOINT değişkenini buna göre güncelleyin.
Stage 3: Apinizer API Proxy Senkronizasyonu
Bu kritik aşamada:
- Proxy Kontrolü: İlgili API Proxy'nin var olup olmadığı kontrol edilir
- Güncelleme veya Oluşturma:
- Proxy varsa: OpenAPI spec'i güncellenir (
PUTrequest) - Proxy yoksa: Yeni proxy oluşturulur (
POSTrequest)
- Proxy varsa: OpenAPI spec'i güncellenir (
Proxy Güncelleme (PUT)
Mevcut bir proxy'yi güncellerken reParse: true parametresi ile OpenAPI specification yeniden parse edilir:
{
"apiProxyName": "YOUR_PROXY_NAME",
"apiProxyCreationType": "OPEN_API",
"specUrl": "YOUR_BACKEND_URL/api/v1/openapi.json",
"clientRoute": {
"relativePathList": ["YOUR_PROXY_RELATIVE_PATH"]
},
"reParse": true,
"deploy": false
}
Detaylı bilgi için Update API Proxy API referansını inceleyebilirsiniz.
Yeni Proxy Oluşturma (POST)
Yeni proxy oluştururken backend routing bilgileri de tanımlanır:
{
"apiProxyName": "YOUR_PROXY_NAME",
"apiProxyDescription": "Auto-generated proxy",
"apiProxyCreationType": "OPEN_API",
"specUrl": "YOUR_BACKEND_URL/api/v1/openapi.json",
"clientRoute": {
"relativePathList": ["YOUR_PROXY_RELATIVE_PATH"]
},
"routingInfo": {
"routingAddressList": [
{
"address": "YOUR_BACKEND_URL",
"weight": 100
}
]
},
"deploy": false
}
Detaylı bilgi için Create API Proxy from URL API referansını inceleyebilirsiniz.
deploy: false parametresi ile proxy otomatik olarak deploy edilmez. Bu, bir sonraki stage'de kontrollü deployment yapılmasını sağlar.
Stage 4: Apinizer Environment'a Deploy
Son aşamada, güncellenen veya yeni oluşturulan proxy belirtilen environment'a deploy edilir. Bu işlem Apinizer'ın deployment API'si kullanılarak gerçekleştirilir:
POST /apiops/projects/{projectName}/apiProxies/{proxyName}/environments/{environmentName}/
Detaylı bilgi için Deploy API Proxy API referansını inceleyebilirsiniz.
Konfigürasyon Parametreleri
Environment Variables
Pipeline'da kullanılan temel environment variable'lar:
| Değişken | Açıklama | Örnek Değer |
|---|---|---|
APINIZER_BASE_URL | Apinizer platform URL'i | YOUR_APINIZER_URL |
APINIZER_PROJECT | Apinizer proje adı | YOUR_PROJECT_NAME |
APINIZER_ENVIRONMENT | Deploy edilecek environment | YOUR_ENVIRONMENT_NAME |
APINIZER_PROXY_NAME | API Proxy adı | YOUR_PROXY_NAME |
APINIZER_PROXY_PATH | Gateway'deki relative path | YOUR_PROXY_RELATIVE_PATH |
API_SPEC_URL | OpenAPI specification URL'i | YOUR_BACKEND_URL/openapi.json |
Apinizer API Endpoints
Bu pipeline'da kullanılan Apinizer API endpoint'leri:
| İşlem | Endpoint |
|---|---|
| Proxy Kontrolü | GET /apiops/projects/{project}/apiProxies/{proxyName}/ |
| Proxy Güncelleme | PUT /apiops/projects/{project}/apiProxies/url/ |
| Proxy Oluşturma | POST /apiops/projects/{project}/apiProxies/url/ |
| Environment Deploy | POST /apiops/projects/{project}/apiProxies/{proxyName}/environments/{env}/ |
Apinizer Management API hakkında detaylı bilgi için API Genel Bakış dokümanını inceleyebilirsiniz.
Kendi Pipeline'ınızı Uyarlamak
Bu örnek senaryo, Kubernetes üzerinde çalışan bir API için tasarlanmıştır. Kendi altyapınıza göre uyarlamak için:
Kubernetes yerine farklı bir orchestrator veya doğrudan VM deployment kullanıyorsanız, K8s Deploy stage'ini kendi deployment metodunuza göre değiştirin.
API'nizin farklı bir health check mekanizması varsa, API_HEALTH_ENDPOINT değişkenini ilgili endpoint ile güncelleyin.
API'nizin OpenAPI specification'ının erişilebilir bir URL'de olduğundan emin olun. Bu URL Apinizer tarafından erişilebilir olmalıdır.
Apinizer'da kullanmak istediğiniz environment'ı (dev, test, prod vb.) APINIZER_ENVIRONMENT değişkeninde belirtin.
Credential'larınızı Jenkins Credentials Manager üzerinden yönetmeniz, pipeline güvenliği açısından daha uygun bir yaklaşım olacaktır.
Sonuç
Bu kılavuz, GitHub Actions, Jenkins ve Apinizer'ı kullanarak tam otomatik bir CI/CD pipeline'ının nasıl kurulacağını göstermiştir. Her kod değişikliği otomatik olarak build edilir ve Apinizer'a deploy edilir. Bu yaklaşım, manuel işlemleri minimize ederek deployment sürecinizi hızlandırır ve hata olasılığını azaltır.