Sonatype Nexus Repository Manager
Kirish
Bugungi software development jarayonlarida CI/CD (Continuous Integration/Continuous Deployment) jarayonlarini samarali yuritish muhim ahamiyat kasb etadi. Bunday jarayonlarda paketlar va artifaktlarni boshqarish uchun maxsus repository managerlar kerak bo'ladi. Sonatype Nexus Repository Manager - eng ommabop va ishonchli artifakt menejerlardan biri bo'lib, Java (Maven, Gradle), .NET (NuGet), Python (PyPi), Docker va boshqa paketlarni saqlash va boshqarish uchun eng mashhur va ishonchli yechimlardan biridir.
Nexus opensource (Nexus OSS) va pullik (Nexus Pro) versiyalarda mavjud bo'lib, ushbu qo'llanma asosan Nexus OSS bilan ishlashga yo'naltirilgan.
Sonatype Nexus Repository Manager dasturi dastlab 2007-yilda Sonatype Inc. tomonidan ishlab chiqilgan. U dasturiy ta'minot artifaktlarini saqlash, boshqarish va tarqatish uchun mo'ljallangan markazlashtirilgan repository menejeri sifatida ishlab chiqilgan.
Nexus Repository Manager dasturiy ta'minot ishlab chiqishda artifaktlar va paketlarni saqlash, boshqarish hamda ularga kirishni ta'minlash uchun ishlatiladi. Java (Maven, Gradle), .NET (NuGet), Node.js (NPM), Docker, Python (PyPi) kabi texnologiyalar uchun artifaktlarni markazlashtirilgan holda saqlaydi va boshqaradi.Tashqi repository'lardan yuklash jarayonlarini tezlashtirish va tarmoq yuklamasini kamaytirish imkonini beradi va Korxona ichki(local) repositoriyasini yaratishi, Kompaniyaning o'ziga xos kutubxonalarini(library) boshqarish, xavfsizlikni ta'minlash va dasturiy ta'minot jarayonlarini optimallashtirish uchun ishlatiladi.
Bu amaliyotda biz Sonatype Nexus Repository Managerni docker yordamida o'rnatish va sozlashni va loyihalarimizga va CI/CD ga integratsiya qilishni ko'rib chiqamiz.
Nexus o'rnatish
Bu amaliyotda biz Nexusni docker yordamida ishga tushiramiz va o'rnatishning manual va ansible yordamida qilishni ko'rib chiqamiz.
Minimum Server talabi
OS | RAM | CPU | Xotira | Static IP |
---|---|---|---|---|
Ubuntu 20.04 yoki Rocky Linux 8 | 8GB | 4 | 80GB | Ha kerak |
Quyidagi qo'llanmadan foydalanib Docker o'rnatib olishingiz mumkin - Docker o'rnatish (opens in a new tab)
- Manual
- Ansible
Manual o'rnatish
1-> Nexusni docker orqali o'rnatayotganimiz sababli nexus malumotlarini docker volume yoki hostpath qilib saqlashimiz kerak bo'ladi aks holda nexus container restart bo'lganda malumotlar o'chib ketadi shuning uchun nexusga data papka ochib olamiz.
sudo mkdir -p /mnt/nexus/nexus-data
sudo chown -R 200 /mnt/nexus/nexus-data
2-> Nexusni docker yordamida ishga tushiramiz va nexus-data
ni serverimizdagi /mnt/nexus/nexus-data
ga ulab qo'yamiz va --restart=always
flagi orqali tasodifan server yoki docker restart bo'lganda avtomatik ishga tushirilishini belgilaymiz.
docker run -d \
-p 8081:8081 \
--name nexus \
--restart=always \
-v /mnt/nexus/nexus-data:/nexus-data \
sonatype/nexus3
3-> Nexusni ishga tushirganimizdan keyin u default admin user va parol bilan birga keladi, admin parolni olish uchun quyidagicha amalni bajaramiz.
docker exec -it nexus cat /nexus-data/admin.password
Nexusni o'rnatib bo'lganimizdan keyin brauzerda server_ip:8081
manzilini ochganimizda Nexus ochilishi kerak. Nexus default porti 8081
bo'ladi.
Bu qismda ->Sign in bosib Nexusning login sahifasiga o'tamiz.
Default admin
user va generatsiya qilingan default parol bilan kiramiz.
Bu qismda esa default parol o'rniga o'zimiz yangi parol qo'yishni talab qiladi yangi parolni yozib kiritamiz.
Bu qismda o'zimizga kerak tanlovni tanlaymiz.
Sizda admin
user bilan kirganingizdan keyin sizda quyidagicha dastlabki sahifa ochiladi.
Nexusga domen ulash
Bu bo'limda biz Nexusni domen orqali ulashni va Letsencrypt sertifikat orqali SSL olishni ko'rib chiqamiz.
- Debian Based
- Red Had Based
1-> Nginx va certbotni o'rnatamiz.
sudo apt update
sudo apt install nginx certbot python3-certbot-nginx -y
2-> Nexusga bo'glamoqchi bo'lgan domenimiz DNS serveridan A record ochib serverimiz IP manzilini qo'shib qo'yamiz. Rasmda ahost misolida helm.uz domeniga nexus subdomen qo'shib ko'rsatilgan. 3-> Bog'lamoqchi bo'lgan domenimiz nomi bilan nginx konfiguratsiyasini yaratamiz.
sudo nano /etc/nginx/sites-available/nexus.helm.uz
Quyidagicha konfiguratsiyani yozamiz.
server {
listen 80;
max_body_size 100M;
server_name nexus.helm.uz;
location / {
proxy_pass http://localhost:8081;
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 $scheme;
}
}
4-> Konfiguratsiyani sites-enabled
papkasiga joylaymiz.
sudo ln -s /etc/nginx/sites-available/nexus.helm.uz /etc/nginx/sites-enabled/
5-> Nginxga restart beramiz.
sudo systemctl restart nginx
6-> certbot orqali Letsencrypt sertifikatni olish uchun quyidagi buyruqni yozamiz.
sudo certbot
Bunda siz certbot uchun email yozasiz va Terms of Service ni qabul qilishingiz kerak bo'ladi y
bosib o'tib ketasiz.
Bu qismda sizning domenlaringizni ko'rsatadi siz kerakli domenlarni tanlab Enter
bosib o'tib ketasiz, bizning holatda 1.
Sertifikat muvaffaqiyatli olinganidan keyin nginxni restart qilamiz.
sudo systemctl restart nginx
Tekshirib ko'rish uchun brauzerda https://nexus.helm.uz (opens in a new tab) manzilini ochganimizda Nexus https bilan ochilishi kerak.
Nexus bilan tanishuv
Nexus Repository Manager APT, Cargo, Bower CocoaPods, Composer, Conan, Conda, Docker, Git LFS, Go, Helm, Hugging Face, Maven, npm, NuGet, p2, PyPI, R, Raw, RubyGems, Yum(RPM) kabi texnologiyalar uchun repositorylar yaratish va boshqarishni qo'llab-quvvatlaydi.
Sonatype Incning Sonatype Nexus Repositorydan tashqari Sonatype Repository Firewall, Sonatype Lifecycle va Sonatype SBOM kabi service'lari ham mavjud.
Nexusga kirganimizda asosiy sahifa ochiladi.
-> Server Administration and Configuration bo'limida server va konfiguratsiyalarini o'zgartirish imkoniyati mavjud.
-> Blob Stores bo'limida Nexusning fayllarni saqlash uchun ishlatiladigan papkalarni ko'rishimiz mumkin, bizning holda default
papkasi(blobstore) mavjud.
-> Repository bo'limida repositorylarimizni ko'rishimiz mumkin, nexusda default maven-public, maven-central, maven-releases, maven-snapshots, nuget-group, nuget-hosted, nuget.org-proxy repositorylar mavjud.
Agar siz kompaniyangizda Proxy bilan internetga chiqish talab qilinsa -> Settings -> System -> HTTP bo'limiga o'tib proxy sozlashimiz mumkin.
HTTP Proxy uchun Enable HTTP Proxy
ni belgilaymiz va HTTP Proxy Host
ga proxy serverimiz addresi va HTTP Proxy Port
ga portni kiritamiz.
HTTPS Proxy uchun Enable HTTPS Proxy
ni belgilaymiz va HTTPS Proxy Host
ga proxy serverimiz addresi va HTTPS Proxy Port
ga portni kiritamiz. Agar sizning proxyyingiz HTTPS Authenticationni talab qilinsa Enable HTTPS Proxy Authentication
ni belgilaymiz va HTTPS Proxy Username
va HTTPS Proxy Password
ni kiritib ishlatishimiz mumkin.
Nexus servergfa proxy sozlamalarini sozlagandan keyin proxysiz ulanadigan local sercvicelarimizga NO Proxy Hosts qismida yozishimiz mumkin.
Repositorylar bilan ishlash
Sonatype Nexus Repository Manager repositoriyalarni tashkil qilish va boshqarish uchun turli xil turlarni(repo type) qo'llab-quvvatlaydi, ulardan eng asosiylari Proxy, Hosted va Group repositoriyalaridir.
Proxy typedagi repositoriya - tashqi (remote) repositoriyalarni mahalliy (local) server orqali kechlashtirish (cache) va ulardan foydalanishni optimallashtirish uchun ishlatiladi. U Maven Central, NuGet Gallery, Docker Hub, NPM Registry, PyPi va boshqa repositoriyalardan paketlarni olish uchun qo'llaniladi. Bu turdagi repositoriyaning asosiy maqsadi internetga chiqishni kamaytirish va local serverda paketlarni saqlashdir, loyihamiz nexusga ulanganidan keyin u paketlarni yuklab olish uchun birinchi bo'lib nexusga so'rov yuboradi agar loyiha so'ragan package nexus local repositoriyada bo'lmasa Proxy typedagi repositoriya berilgan remote repositorydan oladi va nexus local repositoriyada cache qilib saqlaydi.
Hosted typedagi repository - lokal serverda paketlarni saqlash uchun ishlatiladi. U Maven, NuGet, Docker, PyPi va boshqa paketlarni saqlash uchun ishlatiladi. Bu turdagi repositorylar loyihalarga xizmat qilish uchun ishlatiladi, loyiha paketlarini yuklash uchun ishlatiladi. Bu turdagi repositoriyaning asosiy maqsadi Kompaniya uchun maxsus yozilgan packagelar uchun local repository bo'lib xizmat qiladi.
Group repository - bu bir nechta repositoriyalarni bitta umumiy repositoriya sifatida boshqarish imkonini beruvchi repository turi. Group repository bir vaqtning o'zida Proxy, Hosted va boshqa repositoriyalarni bitta URL orqali boshqarishga yordam beradi. Bu turdagi repositoriya ishlatishga bitta misol: maslan sizda maven-central, maven-releases, maven-snapshots repositorylar mavjud bo'lsa siz ularni bitta maven-public repositoryda birlashtirib qo'yishingiz mumkin va loyihalarga bitta URL orqali boshqarish imkonini beradi, yani siz loyihangizni Nexusga ulaganingizda bitta maven-public repositoriyani belgilab ishlatishingiz mumkin uching ichida esa maven-central, maven-releases, maven-snapshots repositorylar mavjud bo'ladi.
Nexusda default holda Maven va Nuget uchun Proxy, Hosted va Group repositorylar mavjud bo'ladi, Python, Go, Docker, Cargo va boshqalar uchun o'zingiz repositoriyalar yaratishingiz kerak bo'ladi.
-> Server Administration and Configuration bo'limidan -> Repositories bo'limiga o'tib repositoriyalarni ko'rishimiz mumkin. Nexus default repositoriyalar. Keling masalan maven-central repositoryni ko'rib chiqamiz. Bu repositoriya turi Proxy bo'lib internetdan https://repo1.maven.org/maven2/ (opens in a new tab) manzilidan ma'lumotlarni olish uchun ishlatiladi. Quyidagi rasmda maven packagelarni qaysi global repositoriyadan olishini ko'rishimiz mumkin https://repo1.maven.org/maven2/ (opens in a new tab).
maven-public repositoriya group repositoriya bo'lib maven-central, maven-releases, maven-snapshots repositoriyalarini birlashtirgan repositoriya bo'lib, bu repositoriyadan maven packagelarni olishimiz mumkin. Bu rasmda maven-public repositoriyamiz o'z ichiga olgan maven-central, maven-releases, maven-snapshots repositoriyalarini ko'rishimiz mumkin. nuget-group repository ham group repository bo'lib nuget-hosted, nuget.org-proxy repositorylarini birlashtirgan repositoriya bo'lib, bu repositoriyadan nuget packagelarni yani .NET packagelarni olishimiz mumkin. nuget.org-proxy repositoriya proxy repositoriya bo'lib https://api.nuget.org/v3/index.json (opens in a new tab) addresidan nuget packagelarni olish uchun ishlatiladi.
Nexus Integratsiyasi
Bu bosqichda Maven va NuGet loyihalarini Sonatype Nexus Repository Manager bilan integratsiya qilish va shuningdek, CI/CDga qo'shishni ko'rib chiqamiz. Bu bilan biz Nexus'ni ishlatish orqali build vaqtlarini qisqartirish, paketlarni local boshqarish va xavfsizlikni oshirish imkoniyatiga ega bo'lamiz.
Java Maven
Platformamizda Java Spring Boot Deployment: Gitlab CI va Github Actions (opens in a new tab) amaliyotida biz Spring Boot Maven projectni GItlab CI va Github Actyions bilan CI/CD yozib ishga tushirishni ko'rib chiqgandik endi bu bosqichda unga nexus inetgratsiyani ko'rib chiqamiz.
Ushbu bo'limda ishlatiladigan loyihalar:
1-> Loyihangizda pom.xml
faylga quyidagicha dependencyni qo'shib qo'yamiz.
<repositories>
<repository>
<id>nexus</id>
<url>https://nexus.helm.uz/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>nexus</id>
<url>https://nexus.helm.uz/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<repositories>
bo'limi Mavenga Nexusdagi dependencylarni yuklab olish uchun qayerga murojaat qilish kerakligini bildiradi. <id>
- Repositoriyani identifikatsiya qilish uchun unikal nom (nexus deb belgilangan) <url>
- Nexus repositoriyaning manzili (https://nexus.helm.uz/repository/maven-public/ (opens in a new tab)). <releases>
- Release versiyalarning yuklab olinishi yoqilgan (true). <snapshots>
- Snapshot versiyalar ham qollab-quvvatlanishi yoqilgan (true).
<pluginRepositories>
Maven pluginlarini Nexus repositoriyadan yuklash uchun ishlatiladi. Bu Maven build va test jarayonlari uchun zarur bo'lgan plaginlarni Nexus orqali yuklashni taminlaydi. Agar loyiha Maven pluginlari uchun Nexusdan foydalanmoqchi bo'lsa, ushbu bo'lim kiritilishi shart.
2-> Loyihangizda settings.xml
faylga quyidagicha sozlamalarni qo'shib qo'yamiz.
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd">
<servers>
<server>
<id>nexus</id>
<username>${env.NEXUS_USER}</username>
<password>${env.NEXUS_PASSWORD}</password>
</server>
</servers>
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>https://nexus.helm.uz/repository/maven-public/</url>
<layout>default</layout>
</mirror>
</mirrors>
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>nexus</id>
<url>https://nexus.helm.uz/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
</settings>
<servers>
bo'limi Autentifikatsiya konfiglarini o'z ichiga oladi. <id>
- pom.xml
dagi repository ID bilan bir xil bo'lishi kerak (nexus). <username>
va <password>
- Nexusga kirish uchun foydalanuvchi nomi va parol. Nexusga kirish uchun login va parol environment variable sifatida yozilgan ${env.NEXUS_USER}
va ${env.NEXUS_PASSWORD}
.
Bu konfiguratsiya Nexusga artifaktlarni yuklash (mvn deploy
) yoki yuklab olish (mvn install
) uchun autentifikatsiyani ta'minlaydi.
<mirrorOf>*</mirrorOf>
- Barcha (*) repositoriyalar uchun Nexusni o'zgartirilgan mirror sifatida ishlatishni bildiradi. <url>
- Nexus'ning maven-public repositoriyasi orqali barcha dependencylarni yuklash bildiradi. <layout>
esa default Maven repository arxitekturasi ishlatiladi. Bu bo'lim Maven Central yoki boshqa tashqi repositoriyalarni bevosita ishlatish o'rniga, ularni Nexus orqali yuklab olishni ta'minlaydi.
<profiles>
bo'limi turli xil konfiguratsiyalarni yaratish va ishlatish imkonini beradi, bunda biz <id>
nexus nomli profil yaratib olamiz va <repositories>
bu Maven repositoriyalarini yaratish uchun ishlatiladi, unga biz Nexus repositoriya urlni qo'shib qo'yamiz va <activeProfiles>
bo'limida nexusni profilni faollashtiramiz, shunda mvn buyruqlari bajarilganda, Maven ushbu profilni ishlatadi, nexus profili faollashtirilganda, Maven dependencylarni https://nexus.helm.uz/repository/maven-public/ (opens in a new tab) orqali yuklaydi.
3-> ${env.NEXUS_USER}
va ${env.NEXUS_PASSWORD}
environment variablelarni agar sizda Gitlab bo'lsa Gitlab CI/CD variablesga yoki Githubda bo'lsa Github Secretsga qo'shib qo'yishimiz kerak bo'ladi.
Gitlabda Settings -> CI/CD -> Variables bo'limiga o'tib quyidagicha variablelarni qo'shib qo'yamiz.
NEXUS_USER
- Nexusga kirish uchun foydalanuvchi nomi.
NEXUS_PASSWORD
- Nexusga kirish uchun foydalanuvchi paroli.
Githubda esa Settings -> Secrets -> New repository secret bo'limiga o'tib quyidagicha secretlarni qo'shib qo'yamiz.
NEXUS_USER
- Nexusga kirish uchun foydalanuvchi nomi.
NEXUS_PASSWORD
- Nexusga kirish uchun foydalanuvchi paroli.
4-> Maven loyihani settings.xml
bilan ishga tushirish uchun Dockerfileni ham yangilashimiz kerak bo'ladi.
COPY settings.xml /root/.m2/settings.xml
qatorini Dockerfilega qo'shib qo'yamiz.
FROM maven:3.9.5-eclipse-temurin-17-alpine AS builder
WORKDIR /app
COPY settings.xml /root/.m2/settings.xml
COPY pom.xml .
RUN mvn dependency:go-offline -B
COPY src ./src
RUN mvn package -DskipTests -B
FROM eclipse-temurin:17-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
RUN chown -R appuser:appgroup /app
USER appuser
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD wget --spider --quiet http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["java", "-jar", "app.jar"]
5-> Loyihamiz CI/CD'sida ham o'zgarishlar kiritishimiz kerak bo'ladi.
Gitlab CI uchun before_script
bo'limiga quyidagicha yangilamymiz bu qatorlar sed
yordamida settings.xml
faylga NEXUS_USER
va NEXUS_PASSWORD
environment variablelarni yozadi.
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
- sed -i "s|\${env.NEXUS_USER}|${NEXUS_USER}|g" settings.xml
- sed -i "s|\${env.NEXUS_PASSWORD}|${NEXUS_PASSWORD}|g" settings.xml
To'liq Gitlab CI .gitlab-ci.yml
fayli quyidagicha ko'rinishda bo'ladi.
stages:
- build_and_push
- deploy
variables:
IMAGE_NAME: waifulist
CONTAINER_NAME: waifulist
PORT: "8080:8080"
REPO_NAME: $CI_PROJECT_PATH
REGISTRY: "registry.gitlab.com"
SSH_HOST: $SERVER_IP
SSH_USER: $SERVER_USERNAME
SSH_KEY: $SSH_PRIVATE_KEY
SPRING_PROFILES_ACTIVE: dev
DEV_DATABASE_URL: $DEV_DATABASE_URL
DEV_DATABASE_USERNAME: $DEV_DATABASE_USERNAME
DEV_DATABASE_PASSWORD: $DEV_DATABASE_PASSWORD
build_and_push:
stage: build_and_push
image: docker:stable
services:
- docker:dind
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
- sed -i "s|\${env.NEXUS_USER}|${NEXUS_USER}|g" settings.xml
- sed -i "s|\${env.NEXUS_PASSWORD}|${NEXUS_PASSWORD}|g" settings.xml
script:
- docker build -t "$REGISTRY/$REPO_NAME/$IMAGE_NAME:$CI_COMMIT_SHA" .
- docker push "$REGISTRY/$REPO_NAME/$IMAGE_NAME:$CI_COMMIT_SHA"
deploy:
stage: deploy
image: alpine:latest
before_script:
- apk add --update --no-cache openssh-client
script:
- mkdir -p ~/.ssh
- echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- ssh-keyscan -H $SSH_HOST >> ~/.ssh/known_hosts
- ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST "echo "$CI_JOB_TOKEN" | docker login -u gitlab-ci-token --password-stdin $CI_REGISTRY"
- ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST "docker pull $REGISTRY/$REPO_NAME/$IMAGE_NAME:$CI_COMMIT_SHA"
- ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST "docker stop $CONTAINER_NAME || true"
- ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST "docker rm $CONTAINER_NAME || true"
- ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no "$SSH_USER@$SSH_HOST" "docker run -d --name $CONTAINER_NAME --restart=always -p $PORT -e SPRING_PROFILES_ACTIVE=$SPRING_PROFILES_ACTIVE -e DEV_DATABASE_URL=$DEV_DATABASE_URL -e DEV_DATABASE_USERNAME=$DEV_DATABASE_USERNAME -e DEV_DATABASE_PASSWORD=$DEV_DATABASE_PASSWORD $REGISTRY/$REPO_NAME/$IMAGE_NAME:$CI_COMMIT_SHA"
Github Actions uchun.
- name: Replace Nexus Credentials in settings.xml
run: |
sed -i "s|\${env.NEXUS_USER}|${{ secrets.NEXUS_USER }}|g" settings.xml
sed -i "s|\${env.NEXUS_PASSWORD}|${{ secrets.NEXUS_PASSWORD }}|g" settings.xml
To'liq Github Actions .github/workflows/main.yml
fayli quyidagicha ko'rinishda bo'ladi.
name: Github Actions CI/CD
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
REPO_NAME: ${{ github.repository }}
CONTAINER_NAME: waifulist
REGISTRY: ghcr.io
SSH_HOST: ${{ secrets.SERVER_IP }}
SSH_USER: ${{ secrets.SERVER_USERNAME }}
SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
PORT: 8080:8080
SPRING_PROFILES_ACTIVE: dev
jobs:
build_and_push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Replace Nexus Credentials in settings.xml
run: |
sed -i "s|\${env.NEXUS_USER}|${{ secrets.NEXUS_USER }}|g" settings.xml
sed -i "s|\${env.NEXUS_PASSWORD}|${{ secrets.NEXUS_PASSWORD }}|g" settings.xml
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: "${{ env.REGISTRY }}/${{ env.REPO_NAME }}:${{ github.sha }}"
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.REPO_NAME }}:buildcache
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.REPO_NAME }}:buildcache,mode=max
deploy:
needs: build_and_push
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Executing remote SSH commands to deploy
uses: appleboy/ssh-action@master
with:
host: "${{ env.SSH_HOST }}"
username: "${{ env.SSH_USER }}"
key: "${{ env.SSH_KEY }}"
script: |
echo ${{ secrets.GITHUB_TOKEN }} | docker login -u ${{ github.actor }} --password-stdin ${{ env.REGISTRY }}
docker pull "${{ env.REGISTRY }}/${{ env.REPO_NAME }}:${{ github.sha }}"
docker stop "${{ env.CONTAINER_NAME }}" || true
docker rm "${{ env.CONTAINER_NAME }}" || true
docker run -d --name ${{ env.CONTAINER_NAME }} --restart=always -p ${{ env.PORT }} \
-e SPRING_PROFILES_ACTIVE=${{ env.SPRING_PROFILES_ACTIVE }} \
-e DEV_DATABASE_URL=${{ secrets.DEV_DATABASE_URL }} \
-e DEV_DATABASE_USERNAME=${{ secrets.DEV_DATABASE_USERNAME }} \
-e DEV_DATABASE_PASSWORD=${{ secrets.DEV_DATABASE_PASSWORD }} \
${{ env.REGISTRY }}/${{ env.REPO_NAME }}:${{ github.sha }}
6-> Keling endi loyiha CI/CD orqali ishga tushirib uni tekshirib ko'ramiz, loyihamiz barcha package va dependencylarni Nexus orqali yuklab olishi kerak.
Gitlab CI'da ko'rib turganinigizdek barcha package va dependencylarni nexus.helm.uz/repository/maven-public/ manzili orqali yuklab olyapti. Github Actionsda
Nexusga brazuerdan kirib ko'rganimizda ham o'zgarishlarni sezishimiz mumkin.
Nexusdan maven-central repositoryni ko'rib chiqadigan bo'lsak nexus o'zida saqlayotgan local package va dependencylarni ko'rishimiz mumkin.
.NET NuGet
.NET Core loyihalarida Sonatype Nexus Repository Manager bilan integratsiya qilish uchun quyidagicha bosqichlarni bajaramiz. NuGet - bu .NET loyihalari uchun paket menejeri bo'lib, u turli librarylar va tollarni boshqarish uchun ishlatiladi. NuGet.Config
fayli NuGet paketlarini Nexus'ga yo'naltirish, hamda autentifikatsiya ma'lumotlarini kiritish uchun ishlatiladi.
Ushbu bo'limda Github Actions CI/CD (opens in a new tab) amaliyotida ishlatilgan https://github.com/devops-journey-uz/devops-journey-github-actions (opens in a new tab) .NET Core applicationini ishlatamiz, bunga oldin biz Github Actions bilan CI/CD yozib ishga tushirishni ko'rib chiqgandik endi bu bosqichda unga nexus inetgratsiyani ko'rib chiqamiz.
Ushbu bo'limda ishlatiladigan loyihalar:
1-> Loyihamizda NuGet.Config
faylini yaratamiz va quyidagicha configuratsiya qilamiz.
<configuration>
<packageSources>
<clear />
<add key="Nexus" value="https://nexus.helm.uz/repository/nuget-group/index.json" />
</packageSources>
<packageSourceCredentials>
<Nexus>
<add key="Username" value="__NEXUS_USER__" />
<add key="ClearTextPassword" value="__NEXUS_PASSWORD__" />
</Nexus>
</packageSourceCredentials>
</configuration>
Konfiguratsiyada packageSources
- NuGet paket manbalarini aniqlash uchun ishlatiladi. <clear />
avvalgi NuGet manbalarini tozalaydi va faqat biz bergan nexus manbadan foydalanadi. <add key="Nexus" value="https://nexus.helm.uz/repository/nuget-group/index.json" />
Nexus nomli yangi NuGet repositoriya qo'shiladi url esa nuget packagelarni yuklab olish uchun berilgan nexus repositoriya manzili. packageSourceCredentials
Autentifikatsiya ma'lumotlarini o'z ichiga oladi. Bu yerdagi __NEXUS_USER__
va __NEXUS_PASSWORD__
o'zgaruvchilar Gitlab CI variable yoki Github Secretsga qo'shib ishlatiladi.
2-> __NEXUS_USER__
va __NEXUS_PASSWORD__
environment variablelarni agar sizda Gitlab bo'lsa Gitlab CI/CD variablesga yoki Githubda bo'lsa Github Secretsga qo'shib qo'yishimiz kerak bo'ladi.
Gitlabda Settings -> CI/CD -> Variables bo'limiga o'tib quyidagicha variablelarni qo'shib qo'yamiz.
NEXUS_USER
- Nexusga kirish uchun foydalanuvchi nomi.
NEXUS_PASSWORD
- Nexusga kirish uchun foydalanuvchi paroli.
Githubda esa Settings -> Secrets -> New repository secret bo'limiga o'tib quyidagicha secretlarni qo'shib qo'yamiz.
NEXUS_USER
- Nexusga kirish uchun foydalanuvchi nomi.
NEXUS_PASSWORD
- Nexusga kirish uchun foydalanuvchi paroli.
3-> Dockerfile faylini quyidagicha yangilaymiz.
COPY NuGet.Config /root/.nuget/NuGet/NuGet.Config
qatorini Dockerfilega qo'shib qo'yamiz.
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env
WORKDIR /app
COPY NuGet.Config /root/.nuget/NuGet/NuGet.Config
COPY . .
WORKDIR "/app/GitHub.Actions.API"
RUN dotnet publish "GitHub.Actions.API.csproj" -o /app/build -c Release
FROM mcr.microsoft.com/dotnet/aspnet:7.0
WORKDIR /app
ENV ASPNETCORE_ENVIRONMENT=Development
ENV TZ="Asia/Tashkent"
COPY --from=build-env /app/build .
ENTRYPOINT ["dotnet", "GitHub.Actions.API.dll", "--urls=http://0.0.0.0:4001"]
4-> Loyihamiz CI/CD'sida ham o'zgarishlar kiritishimiz kerak bo'ladi.
Gitlab CI uchun before_script
bo'limiga quyidagicha yangilamymiz bu qatorlar sed
yordamida NuGet.Config
faylga NEXUS_USER
va NEXUS_PASSWORD
environment variablelarni yozadi.
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- sed -i 's|__NEXUS_USER__|'"$NEXUS_USER"'|g' NuGet.Config
- sed -i 's|__NEXUS_PASSWORD__|'"$NEXUS_PASSWORD"'|g' NuGet.Config
To'liq Gitlab CI .gitlab-ci.yml
fayli quyidagicha ko'rinishda bo'ladi.
stages:
- build_and_push
- deploy
variables:
API_IMAGE_NAME: github-api
API_CONTAINER_NAME: github-api
UI_IMAGE_NAME: github-ui
UI_CONTAINER_NAME: github-ui
UI_PORT: "4000:4000"
API_PORT: "4001:4001"
REPO_NAME: $CI_PROJECT_PATH
REGISTRY: "registry.gitlab.com"
SSH_HOST: $SERVER_IP
SSH_USER: $SERVER_USERNAME
SSH_KEY: $SSH_PRIVATE_KEY
build_and_push:
stage: build_and_push
image: docker:stable
services:
- docker:dind
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- sed -i 's|__NEXUS_USER__|'"$NEXUS_USER"'|g' NuGet.Config
- sed -i 's|__NEXUS_PASSWORD__|'"$NEXUS_PASSWORD"'|g' NuGet.Config
script:
- docker build -t $REGISTRY/$REPO_NAME/$API_IMAGE_NAME:$CI_COMMIT_SHA -f ./API.Dockerfile .
- docker push $REGISTRY/$REPO_NAME/$API_IMAGE_NAME:$CI_COMMIT_SHA
- docker build -t $REGISTRY/$REPO_NAME/$UI_IMAGE_NAME:$CI_COMMIT_SHA -f ./UI.Dockerfile .
- docker push $REGISTRY/$REPO_NAME/$UI_IMAGE_NAME:$CI_COMMIT_SHA
deploy:
stage: deploy
image: alpine:latest
before_script:
- apk add --update --no-cache openssh-client
script:
- mkdir -p ~/.ssh
- echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- ssh-keyscan -H $SSH_HOST >> ~/.ssh/known_hosts
- ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST "echo "$CI_JOB_TOKEN" | docker login -u gitlab-ci-token --password-stdin $CI_REGISTRY"
- ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST "docker pull $REGISTRY/$REPO_NAME/$API_IMAGE_NAME:$CI_COMMIT_SHA"
- ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST "docker pull $REGISTRY/$REPO_NAME/$UI_IMAGE_NAME:$CI_COMMIT_SHA"
- ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST "docker stop $UI_CONTAINER_NAME || true"
- ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST "docker stop $API_CONTAINER_NAME || true"
- ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST "docker rm $UI_CONTAINER_NAME || true"
- ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST "docker rm $API_CONTAINER_NAME || true"
- ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST "docker run -d --name $API_CONTAINER_NAME --restart=always -p $API_PORT $REGISTRY/$REPO_NAME/$API_IMAGE_NAME:$CI_COMMIT_SHA"
- ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST "docker run -d --name $UI_CONTAINER_NAME --restart=always -p $UI_PORT $REGISTRY/$REPO_NAME/$UI_IMAGE_NAME:$CI_COMMIT_SHA"
Github Actions .github/workflows/ci-cd.yml
faylini quyidagicha yangilaymiz.
- name: Replace Nexus Credentials in NuGet.Config
run: |
sed -i "s|__NEXUS_USER__|${{ secrets.NEXUS_USER }}|g" NuGet.Config
sed -i "s|__NEXUS_PASSWORD__|${{ secrets.NEXUS_PASSWORD }}|g" NuGet.Config
To'liq Github Actions .github/workflows/ci-cd.yml
fayli quyidagicha ko'rinishda bo'ladi.
name: Docker CI/CD
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
API_IMAGE_NAME: github-api
API_CONTAINER_NAME: github-api
UI_IMAGE_NAME: github-ui
UI_CONTAINER_NAME: github-ui
UI_PORT: 4000:4000
API_PORT: 4001:4001
REPO_NAME: ${{ github.repository }}
REGISTRY: ghcr.io
SSH_HOST: ${{ secrets.SERVER_IP }}
SSH_USER: ${{ secrets.SERVER_USERNAME }}
SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
jobs:
build_and_push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Replace Nexus Credentials in NuGet.Config
run: |
sed -i "s|__NEXUS_USER__|${{ secrets.NEXUS_USER }}|g" NuGet.Config
sed -i "s|__NEXUS_PASSWORD__|${{ secrets.NEXUS_PASSWORD }}|g" NuGet.Config
- name: Build and push API Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./API.Dockerfile
push: true
tags: ${{ env.REGISTRY }}/${{ env.REPO_NAME}}/${{ env.API_IMAGE_NAME }}:${{ github.sha }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.REPO_NAME}}/${{ env.API_IMAGE_NAME }}:buildcache
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.REPO_NAME}}/${{ env.API_IMAGE_NAME }}:buildcache,mode=max
- name: Build and push UI Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./UI.Dockerfile
push: true
tags: ${{ env.REGISTRY }}/${{ env.REPO_NAME}}/${{ env.UI_IMAGE_NAME }}:${{ github.sha }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.REPO_NAME}}/${{ env.UI_IMAGE_NAME }}:buildcache
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.REPO_NAME}}/${{ env.UI_IMAGE_NAME }}:buildcache,mode=max
deploy:
needs: build_and_push
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Executing remote SSH commands to deploy
uses: appleboy/ssh-action@master
with:
host: "${{ env.SSH_HOST }}"
username: "${{ env.SSH_USER }}"
key: "${{ env.SSH_KEY }}"
script: |
echo ${{ secrets.GITHUB_TOKEN }} | docker login -u ${{ github.actor }} --password-stdin ${{ env.REGISTRY }}
docker pull "${{ env.REGISTRY }}/${{ env.REPO_NAME}}/${{ env.API_IMAGE_NAME }}:${{ github.sha }}"
docker pull "${{ env.REGISTRY }}/${{ env.REPO_NAME}}/${{ env.UI_IMAGE_NAME }}:${{ github.sha }}"
docker stop "${{ env.UI_CONTAINER_NAME }}" || true
docker stop "${{ env.API_CONTAINER_NAME }}" || true
docker rm "${{ env.UI_CONTAINER_NAME }}" || true
docker rm "${{ env.API_CONTAINER_NAME }}" || true
docker run -d --name "${{ env.API_CONTAINER_NAME }}" --restart=always -p "${{ env.API_PORT }}" "${{ env.REGISTRY }}/${{ env.REPO_NAME}}/${{ env.API_IMAGE_NAME }}:${{ github.sha }}"
docker run -d --name "${{ env.UI_CONTAINER_NAME }}" --restart=always -p "${{ env.UI_PORT }}" "${{ env.REGISTRY }}/${{ env.REPO_NAME}}/${{ env.UI_IMAGE_NAME }}:${{ github.sha }}"
5-> Keling endi loyihani CI/CD orqali ishga tushirib uni tekshirib ko'ramiz, loyihamiz barcha package va dependencylarni Nexus orqali yuklab olishi kerak.
Ko'rib turganingizdek Github Actions CI/CD muvaffaqiyatli yakunlangan.
Nexusga brazuerdan kirib ko'rganimizda ham o'zgarishlarni sezishimiz mumkin.
Nexusdan nuget-group repositoriyani ko'rib chiqadigan bo'lsak nexus o'zida saqlayotgan local package va dependencylarni ko'rishimiz mumkin.
Nihoyat biz bugungi Sonatype Nexus Repository Manager bilan bo'lgan amaliyotimizni shu yerda yakunlaymiz, o'ylaymanku bu sizga foydali bo'ldi. Agar sizda savollar yoki takliflar bo'lsa, ularni shu post izohlariga yozishingiz mumkin. Qolgan PyPI, Docker, Go, Cargo va boshqa package repositoriyalarni sozlashni o'zingiz davom ettirasiz ))
Qo'shimcha
Qo'shimcha Resurslar
- Java Spring Boot Deployment: Gitlab CI va Github Actions (opens in a new tab)
- Gitlab Server o'rnatish va sozlash (opens in a new tab)
- Gitlab CI | Releaselar va Integrationlar (opens in a new tab)
- Github Actions bilan Flutter CI/CD (opens in a new tab)
- Github Actions CI/CD (opens in a new tab)
- Linux Serverlarga Jenkins o'rnatish (opens in a new tab)
- Koddan Servergacha: Jenkins bilan Docker CI/CD va Discord bilan integratsiya (opens in a new tab)
- Kubernetes CI/CD | GitHub Actions + Argo CD | GitOps (opens in a new tab)
Sana: 2025.02.08(2025-yil 8-fevral)
Oxirgi yangilanish: 2025.02.08(2025-yil 8-fevral)
Muallif: Otabek Ismoilov
Telegram (opens in a new tab) | GitHub (opens in a new tab) | LinkedIn (opens in a new tab) |
---|