Series navigation and source code
Requirements and objectives
In the last section of this series, we will use GitHub Actions to deploy TodoList application to Azure Container Instance.
realization
To ensure that the deployed applications can run correctly, we need to do the following:
Create Azure SQL Server instance
Just select the cheapest Database specification. Create a new resource group named todolist, and create a new database instance to obtain the connection string:
Create Azure Container Registry
Used for uploading and deploying built images
Set GitHub Secrets
First create the Service Principle authentication:
groupId=$(az group show \ --name todolist \ --query id --output tsv) az ad sp create-for-rbac \ --scope $groupId \ --role Contributor \ --sdk-auth # You will get output similar to the following { "clientId": "xxxx6ddc-xxxx-xxxx-xxx-ef78a99dxxxx", "clientSecret": "xxxx79dc-xxxx-xxxx-xxxx-aaaaaec5xxxx", "subscriptionId": "xxxx251c-xxxx-xxxx-xxxx-bf99a306xxxx", "tenantId": "xxxx88bf-xxxx-xxxx-xxxx-2d7cd011xxxx", "activeDirectoryEndpointUrl": "https://login.microsoftonline.com", "resourceManagerEndpointUrl": "https://management.azure.com/", "activeDirectoryGraphResourceId": "https://graph.windows.net/", "sqlManagementEndpointUrl": "https://management.core.windows.net:8443/", "galleryEndpointUrl": "https://gallery.azure.com/", "managementEndpointUrl": "https://management.core.windows.net/" }
Next, update the authentication of Registry
registryId=$(az acr show \ --name code4nothing \ --query id --output tsv) az role assignment create \ --assignee <ClientId> \ --scope $registryId \ --role AcrPush
Finally, configure Secrets into Github Repo settings:
For detailed parameter description, please refer to: Save credentials to GitHub repo
Create Actions configuration
In Github's Repo, select Actions and set up a workflow yourself
Define the following build steps:
on: [push] name: Linux_Container_Workflow jobs: build-and-deploy: runs-on: ubuntu-latest steps: # checkout the repo - name: 'Checkout GitHub Action' uses: actions/checkout@main - name: 'Login via Azure CLI' uses: azure/login@v1 with: creds: ${{ secrets.AZURE_CREDENTIALS }} - name: 'Build and push image' uses: azure/docker-login@v1 with: login-server: ${{ secrets.REGISTRY_LOGIN_SERVER }} username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} - run: | docker build -f src/TodoList.Api/Dockerfile.prod . -t ${{ secrets.REGISTRY_LOGIN_SERVER }}/todolist:${{ github.sha }} docker push ${{ secrets.REGISTRY_LOGIN_SERVER }}/todolist:${{ github.sha }} - name: 'Deploy to Azure Container Instances' uses: 'azure/aci-deploy@v1' with: resource-group: ${{ secrets.RESOURCE_GROUP }} dns-name-label: ${{ secrets.RESOURCE_GROUP }}${{ github.run_number }} image: ${{ secrets.REGISTRY_LOGIN_SERVER }}/todolist:${{ github.sha }} registry-login-server: ${{ secrets.REGISTRY_LOGIN_SERVER }} registry-username: ${{ secrets.REGISTRY_USERNAME }} registry-password: ${{ secrets.REGISTRY_PASSWORD }} name: aci-todolist location: 'east asia'
Modify project code for Production deployment
- Dockerfile.prod
ARG NET_IMAGE=6.0-bullseye-slim FROM mcr.microsoft.com/dotnet/aspnet:${NET_IMAGE} AS base WORKDIR /app EXPOSE 80 ENV ASPNETCORE_ENVIRONMENT=Production FROM mcr.microsoft.com/dotnet/sdk:${NET_IMAGE} AS build WORKDIR /src COPY ["src/TodoList.Api/TodoList.Api.csproj", "TodoList.Api/"] COPY ["src/TodoList.Application/TodoList.Application.csproj", "TodoList.Application/"] COPY ["src/TodoList.Domain/TodoList.Domain.csproj", "TodoList.Domain/"] COPY ["src/TodoList.Infrastructure/TodoList.Infrastructure.csproj", "TodoList.Infrastructure/"] RUN dotnet restore "TodoList.Api/TodoList.Api.csproj" COPY ./src . WORKDIR "/src/TodoList.Api" RUN dotnet build "TodoList.Api.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish --no-restore "TodoList.Api.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "TodoList.Api.dll"]
- appsettings.Production.json
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "UseFileToLog": true, "ConnectionStrings": { "SqlServerConnection": "Server=tcp:code4nothing.database.windows.net,1433;Initial Catalog=TodoListDb;Persist Security Info=False;User ID=code4nothing;Password=TestTodo@123;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" } }
After the code is merged into main, Actions will be triggered automatically:
After running the ACI instance, you can see:
verification
Let's access the API port from the local Insomia to see if liveness probes works normally:
The requested host can be obtained here:
After querying TodoList, query TodoItems results:
A little expansion
The new Azure service Azure Container Apps(preview) launched by Microsoft is another option for deployment as a container service. A brief description:
Deploy containerized apps without managing complex infrastructure. Write code using your preferred programming language or framework, and build microservices with full support for Distributed Application Runtime (Dapr). Scale dynamically based on HTTP traffic or events powered by Kubernetes Event-Driven Autoscaling (KEDA).
From official documents Azure Container Apps
summary
If the deployment of ACI fails, especially if the container does not run successfully in ACI, you can refer to: Troubleshoot common issues in Azure Container Instances To view and solve problems.
In this article, we implemented how to deploy applications to Azure Container Instance service through Github Actions. So as of this section, use. NET 6 development TodoList application article index This is used in series NET Web API development foundation series is over. Thank you for your support in this process.
In the writing and publishing of this series, we have also missed several articles that have not been completed for the time being, including several unfinished pits pointed out by some comments. I will try to fill them up in time. But the update speed should not be as dense as when writing this series.
The later plan is to write several small series to familiarize yourself with the knowledge points that may be used later, such as GraphQL, RabbitMQ, gRPC, Envoy and Dapr, before officially starting the series of practice articles on microservices.
Thank you for correcting the mistakes in the article. I hope we can continue to work together and master more skills step by step.