Selamlar arkadalaşlar,
Karantidayken ne yapsam diye düşünürken birden aklıma github‘un yayınlamış olduğu ci/cd çözümü olan Github Actions ‘u denemek geldi.
Bu çalışmada senaryomuz ise şöyle; basit bir asp.net core web projesi oluşturup bunu github‘a yükleyeceğiz ardından her atılan her commit‘te yeni bir docker imajı oluşturup bu yeni imajı sunucumuza deploy edeceğiz.
Çalışmayı yapabilmek için visual studio ile bir asp.net core web projesi oluşturup github repository’ime yükledim.
Ardından projede kullanacağım dockerfile‘ı ana dizine ekleyip projeyle alakalı dosyaları ise src altında bir dizine taşıdım.
Burda önemli olan nokta ise kullandığımız sln dosyası ile dockerfile‘ın kök dizinde olması gerekliliği. Bunu sağlayabilmek için sln dosyasındaki “Project(“{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}”) = “WebApplication1”, “WebApplication1\WebApplication1.csproj”, “{0311290B-BE99-4D8F-8D9C-A125FFCAA0DA}” satırını “Project(“{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}”) = “WebApplication1”, “src\WebApplication1.csproj”, “{0311290B-BE99-4D8F-8D9C-A125FFCAA0DA}” olarak güncelliyorum ve sln dosyasını kök dizine atıyorum.
Kullandığm dockerfile‘ın içeriği ise şöyledir (Kopyalamak için buraya kullanın: https://github.com/ismkdc/github-actions-example/blob/master/dockerfile):
FROM mcr.microsoft.com/dotnet/core/sdk:3.1.201-alpine AS build-env WORKDIR /app COPY . . RUN dotnet restore RUN dotnet build -c Release -o /out RUN dotnet publish -c Release -o /out # Runtime image FROM mcr.microsoft.com/dotnet/core/aspnet:3.1.3-alpine WORKDIR /app COPY --from=build-env /out . ENTRYPOINT ["dotnet", "WebApplication1.dll"]
Şimdi ise sıra geldi Github Action‘uzumu hazırlamaya:

name: Publish Docker on: push: branches: - master jobs: build: runs-on: ubuntu-latest steps: - uses: actions/[email protected] - name: Publish to Registry uses: elgohr/[email protected] with: name: ismkdc/github-actions-example username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} snapshot: true release: needs: build runs-on: ubuntu-latest steps: - name: executing remote ssh commands using password uses: appleboy/[email protected] with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USERNAME }} password: ${{ secrets.SSH_PASSWORD }} port: ${{ secrets.SSH_PORT }} script: | docker rm -f $(docker ps -aq -f name=github-actions-example) docker rmi $(docker images | grep 'ismkdc/github-actions-example' | awk '{print $3}') docker pull ismkdc/github-actions-example:dev docker run --name github-actions-example -p 5000:80 --restart=always -d ismkdc/github-actions-example
Oluşturduğumuz bu Actionu kısaca açıklamak gerekirse; Action, build adımında projemizi build edip bir docker imajı oluşturuyor ve bu oluşan imajı docker registry‘e push ediyor. Ardından sunucumuza ssh ile bağlanıp güncel imajı indirip bu imajdan bir container ayağa kaldırıyor. Burda dikkat edilmesi gereken nokta bu yaml içerisinde tanımlı değişkenleri repository‘imze tanımlamamız.
Repository‘e değişkenleri tanımlamak için repository içerisindeki Settings menüsü altından sol taraftaki Secrets menüsünü kullanmamız gerekiyor. Bu menüye girdikten sonra tanımlamamız gereken toplam 6 adet değişken mevcut. Bunlardan 2’si docker hub için diğer 4’ü ise ssh için gerekli.
Sırasıyla açıklamak gerekirse;
DOCKER_USERNAME: docker hub üzerindeki kullanıcı adımız.
DOCKER_PASSWORD: docker hub üzerindeki Access Tokenimiz (Token almak için: https://hub.docker.com/settings/security)
SSH_HOST: bağlanacağımız sunucunun ip adresi
SSH_USERNAME: bağlanacağımız sunucudaki kullanıcı adımız
SSH_PASSWORD: bağlanacağımız sunucudaki parolamız
SSH_PORT: bağlanacağımız sunucunun ssh portu (default 22)
Hepsini oluşturduktan sonra yukarıdaki gibi bir tabloyla karşılaşmamız gerekiyor.
Burada dikkat etmeniz gereken diğer bir durum ise ssh ile bağlantı yapacak kullacının yetkilerinin sadece docker kullanabilecek şekilde sınırlandırılmış olması gerektiğidir.
Herşeyi tamamladıktan sonra artık pipeline‘ımızı deneyebiliriz.
Commit‘imizi attıktan sonra otomatik deployment için bekleyemeye başlıyoruz. Bu bekleme esnasında Actions tab’i altında pipeline‘ımızın ilerleme durumunu kontrol edebiliriz.
Vee.. Uygulamamız yayında!
Artık atılan her commit için uygulamamız pipeline tarafından otomatik olarak deploy ediliyor olmuş oldu. Tabi bazı durumlarda her commit yayına gitsin istemeyiz bu tür durumlarda master yerine başka bir branch‘i işaretleyerek sadece ilgili branch‘e giden kodlar için pipeline‘ımızın tetiklenmesini sağlamalıyız. Bunun için ise main.yml dosyasındaki branches:- master kısmını ilgili branch ismiye değiştirmemiz yeterlidir.
Artı olarak yine prod env için bu pipeline üzerine yazılmış olan testlerin çalıştırılıp eğer testlerin hepsi geçmezse pipeline‘ın fail etmesi durumunu eklememiz gerekir.
Çalışmanın son hali: https://github.com/ismkdc/github-actions-example