Küçük Projeler İçin Kurtarıcı GitLab CI/CD Pipeline'ı
Reklam
Hiçbir CI/CD kurulumu olmayan küçük bir projeyi devraldığımda, deployment (dağıtım) süreci genelde birinin sunucuya SSH ile bağlanıp en son commit'i çekmesi ve servisi elle yeniden başlatması anlamına gelir.
Bu yöntem patlayana kadar iyi çalışır. Unutulmuş bir npm install, yanlış bir branch'ten çıkılan deploy veya gözden kaçan bir çevre değişkeni (environment variable) production'ı yıkmak için yeterlidir. Bunun çözümü, on iki farklı aşaması olan karmaşık bir pipeline yazmak değildir. Çözüm, her seferinde aynı üç şeyi kesin bir güvenilirlikle yapan kısa bir .gitlab-ci.yml dosyasıdır: derle, test et ve dağıt (build, test, deploy).
Yapının kendisi
stages:
- build
- test
- deploy
variables:
GIT_DEPTH: 1
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
build:
stage: build
image: node:20
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 hour
test:
stage: test
image: node:20
script:
- npm ci
- npm run test -- --ci
GIT_DEPTH: 1 parametresi, uzun geçmişe sahip repolarda git checkout işlemlerinin inanılmaz hızlı kalmasını sağlar. node_modules klasörünün branch bazlı önbelleğe alınması (caching), pipeline'ların büyük çoğunluğunda sıfırdan npm kurulumu yapılmasını atlar. Build (derleme) aşaması, deploy aşamasının yeniden kullanacağı derlenmiş bir artifact üretir. Bu da kodun her bir aşamada değil, pipeline başına sadece bir kez derlenmesini garanti eder.
SSH üzerinden deploy
Küçük projelerde, bir Kubernetes manifestosu yazmak veya bir konteyner kayıt defteri (container registry) kurmak çoğu zaman projenin gerçekte ihtiyaç duyduğundan daha fazla altyapı yükü getirir. Doğrudan CI üzerinden tetiklenen basit bir SSH üzeri rsync işlemi, şaşırtıcı sayıda gerçek dünya senaryosunu güvenle çözer:
deploy_staging:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache openssh-client rsync
- eval $(ssh-agent -s)
- echo "$STAGING_SSH_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh && chmod 700 ~/.ssh
- ssh-keyscan -H "$STAGING_HOST" >> ~/.ssh/known_hosts
script:
- rsync -az --delete dist/ deploy@$STAGING_HOST:/var/www/staging/
environment:
name: staging
url: https://staging.example.com
rules:
- if: '$CI_COMMIT_BRANCH == "develop"'
Kullanılan SSH anahtarı kodun içinde değil, tamamen GitLab üzerinde maskelenmiş ve korunmuş bir CI/CD değişkeninde yaşar. ssh-keyscan komutu known_hosts dosyasını doldurur ki pipeline işlemi bir host-key onay ekranında sonsuza kadar asılı kalmasın. Son olarak, rsync --delete komutu uzak sunucudaki dizini build çıktısı ile birebir senkronize tutar ve zamanla kullanılmayan eski dosyaların orada çöp gibi birikmesini engeller.
Production için manuel onay kapısı
Staging ortamı develop branch'ine yapılan her push'ta otomatik olarak deploy edilir. Production ortamı ise main üzerinden deploy edilir, ancak yalnızca birisi o butona tıkladığında:
deploy_production:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache openssh-client rsync
- eval $(ssh-agent -s)
- echo "$PRODUCTION_SSH_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh && chmod 700 ~/.ssh
- ssh-keyscan -H "$PRODUCTION_HOST" >> ~/.ssh/known_hosts
script:
- rsync -az --delete dist/ deploy@$PRODUCTION_HOST:/var/www/production/
environment:
name: production
url: https://example.com
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual
when: manual ayarı, işi kendi kendine ateşlenen bir betikten ziyade GitLab'in pipeline görünümünde gerçek bir butona dönüştürür. GitLab'in ortam (environment) takibiyle birleştiğinde, tek tıkla eski bir artifact'a geri dönüş (rollback) yapabileceğiniz tam bir deployment geçmişi kazanırsınız. Bu rollback butonu, hatalı bir deploy sonrası yaşanacak tam teşekküllü bir paniği birden fazla kez otuz saniyelik basit bir müdahaleye çevirmiştir.
Bu neden genelde yeterlidir?
Bu pipeline kod için linter çalıştırmaz. Bir Docker imajı (image) oluşturmaz. Gidip bir Kubernetes kümesiyle konuşmaz. Küçük projelerin ezici bir çoğunluğu için bu durum son derece normaldir. Eğer proje gerçekten büyüyüp bunlara ihtiyaç duyarsa, bu özellikler sonradan rahatlıkla eklenebilir.
Bu pipeline'ın asıl yaptığı şey, manuel dağıtımların çuvalladığı o üç noktayı kalıcı olarak ortadan kaldırmasıdır: birisinin bağımlılıkları yüklemeyi unutması, test edilmemiş bir kodu canlıya atması veya yanlış branch'i deploy etmesidir. Bu kısalıktaki bir .gitlab-ci.yml bu üçünü de yakalar. Dahası, projeye dokunacak bir sonraki mühendisin tüm deployment akışını bir dakikadan kısa sürede okuyup anlayabileceği kadar da kısadır.
Reklam