<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
  <channel xmlns:media="http://search.yahoo.com/mrss/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <title>ABP.IO Stories</title>
    <link>https://abp.io/community/articles</link>
    <description>A hub for ABP Framework, .NET, and software development. Access articles, tutorials, news, and contribute to the ABP community.</description>
    <lastBuildDate>Sun, 11 Oct 2026 19:47:59 Z</lastBuildDate>
    <generator>Community - ABP.IO</generator>
    <image>
      <url>https://abp.io/assets/favicon.ico/favicon-32x32.png</url>
      <title>ABP.IO Stories</title>
      <link>https://abp.io/community/articles</link>
    </image>
    <a10:link rel="self" type="application/rss+xml" title="self" href="https://abp.io/community/rss?member=selmankoc" />
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/.net-11-container-publishing-hype-handson-reality-and-the-devops-playbook-kjsc1qoc</guid>
      <link>https://abp.io/community/posts/.net-11-container-publishing-hype-handson-reality-and-the-devops-playbook-kjsc1qoc</link>
      <a10:author>
        <a10:name>selmankoc</a10:name>
        <a10:uri>https://abp.io/community/members/selmankoc</a10:uri>
      </a10:author>
      <category>docker</category>
      <category>deployment</category>
      <category>ci-cd</category>
      <category>dotnet</category>
      <category>containerization</category>
      <title>.NET 11 Container Publishing: Hype, Hands-On Reality, and the DevOps Playbook</title>
      <description>Shipping multi-platform, secure containers without maintaining complex Dockerfiles is the holy grail for platform engineering. With .NET 11 (Release Candidate 1), Microsoft heavily markets its built-in SDK container publishing as the solution. But marketing claims and CI/CD realities often clash.</description>
      <pubDate>Thu, 17 Sep 2026 08:37:28 Z</pubDate>
      <a10:updated>2026-10-11T19:47:14Z</a10:updated>
      <content:encoded><![CDATA[<h1>.NET 11 Container Publishing: Hype, Hands-On Reality, and the DevOps Playbook</h1>
<p>Shipping multi-platform, secure containers without maintaining complex <code>Dockerfile</code>s is the holy grail for platform engineering. With .NET 11 (Release Candidate 1), Microsoft heavily markets its built-in SDK container publishing as the solution. But marketing claims and CI/CD realities often clash.</p>
<p>After running the .NET 11 RC1 SDK through an isolated sandbox environment—testing everything from cross-compilation to rootless runtimes—here is the unvarnished DevOps breakdown of what actually works, what is overhyped, and how you should adapt your pipelines.</p>
<h2>1. SDK-Driven Publishing and the Base Image Reality</h2>
<p>The SDK natively understands your <code>.csproj</code> and generates an OCI-compliant image without a single Dockerfile command. Running a simple publish command works effortlessly:</p>
<pre><code class="language-bash">dotnet publish /t:PublishContainer -p:ContainerRepository=my-registry.local/myapp -p:ContainerImageTag=1.0.0

</code></pre>
<p>The process takes roughly 6 to 11 seconds. However, contrary to the belief that the SDK defaults to &quot;microscopic&quot; secure images, the default base image pulled is the standard Debian-based <code>aspnet:11.0.0-rc.1</code>, resulting in a ~256MB footprint.</p>
<p>To achieve a minimal attack surface, you must explicitly opt into Ubuntu Chiseled images. In .NET 11, the correct chiseled tag family corresponds to Ubuntu 26.04 (Resolute) rather than Ubuntu 24.04 (Noble). If you rely on auto-inference during the preview/RC phase, the SDK might incorrectly target <code>noble-chiseled</code> and fail, so you must explicitly declare it:</p>
<pre><code class="language-xml">&lt;!-- Add this to your .csproj --&gt;
&lt;ContainerFamily&gt;resolute-chiseled&lt;/ContainerFamily&gt;

</code></pre>
<p>While marketing sometimes hints at sub-50MB footprints, sandbox testing shows a standard minimal API built on <code>resolute-chiseled</code> clocks in at <strong>128MB uncompressed</strong>—still an excellent 50% reduction with zero package managers or shells included.</p>
<h2>2. Multi-Architecture: The Massive Win and the Critical Gotcha</h2>
<p>Transitioning to ARM64 (like AWS Graviton) saves money, but configuring QEMU and Docker Buildx in CI pipelines is notoriously slow. .NET 11 handles this beautifully at the compiler level.</p>
<p>By passing <code>-r linux-arm64</code>, the SDK cross-compiles the Intermediate Language (IL) natively and constructs the ARM64 container layers on an x64 runner without ever invoking QEMU. This is a massive CI performance win.</p>
<p><strong>The Pipeline Gotcha:</strong> You cannot rely on the SDK to build a true multi-architecture tag (a single <code>latest</code> tag that resolves correctly on both architectures). If you run consecutive publish commands for <code>linux-x64</code> and <code>linux-arm64</code> pointing to the same registry tag, the second push <strong>completely overwrites</strong> the first manifest.</p>
<h2><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2026-09-17-NET-11-Container-Publishing/2-conflict.jpeg" alt="conflict" /></h2>
<p>To create a genuine multi-arch manifest list, your CI/CD pipeline still requires a manual step.</p>
<h2><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2026-09-17-NET-11-Container-Publishing/2-manifest.jpeg" alt="manifest" /></h2>
<blockquote>
<p><strong>Key insight:</strong> Build and push architecture-specific tags (<code>latest-amd64</code>, <code>latest-arm64</code>) with the SDK, then use <code>docker manifest create</code> or <code>buildah manifest</code> at the end of your pipeline to bind them together.</p>
</blockquote>
<h2>3. Daemonless CI/CD: Seamless Podman Integration</h2>
<p>If your enterprise strictly enforces rootless, daemonless CI/CD agents, .NET 11 is a game changer. Historically, using Podman required brittle <code>DOCKER_HOST</code> socket mapping hacks.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2026-09-17-NET-11-Container-Publishing/3-podman.jpeg" alt="podman" /></p>
<p>In testing, completely removing Docker from the <code>PATH</code> and installing only Podman resulted in flawless execution. The SDK automatically detects Podman and pushes directly to its local image store. You can finally adopt rootless Podman on RHEL/Ubuntu GitHub Action runners without modifying your <code>dotnet publish</code> commands.</p>
<h2>4. Supply-Chain Security: The Reproducibility Illusion</h2>
<p>Software Supply Chain standards like SLSA emphasize reproducible builds—the guarantee that the same source code produces the exact same artifact digest.</p>
<p>While the .NET 11 compiler is perfectly deterministic (producing byte-for-byte identical DLLs on identical source code), the resulting container image digest (SHA256) <strong>will still change</strong> on every build. This occurs because the container packing step embeds the current wall-clock time (<code>mtime</code>) into the headers of the <code>tar</code> filesystem layers. Until the SDK provides a robust <code>SOURCE_DATE_EPOCH</code> injection mechanism, strict bit-for-bit image digest reproducibility requires external tooling.</p>
<h2>The DevOps Adoption Checklist</h2>
<p>Before ripping out your <code>Dockerfile</code>s for .NET 11, evaluate your pipelines against these verified realities:</p>
<ol>
<li><p><strong>Validate OS Dependencies:</strong> No apt-get allowed.
The SDK cannot install OS-level packages (e.g., <code>ffmpeg</code>, <code>wkhtmltopdf</code>). If your app relies on them, stick to a <code>Dockerfile</code>.</p>
</li>
<li><p><strong>Force Chiseled Images:</strong> Update your .csproj.
Add <code>&lt;ContainerFamily&gt;resolute-chiseled&lt;/ContainerFamily&gt;</code> to halve your image size and eliminate shell-based CVE vectors.</p>
</li>
<li><p><strong>Keep Manifest Commands:</strong> Don't trust the overwrite.
Continue using <code>docker manifest</code> in your pipeline to aggregate the lightning-fast, QEMU-free <code>linux-x64</code> and <code>linux-arm64</code> SDK builds into a single tag.</p>
</li>
<li><p><strong>Switch to Podman Agents:</strong> Zero-config rootless builds.
Upgrade your self-hosted runners to Podman to immediately benefit from rootless container execution without updating build scripts.</p>
</li>
</ol>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2026-09-17-NET-11-Container-Publishing/5-checklist.jpeg" alt="5-checklist" /></p>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a23c0b0-5739-15b7-53ee-fa1559c83193" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a23c0b0-5739-15b7-53ee-fa1559c83193" medium="image" />
    </item>
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/5-things-you-should-keep-in-mind-when-deploying-to-a-clustered-environment-i9byusnv</guid>
      <link>https://abp.io/community/posts/5-things-you-should-keep-in-mind-when-deploying-to-a-clustered-environment-i9byusnv</link>
      <a10:author>
        <a10:name>selmankoc</a10:name>
        <a10:uri>https://abp.io/community/members/selmankoc</a10:uri>
      </a10:author>
      <category>deployment</category>
      <category>state-management</category>
      <category>logging</category>
      <category>background-worker</category>
      <category>clustered</category>
      <title>5 Things You Should Keep in Mind When Deploying to a Clustered Environment</title>
      <description>Deploying to a cluster isn’t only about scaling up — it’s about staying stable when you do.
Systems that handle state, logging, and background work correctly tend to age gracefully.
Everything else eventually learns the hard way.</description>
      <pubDate>Thu, 30 Oct 2025 07:38:37 Z</pubDate>
      <a10:updated>2026-10-11T16:43:59Z</a10:updated>
      <content:encoded><![CDATA[<h1>5 Things You Should Keep in Mind When Deploying to a Clustered Environment</h1>
<p>Let’s be honest — moving from a single server to a cluster sounds simple on paper.<br />
You just add a few more machines, right?<br />
In practice, it’s the moment when small architectural mistakes start to grow legs.<br />
Below are a few things that experienced engineers usually double-check before pressing that “Deploy” button.</p>
<hr />
<h2>1️⃣ Managing State the Right Way</h2>
<p>Each request in a cluster might hit a different machine.<br />
If your application keeps user sessions or cache in memory, that data probably won’t exist on the next node.<br />
That’s why many teams decide to push state out of the app itself.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2025-10-17-5-Things-Deploy-Clustered-Environment/stateless.png" alt="Stateless vs Stateful" /></p>
<p><strong>A few real-world tips:</strong></p>
<ul>
<li>Keep sessions in <strong>Redis</strong> or something similar instead of local memory.</li>
<li>Design endpoints so they don’t rely on earlier requests.</li>
<li>Don’t assume the same server will handle two requests in a row — it rarely does.</li>
</ul>
<hr />
<h2>2️⃣ Shared Files and Where to Put Them</h2>
<p>Uploading files to local disk? That’s going to hurt in a cluster.<br />
Other nodes can’t reach those files, and you’ll spend hours wondering why images disappear.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2025-10-17-5-Things-Deploy-Clustered-Environment/shared.png" alt="Shared Storage" /></p>
<p><strong>Better habits:</strong></p>
<ul>
<li>Push uploads to <strong>S3</strong>, <strong>Azure Blob</strong>, or <strong>Google Cloud Storage</strong>.</li>
<li>Send logs to a shared location instead of writing to local files.</li>
<li>Keep environment configs in a central place so each node starts with the same settings.</li>
</ul>
<hr />
<h2>3️⃣ Database Connections Aren’t Free</h2>
<p>Every node opens its own database connections.<br />
Ten nodes with twenty connections each — that’s already two hundred open sessions.<br />
The database might not love that.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2025-10-17-5-Things-Deploy-Clustered-Environment/database.png" alt="Database Connections" /></p>
<p><strong>What helps:</strong></p>
<ul>
<li>Put a cap on your connection pools.</li>
<li>Avoid keeping transactions open for too long.</li>
<li>Tune indexes and queries before scaling horizontally.</li>
</ul>
<hr />
<h2>4️⃣ Logging and Observability Matter More Than You Think</h2>
<p>When something breaks in a distributed system, it’s never obvious which server was responsible.<br />
That’s why observability isn’t optional anymore.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2025-10-17-5-Things-Deploy-Clustered-Environment/logging.png" alt="Observability" /></p>
<p><strong>Consider this:</strong></p>
<ul>
<li>Stream logs to <strong>ELK</strong>, <strong>Datadog</strong>, or <strong>Grafana Loki</strong>.</li>
<li>Add a <strong>trace ID</strong> to every incoming request and propagate it across services.</li>
<li>Watch key metrics with <strong>Prometheus</strong> and visualize them in Grafana dashboards.</li>
</ul>
<hr />
<h2>5️⃣ Background Jobs and Message Queues</h2>
<p>If more than one node runs the same job, you might process the same data twice — or delete something by mistake.<br />
You don’t want that kind of excitement in production.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2025-10-17-5-Things-Deploy-Clustered-Environment/background.png" alt="Background Jobs" /></p>
<p><strong>A few precautions:</strong></p>
<ul>
<li>Use a <strong>distributed lock</strong> or <strong>leader election</strong> system.</li>
<li>Make jobs <strong>idempotent</strong>, so running them twice doesn’t break data.</li>
<li>Centralize queue consumers or use a proper task scheduler.</li>
</ul>
<hr />
<h2>Wrapping Up</h2>
<p>Deploying to a cluster isn’t only about scaling up — it’s about staying stable when you do.<br />
Systems that handle state, logging, and background work correctly tend to age gracefully.<br />
Everything else eventually learns the hard way.</p>
<blockquote>
<p>A cluster doesn’t fix design flaws — it magnifies them.</p>
</blockquote>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a1d463a-bf9e-03e3-fd3d-52b64ab075c4" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a1d463a-bf9e-03e3-fd3d-52b64ab075c4" medium="image" />
    </item>
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/best-practices-for-azure-devops-cicd-pipelines-wiguy1ew</guid>
      <link>https://abp.io/community/posts/best-practices-for-azure-devops-cicd-pipelines-wiguy1ew</link>
      <a10:author>
        <a10:name>selmankoc</a10:name>
        <a10:uri>https://abp.io/community/members/selmankoc</a10:uri>
      </a10:author>
      <title>Best Practices for Azure DevOps CI/CD Pipelines</title>
      <description>Good Azure DevOps pipelines aren't just about automation - they help you feel confident in your process.  
Remember these main points:

✔ Use YAML files to keep everything visible and trackable  
✔ Keep passwords and sensitive data in secure storage (not in your code)  
✔ Build once, deploy to many places  
✔ Let automatic tests find problems before users do  
✔ Add safety checks for important systems</description>
      <pubDate>Thu, 21 Aug 2025 11:20:45 Z</pubDate>
      <a10:updated>2026-10-11T11:26:11Z</a10:updated>
      <content:encoded><![CDATA[<h1>🚀 Best Practices for Azure DevOps CI/CD Pipelines</h1>
<p><strong>CI/CD (Continuous Integration / Continuous Delivery)</strong> is not just fancy tech talk - it's now a must-have for modern software teams.<br />
Microsoft's <strong>Azure DevOps</strong> helps make these processes easier to manage.<br />
But how do you create pipelines that work well for your team? Let's look at some practical tips that will make your life easier.</p>
<hr />
<h2>1. 📜 Define Your Pipeline as Code</h2>
<p>Don't use the manual setup method that's hard to track. Azure DevOps lets you use <strong>YAML files</strong> for your pipelines, which gives you:</p>
<ul>
<li>A record of all changes - who made them and when</li>
<li>The same setup across all environments</li>
<li>The ability to undo changes when something goes wrong</li>
</ul>
<p>This stops the common problem where something works on one computer but not another.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2025-08-19-Best-Practices-Azure-Devops/1-pipeline-yaml.png" alt="1-pipeline-yaml" /></p>
<hr />
<h2>2. 🔑 Store Sensitive Information Safely</h2>
<p>Never put passwords directly in your code, even temporarily.<br />
Each environment should have its own settings, and keep sensitive information in <strong>Azure Key Vault</strong> or <strong>Library Variable Groups</strong>.</p>
<p>You'll avoid security problems later.</p>
<!-- ![2-azure-key](https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2025-08-19-Best-Practices-Azure-Devops/2-azure-key.png) -->
<hr />
<h2>3. 🏗️ Keep Building and Releasing Separate</h2>
<p>Think of <strong>Building</strong> like cooking a meal - you prepare everything and package it up.<br />
<strong>Releasing</strong> is like delivering that meal to different people.</p>
<p>Keeping these as separate steps means:</p>
<ul>
<li>You create your package once, then send it to multiple places</li>
<li>You save time and resources by not rebuilding the same thing over and over</li>
</ul>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2025-08-19-Best-Practices-Azure-Devops/3-release.png" alt="3-release" /></p>
<hr />
<h2>4. 🧪 Add Automatic Testing</h2>
<p>Don't waste time testing the same things manually over and over.<br />
Set up <strong>different types of tests</strong> to run automatically. When tests run every time you make changes:</p>
<ul>
<li>You catch problems before your customers do</li>
<li>Your software quality stays high without extra manual work</li>
</ul>
<p>Azure DevOps has tools to help you see test results easily without searching through technical logs.</p>
<hr />
<h2>5. 🛡️ Add Safety Checks</h2>
<p>Automatic doesn't mean pushing everything to your live system right away.<br />
For important environments, add <strong>human approval steps</strong> or <strong>automatic checks</strong> like security scans.</p>
<p>This helps you avoid emergency problems in the middle of the night.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2025-08-19-Best-Practices-Azure-Devops/4-safe-deploy.png" alt="4-safe-deploy" /></p>
<hr />
<h2>✅ Conclusion</h2>
<p>Good Azure DevOps pipelines aren't just about automation - they help you feel confident in your process.<br />
Remember these main points:</p>
<p>✔ Use YAML files to keep everything visible and trackable<br />
✔ Keep passwords and sensitive data in secure storage (not in your code)<br />
✔ Build once, deploy to many places<br />
✔ Let automatic tests find problems before users do<br />
✔ Add safety checks for important systems</p>
<h2><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2025-08-19-Best-Practices-Azure-Devops/5-summarizing.png" alt="5-summarizing" /></h2>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a1bde88-f4e4-de35-8450-c7f3b28903f0" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a1bde88-f4e4-de35-8450-c7f3b28903f0" medium="image" />
    </item>
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/deploy-your-abp-framework-angular-project-to-azure-kubernetes-service-aks-h1hmbm4c</guid>
      <link>https://abp.io/community/posts/deploy-your-abp-framework-angular-project-to-azure-kubernetes-service-aks-h1hmbm4c</link>
      <a10:author>
        <a10:name>selmankoc</a10:name>
        <a10:uri>https://abp.io/community/members/selmankoc</a10:uri>
      </a10:author>
      <category>deployment</category>
      <category>kubernetes</category>
      <title>Deploy Your ABP Framework Angular Project to Azure Kubernetes Service (AKS)</title>
      <description>How we can deploy ABP Angular project to kubernetes environment, which looks a bit more complex but is more preferred for production, using a Helm chart.</description>
      <pubDate>Tue, 28 May 2024 10:32:03 Z</pubDate>
      <a10:updated>2026-10-11T09:01:43Z</a10:updated>
      <content:encoded><![CDATA[<h1>Deploy Your ABP Framework Angular Project to Azure Kubernetes Service (AKS)</h1>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-28-AKS-Helm-deployment-ABP-Angular/abp-angular-aks-helm.png" alt="ABP Framework Angular Project" /></p>
<p>In my previous article on <a href="https://community.abp.io/posts/deploy-your-abp-framework-mvc-project-to-azure-container-apps-r93u9c6d">Deploy Your ABP Framework MVC Project to Azure Container Apps</a>, I talked about how ABP Mvc project can be easily deployed to Azure Container Apps. Now I will show how we can deploy to kubernetes environment, which looks a bit more complex but is more preferred for production, using a Helm chart.</p>
<h3>Getting Started with ABP Framework Angular and Azure Kubernetes Service</h3>
<p>To get started, you will need an ABP Framework Angular project that you want to deploy. If you don't have one, you can <a href="https://docs.abp.io/en/abp/latest/Startup-Templates/Application">create a new project using the ABP CLI</a>. You will also need <a href="https://azure.microsoft.com">an Azure subscription</a> and <a href="https://azure.microsoft.com/en-gb/services/kubernetes-service/">an Azure Kubernetes Service</a>.</p>
<h3>Configuring Your ABP Framework Angular Project</h3>
<p>We have a sample ABP Framework Angular project that we will use for this deployment. Before creating the Docker image and Helm chart, you just need to configure  <code>aspnet-core/src/***.HttpApi.Host/***.HttpApiHostModule.cs</code> file to allow CORS requests from your frontend application. You can do this by updating the following code to the <code>ConfigureServices</code> method:</p>
<pre><code class="language-csharp">public override void ConfigureServices(ServiceConfigurationContext context)
    {
        var configuration = context.Services.GetConfiguration();
        var hostingEnvironment = context.Services.GetHostingEnvironment();

        if (!configuration.GetValue&lt;bool&gt;(&quot;App:DisablePII&quot;))
        {
            Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
        }

        if (!configuration.GetValue&lt;bool&gt;(&quot;AuthServer:RequireHttpsMetadata&quot;))
        {
            Configure&lt;OpenIddictServerAspNetCoreOptions&gt;(options =&gt;
            {
                options.DisableTransportSecurityRequirement = true;
            });
        }
        context.Services.Configure&lt;ForwardedHeadersOptions&gt;(options =&gt;
            {
                options.ForwardedHeaders = ForwardedHeaders.XForw
</code></pre>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-28-AKS-Helm-deployment-ABP-Angular/configure-cors.png" alt="Configure CORS" /></p>
<p>If your ABP Framework Angular project and Azure kubernetes cluster ready, we can start to build the docker images and pushing them to any container registry. In this article, I will use DockerHub as the container registry.</p>
<p>I will also show you how I automated the steps that I originally did manually to make it simpler in the beginning and then automated them in Azure Devops.</p>
<h3>Creating a Docker Image for ABP Framework Angular</h3>
<p>To create a Docker image for your ABP Framework Angular project, navigate to <code>etc/build/build-images-locally.ps1</code> and fix the script to match your Docker Hub username and image name. Then, run the script to build the Docker image locally.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-28-AKS-Helm-deployment-ABP-Angular/build-docker-image.png" alt="Build Docker Image" /></p>
<p>At the end of this process, check your Docker Hub repository to confirm that the image has been pushed successfully. My Docker Hub repository looks like this. Also you can use these my public images to test the deployment.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-28-AKS-Helm-deployment-ABP-Angular/docker-hub-repository.png" alt="Docker Hub Repository" /></p>
<h3>Creating Helm Chart for ABP Framework Angular</h3>
<p>To deploy your ABP Framework Angular project to Azure Kubernetes Service, you need to create a Helm chart. Helm is a package manager for Kubernetes that allows you to define, install, and upgrade even the most complex Kubernetes applications. Helm uses a packaging format called charts, which are a collection of files that describe a related set of Kubernetes resources.</p>
<p>These helm charts are prepared to create a deployment, configmap, service and ingress for your ABP Framework Angular project. It is prepared not only for migration, frontend and backend, but also to create the sqlserver and redis that the application needs as a kubernetes service. If you already have redis and sqlserver, you don't need to stand them up in kubernetes, of course.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-28-AKS-Helm-deployment-ABP-Angular/helm-chart.png" alt="Helm Chart" /></p>
<p>You can find the helm chart in the https://github.com/skoc10/k8s_works/tree/main/demo/helm/k8s/angular repository. You can configure the <code>values-azure.yaml</code> file according to your needs.</p>
<h3>Deploying to Azure Kubernetes Service</h3>
<p><code>Note:</code> You need to have nginx-ingress-controller and cert-manager installed for letsencrypt certificate in your kubernetes cluster.</p>
<p>Now that you have Docker images for your ABP Framework Angular project and a Helm chart, you can proceed to deploy it to Azure Kubernetes Service. To do this, you need to create a new Azure Kubernetes Service resource and configure the <code>values-azure.yaml</code> file according to your needs. If you want, you can deploy a single Helm with <code>demo/helm/k8s/deploy-staging.ps1</code> script you can deploy each chart separately.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-28-AKS-Helm-deployment-ABP-Angular/create-azure-kubernetes-service.png" alt="Create Azure Kubernetes Service" /></p>
<p>After deploying the Helm chart, you can check the deployment status to confirm that the deployment was successful. You can also check the logs of the pods to see if there are any errors.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-28-AKS-Helm-deployment-ABP-Angular/deploy-helm-chart.png" alt="Deploy Helm Chart" /></p>
<p>Finally, you can navigate to the web url to see your ABP Framework Angular project running in Azure Kubernetes Service.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-28-AKS-Helm-deployment-ABP-Angular/abp-angular-aks.png" alt="ABP Framework Angular Project" /></p>
<h3>CI/CD with Azure DevOps</h3>
<p>I have automated the steps that I originally did manually to make it simpler in the beginning and then automated them in Azure Devops. You can find the <code>azure-pipelines.yml</code> file in the https://github.com/skoc10/k8s_works/blob/main/demo/azure/azure-pipelines.yml repository. You can configure the <code>azure-pipelines.yml</code> file according to your needs.</p>
<pre><code class="language-yaml">trigger:
  tags:
    include:
      - &quot;*.*.*&quot;

variables:
  dockerRegistryServiceConnection: 'demo-reg'
  buildContextBasePath: '$(Build.SourcesDirectory)'
  tag: $(Build.BuildNumber)
  DOCKER_BUILDKIT: 1

pool:
  name: ubuntu

stages:
- stage: Build
  displayName: Build
  jobs:
  - job: CheckChanges
    displayName: Check if Angular or ASP.NET Core has changed
    pool:
      name: ubuntu
    steps:
    - checkout: self

# Migration
    - task: Docker@2
      displayName: 'Build Migration Docker image'
      inputs:
        command: build
        repository: demo-angular-apppro/migration
        dockerfile: $(buildContextBasePath)/aspnet-core/src/Demo.AzureAppsAngular.DbMigrator/Dockerfile.azure
        buildContext: $(buildContextBasePath)/aspnet-core
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)

    - task: Docker@2
      displayName: 'Push Migration Docker image'
      inputs:
        command: push
        repository: demo-angular-apppro/migration
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)

    - task: HelmDeploy@0
      displayName: 'Delete Migrator'
      inputs:
        connectionType: Kubernetes Service Connection
        kubernetesServiceConnection: 'aks-demoms'
        namespace: 'angular'
        command: delete
        arguments: dbmigrator
      continueOnError: true

    - task: HelmDeploy@0
      displayName: 'Deploy Migration to AKS'
      inputs:
        connectionType: Kubernetes Service Connection
        kubernetesServiceConnection: 'aks-demoms'
        namespace: 'angular'
        command: 'upgrade'
        chartType: 'FilePath'
        chartPath: '$(buildContextBasePath)/aspnet-core/etc/k8s/angular/charts/dbmigrator'
        releaseName: 'dbmigrator'
        overrideValues: 'image.tag=$(tag)'
        valueFile: '$(buildContextBasePath)/aspnet-core/etc/k8s/angular/charts/dbmigrator/values.yaml'
        waitForExecution: false

# Backend
    - task: Docker@2
      displayName: 'Build Backend Docker image'
      inputs:
        command: build
        repository: demo-angular-apppro/backend
        dockerfile: $(buildContextBasePath)/aspnet-core/src/Demo.AzureAppsAngular.HttpApi.Host/Dockerfile.azure
        buildContext: $(buildContextBasePath)/aspnet-core
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)

    - task: Docker@2
      displayName: 'Push Backend Docker image'
      inputs:
        command: push
        repository: demo-angular-apppro/backend
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)

    - task: HelmDeploy@0
      displayName: 'Deploy Backend to AKS'
      inputs:
        connectionType: Kubernetes Service Connection
        kubernetesServiceConnection: 'aks-demoms'
        namespace: 'angular'
        command: 'upgrade'
        chartType: 'FilePath'
        chartPath: '$(buildContextBasePath)/aspnet-core/etc/k8s/angular/charts/backend'
        releaseName: 'backend'
        overrideValues: 'image.tag=$(tag)'
        valueFile: '$(buildContextBasePath)/aspnet-core/etc/k8s/angular/charts/backend/values.yaml'
        waitForExecution: false

# Frontend
    - task: Docker@2
      displayName: 'Build Frontend Docker image'
      inputs:
        command: build
        repository: demo-angular-apppro/frontend
        dockerfile: $(buildContextBasePath)/angular/Dockerfile.azure
        buildContext: $(buildContextBasePath)/angular
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)

    - task: Docker@2
      displayName: 'Push Frontend Docker image'
      inputs:
        command: push
        repository: demo-angular-apppro/frontend
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)

    - task: HelmDeploy@0
      displayName: 'Deploy Frontend to AKS'
      inputs:
        connectionType: Kubernetes Service Connection
        kubernetesServiceConnection: 'aks-demoms'
        namespace: 'angular'
        command: 'upgrade'
        chartType: 'FilePath'
        chartPath: '$(buildContextBasePath)/aspnet-core/etc/k8s/angular/charts/angular'
        releaseName: 'frontend'
        overrideValues: 'image.tag=$(tag)'
        valueFile: '$(buildContextBasePath)/aspnet-core/etc/k8s/angular/charts/angular/values.yaml'
        waitForExecution: false
</code></pre>
<h3>Conclusion</h3>
<p>In this article, I showed you how you can deploy your ABP Framework Angular project to Azure Kubernetes Service using Helm chart. I also showed you how you can automate the deployment process using Azure DevOps. I hope you found this article helpful. If you have any questions or feedback, please feel free to leave a comment below.</p>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a12d0ee-a647-a8e4-06a4-a851210dd1be" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a12d0ee-a647-a8e4-06a4-a851210dd1be" medium="image" />
    </item>
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/deploy-your-abp-framework-mvc-project-to-azure-container-apps-r93u9c6d</guid>
      <link>https://abp.io/community/posts/deploy-your-abp-framework-mvc-project-to-azure-container-apps-r93u9c6d</link>
      <a10:author>
        <a10:name>selmankoc</a10:name>
        <a10:uri>https://abp.io/community/members/selmankoc</a10:uri>
      </a10:author>
      <category>azure</category>
      <category>deployment</category>
      <category>containerization</category>
      <title>Deploy Your ABP Framework MVC Project to Azure Container Apps</title>
      <description>In this article, we will show the seamless deployment of an ABP Framework MVC project to Azure Container Apps.</description>
      <pubDate>Tue, 07 May 2024 13:48:33 Z</pubDate>
      <a10:updated>2026-10-11T02:57:16Z</a10:updated>
      <content:encoded><![CDATA[<h1>Deploy Your ABP Framework MVC Project to Azure Container Apps</h1>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-07-Azure-Container-Apps-Deployment-with-ABP/azure-container-abp.png" alt="" /></p>
<p>In this article, we will show the seamless deployment of an ABP Framework MVC project to Azure Container Apps. enabling you to deploy and run containerized applications without the hassle of managing the infrastructure underneath. It provides an uncomplicated and cost-effective method for deploying and scaling your applications.</p>
<h3>Getting Started with ABP Framework MVC and Azure Container Apps</h3>
<p>To get started, you will need an ABP Framework MVC project that you want to deploy. If you don't have one, you can <a href="https://docs.abp.io/en/abp/latest/Startup-Templates/Application">create a new project using the ABP CLI</a>. You will also need <a href="https://azure.microsoft.com">an Azure subscription</a> and <a href="https://azure.microsoft.com/en-gb/products/azure-sql">an Azure SQL database</a>.</p>
<p>Before creating Azure container apps resources and deploying the ABP Framework MVC project, I show you how you can effortlessly create Docker images and push them to Docker Hub, leveraging the pre-configured Docker file and scripts that come with the ABP MVC framework.</p>
<h3>Creating a Docker Image for ABP Framework MVC</h3>
<p>To create a Docker image for your ABP Framework MVC project, navigate to <code>etc/build/build-images-locally.ps1</code> and fix the script to match your Docker Hub username and image name. Then, run the script to build the Docker image locally.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-07-Azure-Container-Apps-Deployment-with-ABP/build-docker-image.png" alt="Build Docker Image" /></p>
<p>Next, check the Docker Hub repository to confirm that the image has been pushed successfully.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-07-Azure-Container-Apps-Deployment-with-ABP/docker-hub-repository.png" alt="Docker Hub Repository" /></p>
<h3>Deploying to Azure Container Apps</h3>
<p>Now that you have Docker images for your ABP Framework MVC project, you can proceed to deploy it to Azure Container Apps. To do this, navigate to the Azure portal and create a new Azure Container Apps resource. Ypu will not need just an Azure Container Apps resource, but also an Azure Container Apps Job resource to migrate the database schema and seed data for your ABP Framework MVC project.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-07-Azure-Container-Apps-Deployment-with-ABP/create-azure-container-apps.png" alt="Create Azure Container Apps" /></p>
<h4>Step 1: Deploy the Docker Image</h4>
<p>Firstly, create a new Azure Container Apps resource without environment variables. You will need web url so that you can set it as an environment variable in the next step. Then, check the deployment status to confirm that the deployment was successful.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-07-Azure-Container-Apps-Deployment-with-ABP/deploy-docker-image.png" alt="Deploy Docker Image" /></p>
<h4>Step 2: Migrate Database Schema and Seed Data</h4>
<p>Secondly, create a new Azure Container Apps Job resource to migrate the database schema and seed data. You can do this by creating a new job with the following environment variables:</p>
<pre><code class="language-text">ConnectionStrings__Default - Server=tcp:demoabpapp.database.windows.net,1433;Initial Catalog=mvcapppro;Persist Security Info=False;User ID=demoapppro;Password={your_password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;

OpenIddict__Applications__mvcapppro_Web__RootUrl - https://mvcwebapp.victoriousgrass-8b06438d.northeurope.azurecontainerapps.io
</code></pre>
<p>To get ConnectionStrings of Sql Database and url of the web app, you can navigate to the Azure portal and check the properties of the Azure SQL database and Azure Container Apps resource.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-07-Azure-Container-Apps-Deployment-with-ABP/azure-sql-database-connection-strings.png" alt="Azure SQL Database Connection Strings" /></p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-07-Azure-Container-Apps-Deployment-with-ABP/create-azure-container-apps-job.png" alt="Create Azure Container Apps Job" /></p>
<p>Finally, check the job status to confirm that the database migration and seeding were successful. You can connect to the Azure SQL database to verify that the schema and seed data have been applied.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-07-Azure-Container-Apps-Deployment-with-ABP/check-job-status.png" alt="Check Job Status" /></p>
<h4>Step 3: Edit the Azure Container Apps Resource</h4>
<p>After completing these steps, you have to edit the Azure Container Apps resource to add the required environment variables for your ABP Framework MVC project. You can do this by adding the following environment variables:</p>
<pre><code class="language-text">App__SelfUrl - https://mvcwebapp.victoriousgrass-8b06438d.northeurope.azurecontainerapps.io

ASPNETCORE_URLS - http://+:80

AuthServer__Authority - https://mvcwebapp.victoriousgrass-8b06438d.northeurope.azurecontainerapps.io

ConnectionStrings__Default - Server=tcp:demoabpapp.database.windows.net,1433;Initial Catalog=mvcapppro;Persist Security Info=False;User ID=demoapppro;Password={your_password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;
</code></pre>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-07-Azure-Container-Apps-Deployment-with-ABP/add-environment-variables.png" alt="Add Environment Variables" /></p>
<h4>Step 4: Create a New Deployment</h4>
<p>Once you have added the environment variables, save and create a new deployment to apply the changes. You can now access your ABP Framework MVC project running on Azure Container Apps by navigating to the URL provided in the environment variables.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-07-Azure-Container-Apps-Deployment-with-ABP/access-abp-framework-mvc-project.png" alt="Access ABP Framework MVC Project" /></p>
<p>You can see the Azure resources created for the ABP Framework MVC project deployment that includes the Azure Container Apps resource, Azure Container Apps Job resource, and Azure SQL database.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2024-05-07-Azure-Container-Apps-Deployment-with-ABP/azure-resources.png" alt="Azure Resources" /></p>
<h3>Conclusion</h3>
<p>Azure Container Apps provides a simple and cost-effective way to deploy and scale your ABP Framework MVC projects without managing the underlying infrastructure. By following the steps outlined in this article, you can seamlessly deploy your ABP Framework MVC projects to Azure Container Apps and enjoy the benefits it offers.</p>
<p>I hope you found this article helpful. If you have any questions or feedback, please feel free to leave a comment below.</p>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a12657d-021a-a122-bbfb-6ce0fcbe583b" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a12657d-021a-a122-bbfb-6ce0fcbe583b" medium="image" />
    </item>
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/creating-a-custom-status-page-for-abp.io-with-upptime-jbly5qax</guid>
      <link>https://abp.io/community/posts/creating-a-custom-status-page-for-abp.io-with-upptime-jbly5qax</link>
      <a10:author>
        <a10:name>selmankoc</a10:name>
        <a10:uri>https://abp.io/community/members/selmankoc</a10:uri>
      </a10:author>
      <title>Creating a Custom Status Page for abp.io with Upptime</title>
      <description>process of creating our own status page and customizing it to suit our needs</description>
      <pubDate>Mon, 27 Mar 2023 22:23:17 Z</pubDate>
      <a10:updated>2026-10-11T10:35:28Z</a10:updated>
      <content:encoded><![CDATA[<h1>Creating a Custom Status Page for abp.io with Upptime</h1>
<h2>Introduction</h2>
<p>In today's digital world, providing reliable and transparent information about your platform's availability is essential to maintaining trust among your community and customers. With the growing number of abp.io users, we needed a dedicated status page <a href="https://status.abp.io/">status.abp.io</a> to keep everyone informed about our platform's health. To achieve this, we utilized the open-source project <a href="https://upptime.js.org/">Upptime</a> and built a custom status page on <a href="https://pages.github.com/">GitHub Pages</a>. In this article, we'll guide you through the process of creating our own status page and customizing it to suit our needs.</p>
<h2>Why we chose Upptime</h2>
<p><a href="https://github.com/upptime/upptime">Upptime</a> is an open-source, easy-to-use, and cost-effective solution for monitoring websites and APIs. It offers essential features, such as downtime alerts, response time monitoring, and status history. We decided to use Upptime because of its compatibility with GitHub Pages, ease of customization, comprehensive <a href="https://upptime.js.org/docs/">documentation </a> and discord notifications.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-27-creating-a-custom-status-page-for-abpio-with-upptime/gh-status.png" alt="gh-status" /></p>
<h4>Advantages of Upptime</h4>
<ul>
<li><p>Open-source: Allows easy customization and community support.</p>
</li>
<li><p>GitHub Pages compatibility: Seamless integration with GitHub Pages for hosting.</p>
</li>
<li><p>Cost-effective: Utilizes GitHub Actions, which provides free monitoring within the GitHub Actions usage limits.</p>
</li>
<li><p>Comprehensive documentation: Easy-to-follow instructions for setting up and customizing the status page.</p>
</li>
</ul>
<h4>Disadvantages of Upptime</h4>
<ul>
<li><p>Limited monitoring capabilities: Upptime offers basic monitoring features but lacks advanced capabilities found in dedicated monitoring tools.</p>
</li>
<li><p>Dependence on GitHub Actions: Upptime relies on GitHub Actions, which may pose limitations for users unfamiliar with GitHub's ecosystem or those with large-scale projects.</p>
</li>
<li><p>No built-in alerting system: Users must rely on third-party integrations or custom solutions for notifications, requiring additional configuration.</p>
</li>
<li><p>Limited customization options: Upptime allows for some customization, but options are limited compared to comprehensive monitoring platforms.</p>
</li>
<li><p>Self-hosted limitations: As a self-hosted solution, users are responsible for maintaining and managing their own infrastructure, which may not be ideal for those who prefer a fully managed monitoring solution.</p>
</li>
</ul>
<h2>How to set up the status page on GitHub Pages</h2>
<p>To get started with our custom status page, we followed the instructions in the <a href="https://upptime.js.org/docs/">Upptime documentation</a>. Here's a summary of the steps we took:</p>
<ul>
<li><p>Fork the Upptime <a href="https://github.com/upptime/upptime">template repository</a> to our own GitHub account as <a href="https://github.com/abpframework/abpio-status">abpio-status</a>.</p>
</li>
<li><p>Configure the GitHub Actions workflow. We configured the GitHub Actions workflow by adding the following lines to the <a href="https://github.com/abpframework/abpio-status/blob/master/.github/workflows/uptime.yml"><code>.github/workflows/uptime.yml</code></a></p>
</li>
<li><p>Add the monitored endpoints. We added the monitored endpoints (our abp.io websites) to the <a href="https://github.com/abpframework/abpio-status/blob/master/.upptimerc.yml">.upptimerc.yml</a> file. This file is located in the root of the repository and contains a list of URLs that Upptime monitors.</p>
</li>
</ul>
<pre><code class="language-yaml">
sites:

  - name: abp.io

    url: https://abp.io/health-status

  - name: community.abp.io

    url: https://community.abp.io/health-status

  - name: commercial.abp.io

    url: https://commercial.abp.io/health-status

  - name: nuget.abp.io

    url: https://nuget.abp.io/health-status

  - name: docs.abp.io

    url: https://docs.abp.io/health-status

  - name: support.abp.io

    url: https://support.abp.io/health-status

  - name: blog.abp.io

    url: https://blog.abp.io/health-status

  - name: commercial-demo.abp.io

    url: https://commercial-demo.abp.io/health-status

</code></pre>
<ul>
<li>Enable GitHub Pages. Finally, we enabled GitHub Pages for our forked repository by going to the repository's settings and selecting the gh-pages branch as the source. This made our status page accessible at <a href="https://status.abp.io/">status.abp.io</a>.</li>
</ul>
<h2>Customizing the status page</h2>
<p>After setting up the default Upptime status page, we focused on customizing it to align with our brand and provide a consistent experience for our community and customers. We made the following changes:</p>
<ul>
<li><p>Updating the logo and favicon. We replaced the default logo and favicon with our own abp.io branded assets. This involved adding the new image files to the repository and updating the references in the <code>.upptimerc.yml</code> file:</p>
</li>
<li><p>Customizing the color scheme and typography. We customized the color scheme and typography to match our corporate identity by editing the <code>.upptimerc.yml</code> file:</p>
</li>
</ul>
<pre><code class="language-yaml">
status-website:

  theme: dark

  # Add your custom domain name, or remove the `cname` line if you don't have a domain

  # Uncomment the `baseUrl` line if you don't have a custom domain and add your repo name there

  cname: status.abp.io

  # baseUrl: /abpio-status

  logoUrl: https://commercial.abp.io/assets/svg/abp-logo-light.svg

  favicon: https://raw.githubusercontent.com/abpframework/abpio-status/master/assets/abp-logo-without-text.svg

  faviconSvg: https://raw.githubusercontent.com/abpframework/abpio-status/master/assets/abp-logo-without-text.svg

</code></pre>
<h2>Creating GitHub Issues for Maintenance Information on status.abp.io</h2>
<p>To provide maintenance information for your status page, you can create GitHub issues in your repository. This allows you to inform your users about planned downtime or ongoing maintenance work.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-27-creating-a-custom-status-page-for-abpio-with-upptime/issue.png" alt="issue" /></p>
<h2>Discord Notifications</h2>
<h3>Create a Discord Webhook</h3>
<p>To set up Discord notifications for your status.abp.io status page using <a href="https://upptime.js.org/docs/notifications#discord">Upptime documentation</a>, follow these steps:</p>
<ul>
<li><p>In Discord, go to &quot;Server Settings&quot; &gt; &quot;Integrations&quot; &gt; &quot;Create Webhook.&quot;</p>
</li>
<li><p>Customize the Webhook name, choose a channel, and copy the Webhook URL.</p>
</li>
</ul>
<h3>Configure GitHub Actions</h3>
<ul>
<li><p>In your Upptime repository, go to the &quot;Settings&quot; tab.</p>
</li>
<li><p>Click on &quot;Secrets&quot; and then &quot;New repository secret.&quot;</p>
</li>
<li><p>Add secret: Name it DISCORD_WEBHOOK_URL and paste the Webhook URL as the value.</p>
</li>
<li><p>Add environment variables NOTIFICATION_DISCORD_WEBHOOK and NOTIFICATION_DISCORD set it to true.</p>
</li>
</ul>
<p>Your status page will now send notifications to your Discord channel whenever there's a change in your platform's status.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-27-creating-a-custom-status-page-for-abpio-with-upptime/discord.png" alt="discord" /></p>
<h2>Conclusion</h2>
<p>If your primary goal is to create a simple, cost-effective status page with basic monitoring features, Upptime is an excellent choice. Its open-source nature, seamless integration with GitHub Pages, and comprehensive documentation make it a user-friendly option.</p>
<p>If you require advanced monitoring capabilities or prefer a fully managed monitoring solution, you may want to explore dedicated monitoring tools, such as Pingdom, Uptime Robot, or Datadog. These tools typically offer more robust monitoring features, built-in alerting systems, and customizable dashboards.</p>
<p>Creating a custom status page for abp.io using Upptime and GitHub Pages proved to be an efficient and cost-effective solution. By following the documentation and customizing the template, we were able to provide our community and customers with a reliable source of information about our platform's availability. With this new status page <a href="https://status.abp.io/">status.abp.io</a>, we can continue to build trust and transparency as our platform grows and evolves.</p>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a0a3757-fd39-2d6f-c836-6ad5492a6d87" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a0a3757-fd39-2d6f-c836-6ad5492a6d87" medium="image" />
    </item>
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/onprem-to-azure-migration-of-abp.io-platform-to-azure-q9g4gyd7</guid>
      <link>https://abp.io/community/posts/onprem-to-azure-migration-of-abp.io-platform-to-azure-q9g4gyd7</link>
      <a10:author>
        <a10:name>selmankoc</a10:name>
        <a10:uri>https://abp.io/community/members/selmankoc</a10:uri>
      </a10:author>
      <category>migration azure</category>
      <title>On-Prem to Azure: Migration of abp.io Platform to Azure</title>
      <description>migrating from a on-premise platform to Azure, the steps taken to create and configure the [abp.io platform](https://abp.io) on Azure, and the benefits gained from the migration.</description>
      <pubDate>Mon, 20 Mar 2023 15:12:37 Z</pubDate>
      <a10:updated>2026-10-11T17:33:02Z</a10:updated>
      <content:encoded><![CDATA[<p>Migrating a Kubernetes platform with a database from our own dedicated servers to Azure can be a compelling task, but it can be a necessary one to take advantage of the benefits that the cloud service offers. In this post, we will discuss the reasons for migrating from a on-premise platform to Azure, the steps taken to create and configure the <a href="https://abp.io">abp.io platform</a> on Azure, and the benefits gained from the migration.</p>
<h3>On-Premise Server: The old platform</h3>
<p>There were several reasons for migrating from the old on-premise platform to Azure. First, the Kubernetes cluster and the database were on the same Windows server. Additionally, the Linux virtual machines in Kubernetes were on the Windows server and had limited resources. Furthermore, the Kubernetes maintenance was quite challenging, which was another reason for the migration.</p>
<h3>Reasons for Moving to Azure: The new platform</h3>
<p>The decision to move to the cloud was made to eliminate the disadvantages of the old platform. The migration to Azure meant that the resources would be independent of each other but faster in terms of communicating with each other. The platform would also take advantage of cloud security and availability. The managed Kubernetes service that Azure offers comes with autoscaling and loadbalancing, which makes the platform more reliable. Finally, the migration to Azure would provide a better quality service to global customers and the community.</p>
<h3>Before Moving to Azure</h3>
<p>Before migrating to Azure, we decided to switch our database from MS-SQL to PostgreSQL on-premise first. This gave us the opportunity to test and fine-tune the migration process before making the final switch to Azure.You can check the details of database migration from this article <a href="https://blog.abp.io/abp/Migrating-from-MS-SQL-to-Postgresql">Migrating from MS-SQL to Postgresql</a>.</p>
<p>The platform was tested in a staging environment created on Azure with the same resources as the production environment. The staging environment was used to test and optimize the migration process, including the migration of data from the old platform to Azure, which was tested multiple times to ensure success.</p>
<h3>Creating and Configuring the abp.io Platform on Azure</h3>
<p>Several steps were taken to create and configure the abp.io platform on Azure. <a href="https://www.terraform.io/">Terraform</a> was used to create the infrastructure (VM, Private Network, AKS, Postgresql Flexible Server...), while <a href="https://www.ansible.com/">Ansible</a> was used to configure the Azure resources like Terraform, Helm, Kubectl, Docker, VPN, Redis, Prometheus, Grafana, ElasticSearch, Kibana and so on.... Azure DevOps pipelines and release were used for AKS deployment. The most time-consuming part in this process was to prepare, test and optimize the terraform and ansible settings files.</p>
<p>To access our platform, which is configured on a private network in Azure, we require a VPN connection. To enable this, we have installed <a href="https://www.wireguard.com/">Wireguard</a> - an open source VPN service - by creating a virtual machine using Terraform and configuring it with Ansible in Azure. This approach has made the process efficient and streamlined.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-on-prem-to-azure-migration-of-abpio-platform-to-azure/terra-wire.png" alt="terra-wire" /></p>
<p>The most important step was to transfer the data in both the database and Kubernetes of the volumes. rsync (remote sync commands) were used to transfer the data from Kubernetes volumes to Azure Files through the VPN machine. Additionally, <code>pg_dump</code> and <code>pg_restore</code> were used to transfer the PostgreSQL database through the machine with VPN.</p>
<p>Before the production environment, the data migration was tested many times for the staging environment. We estimated this migration to take max 1.5 hours. The ABP community was informed that there may be interruptions during the hours designated for the transition to Azure. To inform our customers and community, we created a status page before this migration. The new status page is <a href="https://status.abp.io">status.abp.io</a>. From now on we will make all the infrastructural announcements on <a href="https://status.abp.io">status.abp.io</a>. We used <a href="https://upptime.js.org">Upptime</a> which is an open-source uptime monitor and status page provider. During the migration of the production environment, the websites and databases were still up and running. After the data transfer, the only remaining step was to direct the traffic of the already standing abp.io sites to the Azure Kubernetes service via Cloudflare.</p>
<p>We would like to happily state that <strong>we were offline for only 4 minutes</strong> during this transition.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-on-prem-to-azure-migration-of-abpio-platform-to-azure/az-infra.png" alt="az-infra" /></p>
<h3>Benefits of Moving to Azure</h3>
<p>The migration to Azure resulted in several benefits. The platform is now more reliable, scalable, secure, solid with built-in one-click backup and recovery capabilities for abp.io. Additionally, the critical resources are in a private network, making them more secure than the old environment. When we initially compared the speed of our abp.io sites before and after migrating to Azure, we were pleasantly surprised by the significant improvement in performance. To be honest, we did not expect such a speed increase.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-on-prem-to-azure-migration-of-abpio-platform-to-azure/speed.png" alt="speed" /></p>
<p>In conclusion, migrating a Kubernetes platform with a database from on-premise to Azure is a complex process that requires careful planning and execution. However, the benefits gained from the migration make the process worthwhile. By moving to Azure, the abp.io platform now has a more reliable and available infrastructure that is more secure than the old environment. The migration also resulted in significant improvements in connection speeds, which ultimately provides a better service to global customers and the community.</p>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a0a11c1-3232-108b-3049-19a270d39035" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a0a11c1-3232-108b-3049-19a270d39035" medium="image" />
    </item>
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/migrating-from-mssql-to-postgresql-g1wgv6sa</guid>
      <link>https://abp.io/community/posts/migrating-from-mssql-to-postgresql-g1wgv6sa</link>
      <a10:author>
        <a10:name>selmankoc</a10:name>
        <a10:uri>https://abp.io/community/members/selmankoc</a10:uri>
      </a10:author>
      <category>migration azure</category>
      <title>Migrating from MS-SQL to Postgresql</title>
      <description>Database migration is a common practice for organizations that want to move from one database system to another. This can be for a variety of reasons, including cost, performance, and features. In this article, we will discuss the process of migrating a database from MS-SQL to PostgreSQL.</description>
      <pubDate>Mon, 20 Mar 2023 13:45:33 Z</pubDate>
      <a10:updated>2026-10-11T07:25:41Z</a10:updated>
      <content:encoded><![CDATA[<h2>Introduction</h2>
<p>Database migration is a common practice for organizations that want to move from one database system to another. This can be for various reasons, including cost, performance, and features. In this article, we will discuss migrating a database from MS-SQL to PostgreSQL, the challenges that may arise during the migration, and how to overcome them. And we recently moved the main database of the https://abp.io platform from MS-SQL to PostgreSQL.</p>
<p>We switched our database from Microsoft SQL Server (MS-SQL) to PostgreSQL to move our on-premise platform to Azure. We’ve also discovered that the license cost for MS-SQL on Azure was significantly higher than PostgreSQL. After conducting a cost-benefit analysis, we migrated our database to PostgreSQL to save costs.</p>
<p>Before migrating to Azure, we decided to switch our database from MS-SQL to PostgreSQL on-premise first. This allowed us to test and fine-tune the migration process before making the final switch to Azure.</p>
<h2>Challenges</h2>
<p>Despite using a third-party tool(DBConvert for MySQL &amp; PostgreSQL) for the migration, we faced three main problems when exporting data to PostgreSQL. Firstly, some tables with plain text had</p>
<p>UTF-8 encoding problems. We overcame this problem by dump-restoring these tables.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-migrating-from-ms-sql-to-postgresql/db-converter.jpg" alt="db-converter" /></p>
<p>Secondly, our database had to be case-insensitive, but PostgreSQL does not have this as a default configuration. We handled it using <code>citext</code> with the ABP migration service.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-migrating-from-ms-sql-to-postgresql/citext-1.jpg" alt="citext-1" /></p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-migrating-from-ms-sql-to-postgresql/citext-2.jpg" alt="citext-2" /></p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-migrating-from-ms-sql-to-postgresql/citext-3.jpg" alt="citext-3" /></p>
<p>While everything was proceeding very smoothly, we faced one last problem: importing binary data, such as the content of the NuGet packages. It was hard to understand that the binaries of the NuGet packages were different. Our paid commercial NuGet packages are stored as binary data in the database. Therefore, it was the most compelling part of this migration to transfer the NuGet packages. Fortunately, we overcame the binary error. And we decided to write a custom .NET tool to move only the binary data from MS-SQL to PostgreSQL, thanks to the ABP Core team!</p>
<h2>Conclusion</h2>
<p>One of the benefits of using PostgreSQL is the low license costs of the Azure platform. As the main contributors of ABP, we also use ABP Framework under the hood of our abp.io websites; we could easily switch to PostgreSQL. For those who want to switch their ABP project to PostgreSQL, check out <a href="https://docs.abp.io/en/abp/latest/Entity-Framework-Core-PostgreSQL">docs.abp.io/en/abp/latest/Entity-Framework-Core-PostgreSQL</a>. We had not used any MS-SQL specific function, therefore there was no need to make any changes in the repository classes. This means that the applications that were previously using MS-SQL can seamlessly switch to PostgreSQL without any modifications.</p>
<p>Thanks to the flexibility of ABP, it has <a href="https://www.nuget.org/packages/Volo.Abp.EntityFrameworkCore.PostgreSql">PostgreSQL package</a>, which is 100% compatible with PostgreSQL. This helped us to make this migration very smooth and seamless.</p>
<p>In conclusion, migrating a database from MS-SQL to PostgreSQL can be challenging, but it can bring significant cost savings in the long run. By testing and fine-tuning the migration process before making the final switch, we overcame the challenges we’d faced during the migration process. Thanks to the flexibility of ABP, we were able to make the transition with minimal code changes. Also, we didn't see any big performance differences between MS-SQL and PostgreSQL.</p>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a0a1171-7a79-bf6b-1871-c3ec7f7d5b57" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a0a1171-7a79-bf6b-1871-c3ec7f7d5b57" medium="image" />
    </item>
  </channel>
</rss>