Docker-ი თანამედროვე CI/CD პროცესების (pipelines) მთავარი კომპონენტია, რომელიც უზრუნველყოფს თანმიმდევრულ build-ებს, ეფექტურ ტესტირებას და საიმედო deployment-ს სხვადასხვა გარემოში. აპლიკაციების კონტეინერიზაციით, Docker-ი ქმნის ერთგვაროვან გარემოს განვითარების მთელი ციკლის განმავლობაში, დეველოპერის ლოკალური მანქანიდან დაწყებული, ტესტირებითა და production deployment-ით დამთავრებული.
Docker-ის როლი CI/CD-ში მოიცავს:
იზოლირებული, განმეორებადი build გარემოების უზრუნველყოფა აპლიკაციის შეფუთვის სტანდარტიზაცია სხვადასხვა გარემოსთვის აპლიკაციის image-ების ეფექტური გავრცელების ხელშეწყობა შეუცვლელი (immutable) ინფრასტრუქტურის პატერნების მხარდაჭერა მიკროსერვისების არქიტექტურისა და მასშტაბირებადი deployment-ების მხარდაჭერა ერთი და იგივე გარემო განვითარების, ტესტირებისა და production-ის ეტაპებზე იდენტური გაშვების გარემო (runtime) ყოველ ეტაპზე გამორიცხავს გარემოზე დამოკიდებულ ხარვეზებს კონტეინერის image-ები შეიცავს ყველა დამოკიდებულებას, ბიბლიოთეკასა და კონფიგურაციას "ააწყე ერთხელ, გაუშვი ყველგან" ფილოსოფია პრაქტიკულ რეალობად იქცევა კონფიგურაციებს შორის განსხვავებები იმართება გარემოს ცვლადებით ან კონფიგურაციის ფაილებით "ჩემს კომპიუტერზე მუშაობს" პრობლემის აღმოფხვრა კონტეინერები ერთად ფუთავს ყველა დამოკიდებულებასა და გაშვების გარემოს დეველოპერები, ტესტერები და ოპერაციების გუნდები მუშაობენ იდენტური კონტეინერებით სისტემის დონის დამოკიდებულებები კაფსულირებულია კონტეინერში კონტეინერების ორკესტრაცია უზრუნველყოფს deployment-ის თანმიმდევრულ ქცევას განმეორებადი build-ები და ტესტები კონტეინერიზებული build პროცესები უზრუნველყოფს იზოლირებულ, თანმიმდევრულ build გარემოებს Build-ის არტეფაქტები დამოკიდებულია მხოლოდ საწყის კოდზე და არა build მანქანაზე დეტერმინისტული build-ები იდენტური შემავალი მონაცემებიდან იდენტურ შედეგს იძლევა ავტომატური ტესტირება ეშვება კონტეინერებში, რომლებიც production გარემოს იდენტურია დეტერმინისტული deployment-ები შეუცვლელი (immutable) კონტეინერის image-ები ხელს უშლის გარემოებს შორის შეუსაბამობას კონტეინერების ორკესტრაციის პლატფორმები უზრუნველყოფენ სასურველი მდგომარეობის შენარჩუნებას "ინფრასტრუქტურა როგორც კოდი" პრაქტიკა უზრუნველყოფს თანმიმდევრულ ინფრასტრუქტურას დეკლარაციული კონფიგურაცია ამცირებს ხელით ჩარევასა და შეცდომებს ვერსიების კონტროლის ქვეშ მყოფი ინფრასტრუქტურა Dockerfile-ები და compose ფაილები ინახება ვერსიების კონტროლის სისტემაში Image-ის თეგები უზრუნველყოფს მკაფიო ვერსიონირებასა და მიკვლევადობას კონტეინერის კონფიგურაციები იმართება აპლიკაციის კოდთან ერთად გარემოში განხორციელებული ცვლილებების სრული აუდიტის კვალი დაკეშირებული ფენები (layers) უფრო სწრაფი build-ებისთვის Docker-ის ფენების კეშირება დრამატულად აჩქარებს განმეორებით build-ებს ხელახლა აწყობა სჭირდება მხოლოდ შეცვლილ ფენებს Dockerfile-ების ოპტიმიზაცია ეფექტური კეშირებისთვის BuildKit-ის პარალელური დამუშავება მრავალეტაპიანი build-ებისთვის პარალელური ტესტირება კონტეინერებში რამდენიმე ტესტ-სუიტის ერთდროულად გაშვება იზოლირებულ კონტეინერებში მატრიცული ტესტირება სხვადასხვა კონფიგურაციასა თუ ვერსიაზე რესურს-ეფექტური სატესტო გარემოები კონტეინერიზაციის საშუალებით დროებითი სატესტო გარემოები სწრაფად იქმნება და იშლება Image-ების ეფექტური გავრცელება Image-ების განახლებისას გადაეცემა მხოლოდ შეცვლილი ფენები განაწილებული registry-ები აუმჯობესებს pull-ის წარმადობას ფენების დედუპლიკაცია ამცირებს შენახვის მოთხოვნებს კონტენტზე დაფუძნებული მისამართების საცავი (Content-addressable storage) უზრუნველყოფს მთლიანობას სწრაფი deployment-ი კონტეინერების ორკესტრაციით კონტეინერების ორკესტრატორები ავტომატიზირებენ deployment-ის პროცესებს Rolling updates ამცირებს შეფერხების დროს (downtime) Blue-green და canary deployment-ის პატერნები თვითაღდგენის შესაძლებლობები ავტომატურად აღადგენს სისტემას ხარვეზებისგან სწრაფი უკან დაბრუნება (rollback) საჭიროებისას შეუცვლელი image-ები მყისიერი უკან დაბრუნების საშუალებას იძლევა წინა ვერსიებზე ვერსიების თეგირება უზრუნველყოფს მკაფიო სამიზნეებს უკან დასაბრუნებლად Registry-ს ისტორია ინახავს ყველა წინა ვერსიას ორკესტრაციის პლატფორმებს აქვთ ხარვეზის შემთხვევაში ავტომატური უკან დაბრუნების მხარდაჭერა იზოლირებული build გარემოები თითოეული build ეშვება სუფთა, იზოლირებულ კონტეინერში არ ხდება ჩარევა ერთდროულად მიმდინარე build-ებს შორის გარემოს ცვლადები აკონტროლებენ build-ის სპეციფიკურ პარამეტრებს განმეორებადია CI სერვერის მიუხედავად განცალკევებული სატესტო გარემოები ტესტები ეშვება იზოლირებულ კონტეინერებში, რომლებიც production-ის იდენტურია სატესტო მონაცემების იზოლაცია ხელს უშლის ტესტებს შორის მონაცემების შერევას პარალელური ტესტების შესრულება ჩარევის გარეშე რესურსების ლიმიტები ხელს უშლის "ხმაურიანი მეზობლის" პრობლემებს დამოკიდებულებების იზოლაცია აპლიკაციის დამოკიდებულებები მოთავსებულია image-ებში არ არის კონფლიქტები აპლიკაციებს შორის, რომლებიც სხვადასხვა ვერსიებს საჭიროებენ დამოკიდებულებების მკაფიო დეკლარირება Dockerfile-ებში კონტეინერებს შეუძლიათ გამოიყენონ ერთი და იგივე დამოკიდებულების სხვადასხვა ვერსიები გარემოს სპეციფიკური კონფიგურაციები გარემოს ცვლადები ემატება გაშვების დროს (runtime) კონფიგურაციის ფაილები მაგრდება (mount) ან ემატება სხვადასხვა გარემოსთვის საიდუმლოებების მართვა ინტეგრირებულია კონტეინერულ პლატფორმებთან ერთი და იგივე image-ი ეშვება სხვადასხვა გარემოში სხვადასხვა კონფიგურაციით სუფთა მდგომარეობა ყოველი build-ისთვის ყოველი build-ი და ტესტი იწყება ცნობილი სუფთა მდგომარეობიდან არ რჩება არტეფაქტები წინა build-ებიდან დროებითი build გარემოები ხელს უშლის მდგომარეობის დაგროვებას მკაფიო გამიჯვნა მუდმივ მონაცემებსა და აპლიკაციის კოდს შორის ტიპური Docker CI/CD პროცესი მოიცავს:
საწყისი კოდის გადმოწერა (checkout) რეპოზიტორიის კლონირება ვერსიების კონტროლის სისტემიდან დამოკიდებულებებისა და ქვემოდულების გადმოწერა Build-ის კონფიგურაციის ფაილების მიღება Branch-ების სტრატეგიების გამოყენება (feature, release branch-ები) საწყისი კოდის მთლიანობის ვალიდაცია Image-ის აწყობა Docker build პროცესის გაშვება Dockerfile-ის გამოყენებით მრავალეტაპიანი (multi-stage) build-ების იმპლემენტაცია ოპტიმიზაციისთვის შესაბამისი თეგების მინიჭება branch-ის/commit-ის/ვერსიის მიხედვით BuildKit-ისა და ფენების კეშირების გამოყენება ეფექტურობისთვის პლატფორმა-სპეციფიკური ან მრავალარქიტექტურული image-ების აწყობა ავტომატური ტესტირება Unit ტესტების გაშვება კონტეინერებში ინტეგრაციული ტესტების შესრულება კონტეინერიზებულ დამოკიდებულებებთან ერთად End-to-end ტესტირების ჩატარება სრული კონტეინერული სტეკებით Image-ის ფუნქციონალის ვალიდაცია კონტეინერ-სპეციფიკური ტესტებით წარმადობისა და დატვირთვის ტესტირების ჩატარება იზოლირებულ გარემოებში უსაფრთხოების სკანირება Image-ების სკანირება ცნობილ მოწყვლადობებზე (CVEs) სენსიტიური მონაცემებისა და საიდუმლოებების შემოწმება Image-ის კონფიგურაციის ვალიდაცია უსაფრთხოების საუკეთესო პრაქტიკებთან მიმართებით Image-ის წარმომავლობისა და მთლიანობის დადასტურება უსაფრთხოების პოლიტიკებთან შესაბამისობის უზრუნველყოფა Image-ის რეესტრში შენახვა დადასტურებული image-ების ატვირთვა კონტეინერების რეესტრში შესაბამისი თეგებისა და მეტამონაცემების მინიჭება Image-ების ხელმოწერა ავთენტურობის დასადასტურებლად რეესტრზე წვდომის კონტროლის იმპლემენტაცია Image-ების შენახვის პოლიტიკების კონფიგურაცია გარემოებში deployment-ი Deployment-ი development, staging და production გარემოებში კონტეინერების ორკესტრაციის იმპლემენტაცია (Kubernetes, Swarm) Deployment-ის სტრატეგიების შესრულება (rolling, blue/green, canary) გარემო-სპეციფიკური კონფიგურაციების გამოყენება წარმატებული deployment-ის ვალიდაცია მონიტორინგი და ვერიფიკაცია კონტეინერის სიჯანსაღისა და წარმადობის მონიტორინგი ფუნქციონალის ვერიფიკაცია smoke ტესტების საშუალებით დაკვირვებადობის (observability) იმპლემენტაცია (ლოგები, მეტრიკები, ტრეისები) Deployment-ის წარმატების მეტრიკების თვალყურის დევნება საჭიროების შემთხვევაში ავტომატური უკან დაბრუნების (rollback) გაშვება
name : Docker CI/CD
on :
push :
branches : [ main ]
# სურვილისამებრ, გაეშვას თეგებზე release-ებისთვის
tags : [ 'v*.*.*' ]
pull_request :
branches : [ main ]
jobs :
build-and-push :
runs-on : ubuntu-latest
steps :
- name : Checkout code
uses : actions/checkout@v3
with :
# სრული ისტორიის გადმოწერა სწორი ვერსიონირებისთვის
fetch-depth : 0
# Docker-ის მეტამონაცემების ამოღება
- name : Extract Docker metadata
id : meta
uses : docker/metadata-action@v4
with :
images : username/app
# თეგების გენერირება branch-ის, git თეგის და commit SHA-ს მიხედვით
tags : |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,format=short
- name : Set up Docker Buildx
uses : docker/setup-buildx-action@v2
with :
# პარალელური აწყობისთვის რამდენიმე კვანძის გამოყენება
driver-opts : network=host
- name : Login to DockerHub
# ეს ნაბიჯი გაეშვება მხოლოდ რეესტრში ატვირთვისას (არა pull request-ებზე)
if : github.event_name != 'pull_request'
uses : docker/login-action@v2
with :
username : ${{ secrets.DOCKERHUB_USERNAME }}
password : ${{ secrets.DOCKERHUB_TOKEN }}
# Optionally add logout: true for security
# Docker-ის ფენების კეშირება build-ების დასაჩქარებლად
- name : Cache Docker layers
uses : actions/cache@v3
with :
path : /tmp/.buildx-cache
key : ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys : |
${{ runner.os }}-buildx-
# სურვილისამებრ: ტესტების გაშვება აწყობამდე
- name : Run tests
run : |
docker build -t username/app:test --target test .
docker run username/app:test
# მოწყვლადობების სკანირება ატვირთვამდე
- name : Run Trivy vulnerability scanner
uses : aquasecurity/trivy-action@master
with :
image-ref : 'username/app:test'
format : 'table'
exit-code : '1'
ignore-unfixed : true
severity : 'CRITICAL,HIGH'
- name : Build and push
uses : docker/build-push-action@v4
with :
context : .
# ატვირთვა მხოლოდ იმ შემთხვევაში, თუ არ არის PR და ტესტები/სკანირება წარმატებულია
push : ${{ github.event_name != 'pull_request' }}
# მეტამონაცემების გამოყენება ჭკვიანი თეგირებისთვის
tags : ${{ steps.meta.outputs.tags }}
labels : ${{ steps.meta.outputs.labels }}
# რეესტრის კეშის გამოყენება ეფექტური build-ებისთვის
cache-from : type=registry,ref=username/app:buildcache
cache-to : type=registry,ref=username/app:buildcache,mode=max
# Build არგუმენტები საჭიროების შემთხვევაში
build-args : |
BUILD_VERSION=${{ github.ref_name }}
BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
# BuildKit-ის ეფექტური build შესაძლებლობების გამოყენება
platforms : linux/amd64,linux/arm64
# წარმომავლობის დადასტურების დამატება
provenance : true
# Image-ის ხელმოწერა უსაფრთხოებისთვის (თუ კონფიგურირებულია)
# ხელმოწერის ჩართვა: true
# Deployment-ი staging გარემოში წარმატებული build/push-ის შემდეგ
- name : Deploy to staging
if : github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
run : |
echo "Deployment-ი staging გარემოში"
# გამოიყენეთ kubectl, helm, ან სხვა deployment-ის ხელსაწყოები
# kubectl set image deployment/app-deployment app=username/app:${{ github.sha }}
# პროცესის ყველა ეტაპის განსაზღვრა
stages :
- build
- test
- security
- deploy
- verify
# გლობალური ცვლადები, რომლებიც გამოიყენება job-ებში
variables :
# Commit SHA-ს გამოყენება უნიკალური image-ის თეგირებისთვის
DOCKER_IMAGE : $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
# თეგის მინიჭება semver-ით, თუ თეგი აიტვირთება
RELEASE_IMAGE : $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
# გამოიყენეთ Docker Hub-ის სარკე სიჩქარის ლიმიტების თავიდან ასაცილებლად
DOCKER_HUB_MIRROR : https://mirror.gcr.io
# Docker BuildKit-ის კონფიგურაცია ეფექტური build-ებისთვის
DOCKER_BUILDKIT : 1
# მორგებული build არგუმენტები
BUILD_ARGS : "--build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') --build-arg VCS_REF=$CI_COMMIT_SHORT_SHA"
# Build ეტაპი: აპლიკაციის კომპილაცია და შეფუთვა
build :
stage : build
# გამოიყენეთ Docker-in-Docker image-ების ასაწყობად
image : docker:20.10.16
services :
- docker:20.10.16-dind
before_script :
# საჭიროების შემთხვევაში დააინსტალირეთ დამოკიდებულებები
- apk add --no-cache git curl jq
# Docker BuildX-ის კონფიგურაცია მრავალპლატფორმიანი build-ებისთვის
- docker buildx create --use
# GitLab კონტეინერების რეესტრში ავტორიზაცია
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script :
# წინა build-ებიდან კეშირება
- |
CACHE_FROM=""
if docker pull $CI_REGISTRY_IMAGE:latest &>/dev/null; then
CACHE_FROM="--cache-from $CI_REGISTRY_IMAGE:latest"
fi
# აპლიკაციის image-ის აწყობა მეტამონაცემებით
- >
docker build
$CACHE_FROM
$BUILD_ARGS
--build-arg CI_PIPELINE_ID=$CI_PIPELINE_ID
--label org.opencontainers.image.created="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
--label org.opencontainers.image.revision="$CI_COMMIT_SHA"
--label org.opencontainers.image.version="${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}"
-t $DOCKER_IMAGE
-t $CI_REGISTRY_IMAGE:latest
.
# ორივე თეგის რეესტრში ატვირთვა
- docker push $DOCKER_IMAGE
- docker push $CI_REGISTRY_IMAGE:latest
# ვერსიის თეგის მინიჭება, თუ ეს თეგით build-ია
- |
if [ -n "$CI_COMMIT_TAG" ]; then
docker tag $DOCKER_IMAGE $RELEASE_IMAGE
docker push $RELEASE_IMAGE
fi
# არტეფაქტების შექმნა შემდეგი ეტაპებისთვის
artifacts :
paths :
- docker-image-info.json
expire_in : 1 week
# დამოკიდებულებების კეშირება მომავალი build-ების დასაჩქარებლად
cache :
key : ${CI_COMMIT_REF_SLUG}
paths :
- node_modules/
- .npm/
only :
- main
- tags
- merge_requests
# ტესტირების ეტაპი: ავტომატური ტესტების გაშვება
test :
stage : test
image : $DOCKER_IMAGE
# სატესტო გარემოს ცვლადების განსაზღვრა
variables :
NODE_ENV : test
# გამოიყენეთ in-memory მონაცემთა ბაზა ტესტებისთვის
DATABASE_URL : "sqlite://:memory:"
before_script :
# Prepare test environment
- echo "Setting up test environment"
- npm install --only=dev
script :
# Run unit tests
- npm run test:unit
# Run integration tests
- npm run test:integration
# Run end-to-end tests if not a merge request (for speed)
- '[ "$CI_PIPELINE_SOURCE" = "merge_request_event" ] || npm run test:e2e'
# Generate code coverage report
- npm run coverage
# ტესტის რეპორტების გამოქვეყნება არტეფაქტებად
artifacts :
reports :
junit : junit-*.xml
coverage_report :
coverage_format : cobertura
path : coverage/cobertura-coverage.xml
paths :
- coverage/
coverage : '/Statements\s+:\s+(\d+.?\d*)%/'
only :
- main
- tags
- merge_requests
# უსაფრთხოების სკანირების ეტაპი
security :
stage : security
image :
name : aquasec/trivy:latest
entrypoint : [ "" ]
variables :
# პროცესის შეწყვეტა კრიტიკულ მოწყვლადობებზე
TRIVY_EXIT_CODE : 1
TRIVY_FORMAT : json
TRIVY_OUTPUT : trivy-results.json
# dev დამოკიდებულებების გამოტოვება
TRIVY_SEVERITY : CRITICAL,HIGH
script :
# დასასკანერებელი image-ის გადმოწერა
- docker pull $DOCKER_IMAGE
# Image-ის სკანირება მოწყვლადობებზე
- trivy image --format $TRIVY_FORMAT --output $TRIVY_OUTPUT --exit-code $TRIVY_EXIT_CODE $DOCKER_IMAGE
# უსაფრთხოების რეპორტის გენერირება
artifacts :
paths :
- trivy-results.json
reports :
container_scanning : trivy-results.json
allow_failure : true
only :
- main
- tags
# Deployment-ის ეტაპი
deploy :
stage : deploy
image : docker:20.10.16
services :
- docker:20.10.16-dind
before_script :
# Deployment-ის ხელსაწყოების ინსტალაცია
- apk add --no-cache curl bash
# რეესტრში ავტორიზაცია
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script :
# Deployment-ისთვის image-ის გადმოწერა
- docker pull $DOCKER_IMAGE
# Production release-ებისთვის გამოიყენეთ ვერსიის თეგი
- |
if [ -n "$CI_COMMIT_TAG" ]; then
docker tag $DOCKER_IMAGE $CI_REGISTRY_IMAGE:stable
docker push $CI_REGISTRY_IMAGE:stable
DEPLOY_ENV="production"
else
DEPLOY_ENV="staging"
fi
# Deployment-ი შესაბამის გარემოში
- echo "Deploying to $DEPLOY_ENV environment"
# მაგალითი docker-compose-ის ან kubectl-ის გამოყენებით
- |
if [ "$DEPLOY_ENV" = "production" ]; then
echo "Production deployment-ის შესრულება"
# kubectl set image deployment/app app=$DOCKER_IMAGE
else
echo "Performing staging deployment"
# docker-compose -f docker-compose.staging.yml up -d
fi
environment :
name : $DEPLOY_ENV
url : https://$DEPLOY_ENV.example.com
only :
- main
- tags
# ვერიფიკაციის ეტაპი
verify :
stage : verify
image : curlimages/curl
script :
# დაელოდეთ deployment-ის დასტაბილურებას
- sleep 30
# სიჯანსაღის შემოწმება
- curl -f https://$DEPLOY_ENV.example.com/health || exit 1
# Smoke ტესტების გაშვება
- curl -f https://$DEPLOY_ENV.example.com/api/status | grep -q "OK"
environment :
name : $DEPLOY_ENV
url : https://$DEPLOY_ENV.example.com
only :
- main
- tags
pipeline {
// გამოიყენეთ დინამიური agent-ი Docker-ის შესაძლებლობებით
agent {
docker {
image 'docker:20.10.16-dind'
args '-v /var/run/docker.sock:/var/run/docker.sock -v jenkins-docker-certs:/certs/client -v jenkins-data:/var/jenkins_home'
}
}
// პაიპლაინის გარემოს ცვლადები
environment {
DOCKER_REGISTRY = 'docker.io'
DOCKER_IMAGE = 'myusername/myapp'
DOCKER_CREDENTIALS_ID = 'docker-hub-credentials'
// გამოიყენეთ დროის ნიშნულიანი თეგები ვერსიონირებისთვის
BUILD_VERSION = "${env.BUILD_NUMBER}-${new Date().format('yyyyMMddHHmmss')}"
// Docker BuildKit-ის კონფიგურაცია
DOCKER_BUILDKIT = '1'
}
// Define stages of the pipeline
stages {
// გარემოს მომზადება
stage('Prepare') {
steps {
// გარემოს გასუფთავება
cleanWs()
// კოდის ჩამოტვირთვა SCM-დან
checkout scm
// საჭირო ხელსაწყოების ინსტალაცია
sh 'apk add --no-cache git curl jq'
// Docker BuildX-ის კონფიგურაცია მრავალპლატფორმიანი build-ებისთვის
sh 'docker buildx create --name cibuilder --use || true'
// გარემოს ინფორმაციის გამოტანა დებაგისთვის
sh 'docker version'
sh 'docker info'
sh 'git log -1'
// კოდიდან ვერსიის ინფორმაციის გამოტანა
script {
// სემანტიკური ინფორმაციის გამოტანა package.json-დან
if (fileExists('package.json')) {
def packageJson = readJSON file: 'package.json'
env.APP_VERSION = packageJson.version
echo "Building application version: ${env.APP_VERSION}"
}
}
}
}
// Docker იმიჯის აშენება
stage('Build') {
steps {
// ფენების ქეშირება წინა აშენებიდან, თუ შესაძლებელია
sh '''
if docker pull ${DOCKER_IMAGE}:latest; then
CACHE_FROM="--cache-from ${DOCKER_IMAGE}:latest"
else
CACHE_FROM=""
fi
# Build the image with metadata
docker build \
$CACHE_FROM \
--build-arg BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--build-arg VCS_REF=$(git rev-parse --short HEAD) \
--build-arg VERSION=${APP_VERSION:-0.1.0} \
--label org.opencontainers.image.created=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--label org.opencontainers.image.revision=$(git rev-parse HEAD) \
--label org.opencontainers.image.version=${APP_VERSION:-0.1.0} \
-t myapp:${BUILD_VERSION} \
-t myapp:latest \
.
'''
// იმიჯის დეტალების გამოტანა
sh 'docker image ls myapp'
}
}
// ტესტების გაშვება კონტეინერში
stage('Test') {
steps {
// სხვადასხვა ტიპის ტესტების გაშვება
sh '''
# Unit ტესტები
docker run --rm myapp:latest npm test
# ინტეგრაციული ტესტები, თუ არსებობს
if [ -f "integration-test.sh" ]; then
docker run --rm myapp:latest ./integration-test.sh
fi
# Linting-ის გაშვება თუ შესაძლებელია
if docker run --rm myapp:latest which eslint > /dev/null; then
docker run --rm myapp:latest eslint .
fi
'''
// უსაფრთხოების სკანირება
sh '''
# Optional: Run Trivy scanner
if which trivy > /dev/null; then
trivy image --exit-code 1 --severity HIGH,CRITICAL myapp:latest
else
echo "Trivy not installed, skipping security scan"
fi
'''
}
}
// იმიჯის რეესტრში ატვირთვა
stage('Push') {
steps {
// Jenkins-ის ანგარიშის გამოყენება უსაფრთხო შესვლისთვის
withCredentials([usernamePassword(credentialsId: "${DOCKER_CREDENTIALS_ID}", usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASSWORD')]) {
sh '''
# Login to Docker Hub securely
echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USER}" --password-stdin ${DOCKER_REGISTRY}
# Tag with appropriate names for the registry
docker tag myapp:latest ${DOCKER_IMAGE}:latest
docker tag myapp:latest ${DOCKER_IMAGE}:${BUILD_VERSION}
# If this is a tag build, also tag with the git tag
if [ -n "${GIT_TAG}" ]; then
docker tag myapp:latest ${DOCKER_IMAGE}:${GIT_TAG}
docker push ${DOCKER_IMAGE}:${GIT_TAG}
fi
# Push all tags to the registry
docker push ${DOCKER_IMAGE}:latest
docker push ${DOCKER_IMAGE}:${BUILD_VERSION}
# Logout for security
docker logout ${DOCKER_REGISTRY}
'''
}
}
}
// აპლიკაციის დეფლოიმენტი სამიზნე გარემოში
stage('Deploy') {
steps {
// Deployment-ის სხვადასხვა სტრატეგია branch-ის/გარემოს მიხედვით
script {
if (env.BRANCH_NAME == 'main' || env.BRANCH_NAME == 'master') {
echo "დეფლოიმენტი საწარმოო გარემოში"
// Docker Compose-ის გამოყენება საწარმოო დეფლოიმენტისთვის
withCredentials([file(credentialsId: 'production-env-file', variable: 'ENV_FILE')]) {
sh '''
# გარმოს ფაილის კოპირება საწარმოო გარემოში
cp ${ENV_FILE} .env.production
# იმიჯის ტეგის განახლება compose ფაილში
sed -i "s|image: ${DOCKER_IMAGE}:.*|image: ${DOCKER_IMAGE}:${BUILD_VERSION}|g" docker-compose.prod.yml
# ნულოვანი დაუნთაიმით განახლება
docker-compose -f docker-compose.prod.yml up -d --remove-orphans
# ჯანმრთელობის შემოწმების დალოდება
timeout 60s bash -c 'until docker-compose -f docker-compose.prod.yml exec -T app wget -q -O- http://localhost:3000/health | grep -q "ok"; do sleep 2; done'
'''
}
} else if (env.BRANCH_NAME == 'staging') {
echo "დეფლოიმენტი staging გარემოში"
sh 'docker-compose -f docker-compose.staging.yml up -d'
} else {
echo "Branch ${env.BRANCH_NAME} doesn't trigger deployment"
}
}
}
}
}
// ბილდის შემდგომი მოქმედებები
post {
always {
// Docker-ის რესურსების გასუფთავება
sh '''
docker system prune -f
docker image rm -f myapp:${BUILD_VERSION} myapp:latest || true
'''
}
success {
echo "Pipeline completed successfully!"
// წარმატების შესახებ შეტყობინება (Slack, email, სხვ.)
slackSend(color: 'good', message: "ბილდი წარმატებულია: ${env.JOB_NAME} #${env.BUILD_NUMBER} - ${env.BUILD_URL}")
}
failure {
echo "ფაიფლაინი ჩაიშალა!"
// Notify on failure
slackSend(color: 'danger', message: "ბილდი ჩაიშალა: ${env.JOB_NAME} #${env.BUILD_NUMBER} - ${env.BUILD_URL}")
}
}
}
pipeline {
agent any
environment {
DOCKER_REGISTRY = 'docker.io'
DOCKER_IMAGE = 'myusername/myapp'
DOCKER_CREDENTIALS_ID = 'docker-hub-credentials'
PLATFORMS = 'linux/amd64,linux/arm64,linux/arm/v7'
}
stages {
stage('Prepare BuildX') {
steps {
// Docker BuildX-ის დაყენება თუ საჭიროა
sh '''
# Docker BuildX-ის დაყენება მრავალპლატფორმიანი build-ებისთვის
docker buildx version || {
BUILDX_VERSION="v0.10.0"
mkdir -p ~/.docker/cli-plugins
curl -sSLo ~/.docker/cli-plugins/docker-buildx \
https://github.com/docker/buildx/releases/download/${BUILDX_VERSION}/buildx-${BUILDX_VERSION}.linux-amd64
chmod +x ~/.docker/cli-plugins/docker-buildx
}
# ახალი builder-ის ინსტანსის შექმნა და გამოყენება შესაბამისი დრაივერებით
docker buildx create --name multiarch-builder --driver docker-container --use || true
docker buildx inspect multiarch-builder --bootstrap
'''
}
}
stage('Login to Registry') {
steps {
withCredentials([usernamePassword(credentialsId: "${DOCKER_CREDENTIALS_ID}", usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASSWORD')]) {
sh 'echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USER}" --password-stdin ${DOCKER_REGISTRY}'
}
}
}
stage('Build Multi-arch Images') {
steps {
// მრავალარქიტექტურული იმიჯის აშენება და ატვირთვა ერთ ეტაპად
sh '''
# ვერსიის ამოღება git თეგიდან ან დროის ნიშნულზე დაფუძნებული ვერსიის გენერირება
if git describe --exact-match --tags HEAD > /dev/null 2>&1; then
VERSION=$(git describe --exact-match --tags HEAD)
else
VERSION=$(git rev-parse --short HEAD)
fi
echo "მრავალარქიტექტურული იმიჯის აშენება, ვერსია: $VERSION"
# Build and push with all platforms in one command
docker buildx build \
--platform ${PLATFORMS} \
--build-arg BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--build-arg VCS_REF=$(git rev-parse --short HEAD) \
--build-arg VERSION=${VERSION} \
--tag ${DOCKER_IMAGE}:${VERSION} \
--tag ${DOCKER_IMAGE}:latest \
--push \
.
'''
}
}
}
}
CircleCI-ის სრული პაიპლაინი Docker-ზე დაფუძნებული აპლიკაციებისთვის:
version : 2.1
# ხელახლა გამოსაყენებელი ბრძანებების განსაზღვრა
commands :
docker_build :
description : "Docker-ის იმიჯის აგება და თეგირება"
parameters :
image_name :
type : string
default : "myapp"
dockerfile :
type : string
default : "Dockerfile"
build_args :
type : string
default : ""
steps :
- run :
name : Docker-ის იმიჯის აგება
command : |
# თეგების გამოთვლა
COMMIT_TAG=${CIRCLE_SHA1:0:8}
VERSION_TAG=${CIRCLE_TAG:-$COMMIT_TAG}
# გამოიყენეთ კეში წინა build-ებიდან, თუ ხელმისაწვდომია
CACHE_FROM=""
if docker pull $DOCKERHUB_USERNAME/<< parameters.image_name >>:latest &>/dev/null; then
CACHE_FROM="--cache-from $DOCKERHUB_USERNAME/<< parameters.image_name >>:latest"
fi
# აწყობა შესაბამისი თეგებითა და ლეიბლებით
docker build \
$CACHE_FROM \
-f << parameters.dockerfile >> \
--build-arg BUILDKIT_INLINE_CACHE=1 \
--build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
--build-arg VCS_REF=${CIRCLE_SHA1} \
--build-arg VERSION=${VERSION_TAG} \
<< parameters.build_args >> \
-t << parameters.image_name >>:${COMMIT_TAG} \
-t << parameters.image_name >>:latest \
-t $DOCKERHUB_USERNAME/<< parameters.image_name >>:${COMMIT_TAG} \
-t $DOCKERHUB_USERNAME/<< parameters.image_name >>:latest \
.
# ვერსიის თეგის მინიჭება, თუ ეს თეგით build-ია
if [ -n "${CIRCLE_TAG}" ]; then
docker tag << parameters.image_name >>:${COMMIT_TAG} $DOCKERHUB_USERNAME/<< parameters.image_name >>:${CIRCLE_TAG}
fi
# შემსრულებლის გარემოების განსაზღვრა
executors :
docker-builder :
docker :
- image : cimg/base:2023.03
resource_class : medium+
# Job-ების განსაზღვრა
jobs :
build :
executor : docker-builder
steps :
- checkout
- setup_remote_docker :
version : 20.10.14
docker_layer_caching : true
- docker_build :
image_name : myapp
build_args : "--build-arg NODE_ENV=production"
- run :
name : იმიჯის შენახვა შემდგომი job-ებისთვის
command : |
COMMIT_TAG=${CIRCLE_SHA1:0:8}
mkdir -p /tmp/workspace
docker save myapp:${COMMIT_TAG} | gzip > /tmp/workspace/myapp-image.tar.gz
- persist_to_workspace :
root : /tmp/workspace
paths :
- myapp-image.tar.gz
test :
docker :
- image : cimg/base:2023.03
steps :
- setup_remote_docker :
version : 20.10.14
- attach_workspace :
at : /tmp/workspace
- run :
name : Docker-ის იმიჯის ჩატვირთვა
command : |
docker load < /tmp/workspace/myapp-image.tar.gz
- run :
name : Unit ტესტების გაშვება
command : |
COMMIT_TAG=${CIRCLE_SHA1:0:8}
docker run --rm myapp:${COMMIT_TAG} npm run test:unit
- run :
name : ინტეგრაციული ტესტების გაშვება
command : |
COMMIT_TAG=${CIRCLE_SHA1:0:8}
docker run --rm myapp:${COMMIT_TAG} npm run test:integration
- run :
name : უსაფრთხოების სკანირების გაშვება
command : |
COMMIT_TAG=${CIRCLE_SHA1:0:8}
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy:latest image --severity HIGH,CRITICAL --exit-code 0 myapp:${COMMIT_TAG}
push :
executor : docker-builder
steps :
- checkout
- setup_remote_docker :
version : 20.10.14
- attach_workspace :
at : /tmp/workspace
- run :
name : Docker-ის იმიჯის ჩატვირთვა
command : |
docker load < /tmp/workspace/myapp-image.tar.gz
- run :
name : Docker Hub-ზე ატვირთვა
command : |
COMMIT_TAG=${CIRCLE_SHA1:0:8}
echo "$DOCKERHUB_PASSWORD" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin
docker push $DOCKERHUB_USERNAME/myapp:${COMMIT_TAG}
docker push $DOCKERHUB_USERNAME/myapp:latest
# ვერსიის თეგის ატვირთვა, თუ ეს თეგით build-ია
if [ -n "${CIRCLE_TAG}" ]; then
docker push $DOCKERHUB_USERNAME/myapp:${CIRCLE_TAG}
fi
# უსაფრთხოებისთვის ყოველთვის გამოდით სისტემიდან
docker logout
deploy-staging :
docker :
- image : cimg/base:2023.03
steps :
- checkout
- run :
name : Deployment-ის ხელსაწყოების ინსტალაცია
command : |
sudo apt-get update
sudo apt-get install -y curl jq
# kubectl-ის ინსტალაცია Kubernetes-ის deployment-ებისთვის
curl -LO "https://dl.k8s.io/release/v1.26.0/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
- run :
name : Staging-ზე დეპლოი
command : |
COMMIT_TAG=${CIRCLE_SHA1:0:8}
echo "Deploying $DOCKERHUB_USERNAME/myapp:${COMMIT_TAG} to staging"
# Deployment-ის მაგალითი kubectl-ის გამოყენებით
# kubectl config use-context staging
# kubectl set image deployment/myapp myapp=$DOCKERHUB_USERNAME/myapp:${COMMIT_TAG} --record
# kubectl rollout status deployment/myapp
deploy-production :
docker :
- image : cimg/base:2023.03
steps :
- checkout
- run :
name : Deployment-ის ხელსაწყოების ინსტალაცია
command : |
sudo apt-get update
sudo apt-get install -y curl jq
curl -LO "https://dl.k8s.io/release/v1.26.0/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
- run :
name : Production-ზე დეპლოი
command : |
VERSION_TAG=${CIRCLE_TAG}
echo "Deploying $DOCKERHUB_USERNAME/myapp:${VERSION_TAG} to production"
# საწარმოო deployment-ის მაგალითი
# kubectl config use-context production
# kubectl set image deployment/myapp myapp=$DOCKERHUB_USERNAME/myapp:${VERSION_TAG} --record
# kubectl rollout status deployment/myapp
# სამუშაო პროცესების ორკესტრირება
workflows :
version : 2
build-test-deploy :
jobs :
- build :
filters :
tags :
only : /^v.*/
- test :
requires :
- build
filters :
tags :
only : /^v.*/
- push :
requires :
- test
filters :
tags :
only : /^v.*/
branches :
only : main
- deploy-staging :
requires :
- push
filters :
branches :
only : main
- approve-production :
type : approval
requires :
- push
filters :
tags :
only : /^v.*/
branches :
ignore : /.*/
- deploy-production :
requires :
- approve-production
filters :
tags :
only : /^v.*/
branches :
ignore : /.*/
Docker-ის აგების ოპტიმიზაცია CI/CD-ში:
გამოიყენეთ BuildKit-ი უფრო სწრაფი, პარალელური build-ებისთვის ჩართეთ DOCKER_BUILDKIT=1 გარემოს ცვლადით დამოუკიდებელი build ეტაპების პარალელური შესრულება უფრო ეფექტური კეშირების მექანიზმები საიდუმლოებების დამაგრება ფენებში გაჟონვის გარეშე გაუმჯობესებული build-ის გამომავალი მონაცემები და სტატუსის რეპორტინგი მაგალითი: export DOCKER_BUILDKIT=1 && docker build . დანერგეთ ფენების კეშირება შეინახეთ და ხელახლა გამოიყენეთ ფენები build-ებს შორის დააკონფიგურირეთ რეესტრზე დაფუძნებული კეშირება CI/CD-სთვის მოახდინეთ Dockerfile-ის ოპტიმიზაცია ეფექტური ფენების კეშირებისთვის გამოიყენეთ BuildKit-ის ჩაშენებული კეშის მეტამონაცემები დააყენეთ CI-სპეციფიკური კეშის საცავი მაგალითი: docker build --cache-from myapp:cache --build-arg BUILDKIT_INLINE_CACHE=1 . გამოიყენეთ მრავალეტაპიანი build-ები უფრო მცირე image-ებისთვის გამოყავით build გარემო გაშვების (runtime) გარემოსგან საბოლოო image-ში შეინახეთ მხოლოდ აუცილებელი არტეფაქტები შეამცირეთ თავდასხმის ზედაპირი და image-ის ზომა გააზიარეთ აწყობილი არტეფაქტები მრავალ საბოლოო image-ს შორის მაგალითი: იხილეთ მრავალეტაპიანი Dockerfile-ის მაგალითი ოპტიმიზაციის სექციაში ააწყვეთ მხოლოდ ის, რაც შეიცვალა კეშის დამოკიდებულებებით დაალაგეთ Dockerfile-ის ინსტრუქციები ყველაზე იშვიათად ცვლადიდან ყველაზე ხშირად ცვლადისკენ გამოყავით დამოკიდებულებების ინსტალაცია აპლიკაციის კოდისგან გამოიყენეთ კონკრეტული COPY ბრძანებები COPY . .-ის ნაცვლად დანერგეთ mount კეშირება პაკეტების მენეჯერებისთვის მაგალითი: docker build --build-arg BUILDKIT_INLINE_CACHE=1 . დანერგეთ build არგუმენტები გარემო-სპეციფიკური build-ებისთვის მოახდინეთ build-ების პარამეტრიზაცია ARG ინსტრუქციებით დააკონფიგურირეთ სხვადასხვა ქცევა გარემოს მიხედვით დააყენეთ build-ის დროის ცვლადები ვერსიონირებისთვის თავი აარიდეთ გარემო-სპეციფიკური მნიშვნელობების მყარად ჩაწერას მაგალითი: docker build --build-arg NODE_ENV=production . მიანიჭეთ image-ებს აზრიანი, მიკვლევადი იდენტიფიკატორები გამოიყენეთ სემანტიკური ვერსიონირება release-ის თეგებისთვის მიკვლევადობისთვის დაამატეთ git commit-ის SHA განიხილეთ დროის ნიშნულზე დაფუძნებული თეგები CI build-ებისთვის გამოიყენეთ მრავალი თეგი სხვადასხვა მიზნებისთვის გამოიყენეთ შეუცვლელი (immutable) თეგები production deployment-ებისთვის მაგალითი: docker tag myapp:latest myapp:1.2.3-a7c45b9 Docker-ი უზრუნველყოფს თანმიმდევრულ, იზოლირებულ სატესტო გარემოებს, რომლებიც production-ის იდენტურია. ქვემოთ მოცემულია ტესტირების სრული კონფიგურაცია:
version : '3.8'
services :
# მთავარი აპლიკაციის სერვისი
app :
build :
context : .
dockerfile : Dockerfile
target : development # გამოიყენეთ განვითარების ეტაპი ტესტირების დამოკიდებულებებით
depends_on :
db :
condition : service_healthy # დაელოდეთ მონაცემთა ბაზის სრულ მზადყოფნას
redis :
condition : service_healthy
environment :
- NODE_ENV=test
- DB_HOST=db
- DB_PORT=5432
- DB_USER=test
- DB_PASSWORD=test
- DB_NAME=test_db
- REDIS_HOST=redis
- REDIS_PORT=6379
# საწყისი კოდის დამაგრება განვითარების დროს hot reloading-ისთვის
volumes :
- ./src:/app/src:ro
- ./test:/app/test:ro
- node_modules:/app/node_modules
# პორტის გახსნა debug-ისთვის
ports :
- "9229:9229"
# ჯანმრთელობის შემოწმების დამატება მზადყოფნისთვის
healthcheck :
test : [ "CMD" , "wget" , "-qO-" , "http://localhost:3000/health" ]
interval : 5s
timeout : 3s
retries : 5
start_period : 10s
# მონაცემთა ბაზის სერვისი ტესტირებისთვის
db :
image : postgres:13-alpine
environment :
- POSTGRES_USER=test
- POSTGRES_PASSWORD=test
- POSTGRES_DB=test_db
volumes :
- ./test/fixtures/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
- postgres-data:/var/lib/postgresql/data
# ჯანმრთელობის შემოწმება უზრუნველყოფს, რომ მონაცემთა ბაზა მზად არის ტესტების გაშვებამდე
healthcheck :
test : [ "CMD-SHELL" , "pg_isready -U test -d test_db" ]
interval : 5s
timeout : 3s
retries : 5
start_period : 10s
# კეშის სერვისი
redis :
image : redis:alpine
healthcheck :
test : [ "CMD" , "redis-cli" , "ping" ]
interval : 5s
timeout : 3s
retries : 5
# Unit ტესტები
test-unit :
image : myapp:test
depends_on :
app :
condition : service_healthy
environment :
- NODE_ENV=test
- TEST_TYPE=unit
volumes :
- ./test/reports:/app/test/reports
command : npm run test:unit
# ინტეგრაციული ტესტები
test-integration :
image : myapp:test
depends_on :
app :
condition : service_healthy
db :
condition : service_healthy
redis :
condition : service_healthy
environment :
- NODE_ENV=test
- TEST_TYPE=integration
- DB_HOST=db
- REDIS_HOST=redis
volumes :
- ./test/reports:/app/test/reports
command : npm run test:integration
# End-to-end ტესტები
test-e2e :
image : myapp:test
depends_on :
app :
condition : service_healthy
db :
condition : service_healthy
environment :
- NODE_ENV=test
- TEST_TYPE=e2e
- APP_URL=http://app:3000
volumes :
- ./test/reports:/app/test/reports
- ./test/screenshots:/app/test/screenshots
command : npm run test:e2e
volumes :
node_modules :
postgres-data :
უსაფრთხოების სკანირების CI/CD პროცესში ინტეგრაცია ეხმარება მოწყვლადობების იდენტიფიცირებას განვითარების პროცესის ადრეულ ეტაპზე:
# ძირითადი სკანირება Trivy-ით CI-ში
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:latest image myapp:latest
# გაფართოებული სკანირება ფილტრაციითა და ფორმატირებული გამოტანით
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:latest image \
--severity HIGH,CRITICAL \
--exit-code 1 \
--ignore-unfixed \
--format json \
--output trivy-results.json \
myapp:latest
# პაიპლაინის ინტეგრაცია მოწყვლადობის ზღვარით
if docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:latest image --severity CRITICAL \
--exit-code 1 --no-progress myapp:latest ; then
echo "კრიტიკული მოწყვლადობები არ მოიძებნა"
else
echo "კრიტიკული მოწყვლადობები მოიძებნა, build-ი ჩაიშლება"
exit 1
fi
# სკანირება და რეპორტის დამატება build-ის არტეფაქტებში
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
-v "$( pwd )/reports:/reports" \
aquasec/trivy:latest image \
--format template \
--template "@/contrib/html.tpl" \
-o /reports/trivy-report.html \
myapp:latest
# გაუშვით Docker Bench Security ჰოსტისა და კონტეინერის კონფიგურაციის შესამოწმებლად
docker run --rm -it \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /etc:/etc \
-v /usr/bin/containerd:/usr/bin/containerd \
-v /usr/bin/runc:/usr/bin/runc \
-v /usr/lib/systemd:/usr/lib/systemd \
-v /var/lib:/var/lib \
docker/docker-bench-security
# გაუშვით გამოტანის ფაილში გადამისამართებით CI ინტეგრაციისთვის
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /etc:/etc \
docker/docker-bench-security > docker-bench-results.txt
# მხოლოდ ჩაშლილი შემოწმებების ფილტრაცია
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
docker/docker-bench-security | grep "\[WARN\]" > security-warnings.txt
Image-ის ხელმოწერის დანერგვა გამოიყენეთ Docker Content Trust image-ების ხელმოწერისა და ვერიფიკაციისთვის დააკონფიგურირეთ CI/CD image-ების ავტომატური ხელმოწერისთვის შეინახეთ ხელმოწერის გასაღებები უსაფრთხოდ CI საიდუმლოებებში ან HSM-ებში მაგალითი: DOCKER_CONTENT_TRUST=1 docker push myorg/myapp:1.0.0 დანერგეთ გასაღებების როტაციისა და მართვის პროცედურები Image-ის მთლიანობის ვერიფიკაცია ვალიდაცია გაუკეთეთ image-ის ხელმოწერებს deployment-მდე შეამოწმეთ image-ის digest-ები შეუცვლელობისთვის დანერგეთ ბრძანებათა ჯაჭვის ვერიფიკაცია მაგალითი: docker trust inspect --pretty myorg/myapp:1.0.0 ინტეგრირება CI/CD-ში ავტომატური ვალიდაციის ნაბიჯებით დააყენეთ admission controller-ები დანერგეთ Kubernetes admission controller-ები runtime ვალიდაციისთვის დააკონფიგურირეთ validating და mutating webhook-ები შეამოწმეთ image-ები უსაფრთხოების პოლიტიკების წინააღმდეგ deployment-მდე Kubernetes-ის კონფიგურაციის მაგალითი:
apiVersion : admissionregistration.k8s.io/v1
kind : ValidatingWebhookConfiguration
metadata :
name : image-policy-webhook
webhooks :
- name : image-policy.k8s.io
rules :
- apiGroups : [ "" ]
apiVersions : [ "v1" ]
operations : [ "CREATE" , "UPDATE" ]
resources : [ "pods" ]
scope : "Namespaced"
clientConfig :
service :
namespace : image-policy
name : image-policy-webhook
path : /validate
admissionReviewVersions : [ "v1" , "v1beta1" ]
sideEffects : None
timeoutSeconds : 5
გამოიყენეთ პოლიტიკის ძრავები, როგორიცაა OPA განსაზღვრეთ დეკლარაციული პოლიტიკები Open Policy Agent (OPA)-ით ინტეგრირება Kubernetes-თან Gatekeeper-ის გამოყენებით აღასრულეთ ორგანიზაციული უსაფრთხოების სტანდარტები OPA პოლიტიკის მაგალითი:
package kubernetes.admission
deny[msg] {
input.request.kind.kind == "Pod"
image := input.request.object.spec.containers[_].image
not startswith(image, "approved-registry.com/")
msg := sprintf("image '%v' მოდის არასანდო რეესტრიდან", [image])
}
აღასრულეთ უსაფრთხოების სტანდარტები დანერგეთ შესაბამისობის შემოწმებები ინდუსტრიული სტანდარტებისთვის ვალიდაცია გაუკეთეთ CIS Docker Benchmark-ის წინააღმდეგ აღასრულეთ ორგანიზაცია-სპეციფიკური უსაფრთხოების პოლიტიკები ავტომატიზირება გაუკეთეთ შესაბამისობის ვერიფიკაციას CI/CD-ში გენერირება გაუკეთეთ შესაბამისობის რეპორტებს აუდიტისთვის CI ნაბიჯის მაგალითი:
compliance-check :
runs-on : ubuntu-latest
steps :
- name : CIS Docker Benchmark-ის გაშვება
run : |
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
docker/docker-bench-security --check-sh 5
- name : დამტკიცებული საბაზისო image-ების ვერიფიკაცია
run : |
docker inspect myapp:latest | jq -r '.[].Config.Image' | grep -q "^approved-base-image:"
Docker enables consistent deployments across environments through environment-specific configuration rather than environment-specific builds. This pattern supports the "build once, deploy anywhere" principle:
Development Local developer environments Feature branch deployments Rapid iteration and debugging Additional development tools and verbosity Testing/QA Automated test environments Manual QA verification Performance testing Security testing environments Staging Production-like environment Final validation before production User acceptance testing Pre-production data migrations Production Live customer-facing environment High availability configuration Production-grade security Monitoring and observability
# Example deployment script with advanced environment handling
#!/bin/bash
set -eo pipefail
# Set variables based on environment
case "$ENVIRONMENT" in
"dev")
DOCKER_COMPOSE_FILE="docker-compose.dev.yml"
REPLICAS=1
RESOURCES="--cpus=0.5 --memory=512m"
REGISTRY="dev-registry.example.com"
;;
"qa")
DOCKER_COMPOSE_FILE="docker-compose.qa.yml"
REPLICAS=2
RESOURCES="--cpus=1 --memory=1g"
REGISTRY="qa-registry.example.com"
;;
"staging")
DOCKER_COMPOSE_FILE="docker-compose.staging.yml"
REPLICAS=2
RESOURCES="--cpus=2 --memory=2g"
REGISTRY="staging-registry.example.com"
;;
"production")
DOCKER_COMPOSE_FILE="docker-compose.prod.yml"
REPLICAS=5
RESOURCES="--cpus=4 --memory=4g"
REGISTRY="production-registry.example.com"
# Additional production safeguards
DEPLOY_TIMEOUT="--timeout 300s"
HEALTHCHECK="--health-cmd 'curl -f http://localhost/health || exit 1' --health-interval=10s --health-retries=5"
;;
* )
echo "Unknown environment : $ENVIRONMENT"
exit 1
;;
esac
# Pull the specific image version
IMAGE_TAG=${VERSION:-latest}
docker pull $REGISTRY/myapp:$IMAGE_TAG
# Apply environment-specific configurations
envsubst < ${DOCKER_COMPOSE_FILE}.template > ${DOCKER_COMPOSE_FILE}
# Deploy with environment-specific settings
if [ "$ENVIRONMENT" == "production" ]; then
# Production uses a more careful deployment strategy
echo "Deploying to production with rolling update"
# Verify image security before deployment
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:latest image --severity HIGH,CRITICAL \
--exit-code 1 $REGISTRY/myapp:$IMAGE_TAG || { echo "Security check failed"; exit 1; }
# Backup current state
docker-compose -f docker-compose.prod.yml config > docker-compose.prev.yml
# Deploy new version
docker-compose -f $DOCKER_COMPOSE_FILE up -d --remove-orphans $DEPLOY_TIMEOUT
# Verify deployment health
timeout 60s bash -c 'until docker-compose -f $DOCKER_COMPOSE_FILE ps | grep -q "(healthy)"; do sleep 2; done'
# Run smoke tests
./run_smoke_tests.sh || {
echo "Smoke tests failed, rolling back"
docker-compose -f docker-compose.prev.yml up -d
exit 1
}
else
# Development and staging environments
echo "Deploying to $ENVIRONMENT"
docker-compose -f $DOCKER_COMPOSE_FILE up -d --remove-orphans
fi
# Cleanup
if [ "$ENVIRONMENT" != "production" ]; then
echo "Pruning old images from $ENVIRONMENT"
docker image prune -a -f --filter "until=24h"
fi
echo "Deployment to $ENVIRONMENT complete"
# Base docker-compose configuration
# docker-compose.base.yml
version : '3.8'
services :
app :
image : ${REGISTRY}/myapp:${IMAGE_TAG:-latest}
restart : unless-stopped
environment :
- NODE_ENV=${ENVIRONMENT}
healthcheck :
test : [ "CMD" , "curl" , "-f" , "http://localhost:3000/health" ]
interval : 10s
timeout : 5s
retries : 3
start_period : 30s
deploy :
resources :
limits :
cpus : "${CPU_LIMIT:-0.5}"
memory : "${MEMORY_LIMIT:-512M}"
# Development-specific overrides
# docker-compose.dev.yml
version : '3.8'
services :
app :
extends :
file : docker-compose.base.yml
service : app
environment :
- NODE_ENV=development
- DEBUG=app:*
- LOG_LEVEL=debug
volumes :
- ./src:/app/src:ro
- ./config:/app/config:ro
ports :
- "3000:3000"
- "9229:9229" # Debug port
command : [ "npm" , "run" , "dev" ]
# Production-specific overrides
# docker-compose.prod.yml
version : '3.8'
services :
app :
extends :
file : docker-compose.base.yml
service : app
environment :
- NODE_ENV=production
- LOG_LEVEL=info
secrets :
- app_config
- db_credentials
deploy :
replicas : 5
update_config :
order : start-first
failure_action : rollback
delay : 10s
restart_policy :
condition : any
delay : 5s
max_attempts : 3
window : 120s
resources :
limits :
cpus : '4'
memory : 4G
reservations :
cpus : '2'
memory : 2G
secrets :
app_config :
external : true
db_credentials :
external : true
Automated build and test Automatic code verification at every commit Comprehensive test suite execution Code quality and security checks Artifact generation and validation Example: npm test && npm run lint && npm run build Manual approval for production Human decision point before production deployment Approval gates with required reviewers Compliance and change management integration Documentation of approval process Example CI configuration:
deploy-production :
needs : [ build , test ]
environment : production
when : manual
rules :
- if : $CI_COMMIT_BRANCH == "main"
Ready-to-deploy artifacts Immutable container images Versioned and labeled for traceability Pre-validated in lower environments Stored in secure container registry Example image tagging strategy:
docker tag myapp:latest myapp:1.2.3- ${CI_COMMIT_SHORT_SHA}
docker push myapp:1.2.3- ${CI_COMMIT_SHORT_SHA}
Environment promotion
# ახალი ვერსიის განლაგება (მწვანე)
docker-compose -f docker-compose.green.yml up -d
# smoke ტესტების გაშვება
./run_smoke_tests.sh
# ტრაფიკის მწვანეზე გადართვა
nginx -s reload
# ძველი ვერსიის ამოღება (ცისფერი)
docker-compose -f docker-compose.blue.yml down
Docker-ით საუბნო განლაგებების დანერგვა:
განალაგეთ ახალი ვერსია სერვერების მცირე ნაწილზე მოახდინეთ წარმადობისა და შეცდომების მონიტორინგი თანდათან გაზარდეთ ტრაფიკი ახალ ვერსიაზე ავტომატურად დაბრუნდით პრობლემების აღმოჩენისას დაასრულეთ გადანაცვლება სტაბილურობის შემდეგ
version : '3.8'
services :
app :
image : myapp:latest
secrets :
- db_password
- api_key
secrets :
db_password :
external : true
api_key :
external : true
Jenkins-ი Docker agent-ებით Drone CI Tekton Concourse CI GitLab CI/CD Runner-ები GitHub Actions CircleCI AWS CodeBuild/CodePipeline Google Cloud Build Azure DevOps Pipelines გაითვალისწინეთ ეს საუკეთესო პრაქტიკები Docker-ის CI/CD-ში გამოყენებისას:
გამოიყენეთ კონკრეტული image-ის თეგები და არა 'latest' დანერგეთ კეშირების სწორი სტრატეგიები შეინარჩუნეთ CI/CD პროცესების სისწრაფე დაასკანირეთ image-ები მოწყვლადობებზე ჩაატარეთ ტესტირება production-ის მსგავს გარემოში შეინახეთ Docker-ის კონფიგურაციები ვერსიების კონტროლის სისტემაში დანერგეთ შესაბამისი მონიტორინგი
# Matrix build-ების მაგალითი GitHub Actions-ით
strategy :
matrix :
node-version : [ 14.x , 16.x , 18.x ]
os : [ ubuntu-latest , windows-latest ]
steps :
- uses : actions/checkout@v3
- name : Node.js ${{ matrix.node-version }}-ის გამოყენება
uses : actions/setup-node@v3
with :
node-version : ${{ matrix.node-version }}
- run : docker build --build-arg NODE_VERSION=${{ matrix.node-version }} -t myapp:${{ matrix.node-version }} .
Deployment-ის სიხშირე ცვლილებების დანერგვის დრო ცვლილებების წარუმატებლობის მაჩვენებელი აღდგენის საშუალო დრო Build-ის ხანგრძლივობა შეტყობინებები წარუმატებელი build-ების შესახებ შეტყობინებები deployment-ის შესახებ გაფრთხილებები წარმადობაზე ზემოქმედების შესახებ შეცდომების მაჩვენებლის მონიტორინგი მომხმარებლის უკუკავშირის შეგროვება ხშირი Docker CI/CD პრობლემები და მათი გადაჭრის გზები:
Docker socket-ის უფლებები რეესტრში ავტორიზაციის შეცდომები რესურსების შეზღუდვები CI-ში ქსელთან დაკავშირების პრობლემები კეშის ინვალიდაციის პრობლემები Image-ის ზომისა და გადმოწერის დროის პრობლემები