{"id":9417,"date":"2025-02-05T10:31:53","date_gmt":"2025-02-05T18:31:53","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cosmosdb\/?p=9417"},"modified":"2025-02-05T10:31:53","modified_gmt":"2025-02-05T18:31:53","slug":"use-azure-cosmos-db-as-a-docker-container-in-ci-cd-pipelines","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cosmosdb\/use-azure-cosmos-db-as-a-docker-container-in-ci-cd-pipelines\/","title":{"rendered":"Use Azure Cosmos DB as a Docker container in CI\/CD pipelines"},"content":{"rendered":"<p>There are lot of benefits to using Docker containers in CI\/CD pipelines, especially for stateful systems like databases. For example, when you run integration tests, each CI job can start the database in an isolated container with a clean state, preventing conflicts between tests. This results in a testing environment that is reliable, consistent, and cost effective. This approach also reduces latency and improves the overall performance of the CI\/CD pipeline because the database is locally accessible.<\/p>\n<p>The\u00a0<a href=\"https:\/\/learn.microsoft.com\/azure\/cosmos-db\/emulator-linux\" target=\"_blank\" rel=\"noopener\">Linux-based Azure Cosmos DB emulator<\/a>\u00a0is available as a Docker container and can run on a variety of platforms, including\u00a0ARM64\u00a0architectures like Apple Silicon. It allows local development and testing of applications without needing an Azure subscription or incurring service costs. You can easily run it as a Docker container, and use it for local development and testing:<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">docker pull mcr.microsoft.com\/cosmosdb\/linux\/azure-cosmos-emulator:vnext-preview<\/code><\/pre>\n<h2>Azure Cosmos DB + GitHub Actions<\/h2>\n<p>Let\u2019s walk through an example to better understand how to use Azure Cosmos DB emulator with\u00a0<a href=\"https:\/\/docs.github.com\/actions\" target=\"_blank\" rel=\"noopener\">GitHub Actions<\/a>, which is a continuous integration and continuous delivery (CI\/CD) platform that allows you to automate your build, test, and deployment pipeline using workflows. A\u00a0workflow\u00a0is a configurable automated process that can run one or more jobs. It is defined by a YAML file checked in to your repository and runs when triggered by an event in your repository, or they can be triggered manually, or at a defined schedule.<\/p>\n<h3>Example: CI workflow for a .NET application<\/h3>\n<p>This GitHub Actions workflow configures Azure Cosmos DB Linux-based emulator as a\u00a0<a href=\"https:\/\/docs.github.com\/actions\/use-cases-and-examples\/using-containerized-services\/about-service-containers\" target=\"_blank\" rel=\"noopener\">GitHub actions service container<\/a>\u00a0as part of a job. GitHub takes care of starting the Docker container and destroys it when the job completes \u2013 no manual intervention required (such as executing the\u00a0docker run command).<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">name: .NET App CI\r\n\r\non:\r\n  push:\r\n    branches: [main]\r\n    paths:\r\n      - 'dotnet-app\/**'\r\n  pull_request:\r\n    branches: [main]\r\n    paths:\r\n      - 'dotnet-app\/**'\r\n\r\njobs:\r\n  build-and-test:\r\n    runs-on: ${{ matrix.os }}\r\n\r\n    strategy:\r\n      matrix:\r\n        os: [ubuntu-latest, ubuntu-24.04-arm]\r\n\r\n    services:\r\n      cosmosdb:\r\n        image: mcr.microsoft.com\/cosmosdb\/linux\/azure-cosmos-emulator:vnext-preview\r\n        ports:\r\n          - 8081:8081\r\n        env:\r\n          PROTOCOL: https\r\n\r\n    env:\r\n      COSMOSDB_CONNECTION_STRING: ${{ secrets.COSMOSDB_CONNECTION_STRING }}\r\n      COSMOSDB_DATABASE_NAME: ${{ vars.COSMOSDB_DATABASE_NAME }}\r\n      COSMOSDB_CONTAINER_NAME: ${{ vars.COSMOSDB_CONTAINER_NAME }}\r\n\r\n    steps:\r\n      - name: Checkout repository\r\n        uses: actions\/checkout@v4\r\n\r\n      - name: Set up .NET\r\n        uses: actions\/setup-dotnet@v3\r\n        with:\r\n          dotnet-version: '8.0.x'\r\n\r\n      - name: Export Cosmos DB Emulator Certificate\r\n        run: |\r\n          sudo apt update &amp;&amp; sudo apt install -y openssl\r\n          openssl s_client -connect localhost:8081 &lt;\/dev\/null | sed -ne '\/-BEGIN CERTIFICATE-\/,\/-END CERTIFICATE-\/p' &gt; cosmos_emulator.cert\r\n          \r\n          sudo cp cosmos_emulator.cert \/usr\/local\/share\/ca-certificates\/\r\n          sudo update-ca-certificates\r\n\r\n      - name: Install dependencies\r\n        run: cd dotnet-app &amp;&amp; dotnet restore\r\n\r\n      - name: Build\r\n        run: cd dotnet-app &amp;&amp; dotnet build --no-restore\r\n\r\n      - name: Run tests\r\n        run: cd dotnet-app &amp;&amp; dotnet test --no-build --verbosity normal<\/code><\/pre>\n<p>This job is configured to run on an Ubuntu runner and uses the\u00a0<code>mcr.microsoft.com\/cosmosdb\/linux\/azure-cosmos-emulator:vnext-preview<\/code>\u00a0docker image as a service container. The connection string, database name, and container name are configured as environment variables. Since the job runs directly on a\u00a0<a href=\"https:\/\/docs.github.com\/actions\/using-github-hosted-runners\/using-github-hosted-runners\" target=\"_blank\" rel=\"noopener\">GitHub Actions hosted runner<\/a>, the\u00a0<strong>Run tests<\/strong>\u00a0step can access the emulator using\u00a0<code>localhost:8081<\/code>.<\/p>\n<p><div class=\"alert alert-primary\">The\u00a0Export Cosmos DB Emulator Certificate\u00a0step is specific to .NET (as well as Java) applications because at the time of writing, the .NET and Java SDKs do not support\u00a0<code>HTTP<\/code>\u00a0mode in emulator. The\u00a0<code>PROTOCOL<\/code>\u00a0environment variable is set to\u00a0<code>https<\/code>\u00a0in the\u00a0services\u00a0section and this step exports the emulator certificate and adds them to the operating system trusted certificate store.<\/div><\/p>\n<h2>Try it out!<\/h2>\n<p>This\u00a0<a href=\"https:\/\/github.com\/AzureCosmosDB\/cosmosdb-linux-emulator-github-actions\" target=\"_blank\" rel=\"noopener\">GitHub repository<\/a>\u00a0provides examples of how to configure the Linux emulator as part of a GitHub Actions CI workflow for .NET, Python, Java and Go applications on both\u00a0x64\u00a0and\u00a0ARM64\u00a0architectures (demonstrated for Linux runner using\u00a0<code>ubuntu<\/code>).<\/p>\n<h3>Fork the repository<\/h3>\n<p>Navigate to the GitHub repository, and click the\u00a0<strong>Fork<\/strong>\u00a0button at the top-right corner of the repository page to create a copy of the repository under your own GitHub account.<\/p>\n<p>In your GitHub account, open the repository and make sure to enable workflows in the repository settings.<\/p>\n<p><img decoding=\"async\" width=\"1622\" height=\"806\" class=\"wp-image-9418\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica.png\" alt=\"A screenshot of a computer Description automatically generated\" srcset=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica.png 1622w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-300x149.png 300w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-1024x509.png 1024w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-768x382.png 768w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-1536x763.png 1536w\" sizes=\"(max-width: 1622px) 100vw, 1622px\" \/><\/p>\n<p>Add the Cosmos DB emulator connection string (<code>COSMOSDB_CONNECTION_STRING<\/code>) as\u00a0<a href=\"https:\/\/docs.github.com\/actions\/security-for-github-actions\/security-guides\/using-secrets-in-github-actions#creating-secrets-for-a-repository\" target=\"_blank\" rel=\"noopener\">Repository secret<\/a>\u00a0to the repository. Use the following value:<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">AccountEndpoint=http:\/\/localhost:8081\/;AccountKey=C2y6yDjf5\/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw\/Jw==<\/code><\/pre>\n<p><img decoding=\"async\" width=\"1377\" height=\"796\" class=\"wp-image-9419\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-1.png\" alt=\"A screenshot of a computer Description automatically generated\" srcset=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-1.png 1377w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-1-300x173.png 300w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-1-1024x592.png 1024w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-1-768x444.png 768w\" sizes=\"(max-width: 1377px) 100vw, 1377px\" \/><\/p>\n<p>Add database name (<code>COSMOSDB_DATABASE_NAME<\/code>) and container name (<code>COSMOSDB_CONTAINER_NAME<\/code>) as\u00a0<a href=\"https:\/\/docs.github.com\/actions\/writing-workflows\/choosing-what-your-workflow-does\/store-information-in-variables#creating-configuration-variables-for-a-repository\" target=\"_blank\" rel=\"noopener\">Repository variables<\/a>:<\/p>\n<p><img decoding=\"async\" width=\"1380\" height=\"706\" class=\"wp-image-9420\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-2.png\" alt=\"A screenshot of a computer Description automatically generated\" srcset=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-2.png 1380w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-2-300x153.png 300w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-2-1024x524.png 1024w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-2-768x393.png 768w\" sizes=\"(max-width: 1380px) 100vw, 1380px\" \/><\/p>\n<p>Clone the forked repository to your local machine (make sure to use your GitHub username):<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">git clone https:\/\/github.com\/&lt;your-username&gt;\/cosmosdb-linux-emulator-github-actions.git\r\n\r\ncd cosmosdb-linux-emulator-github-actions<\/code><\/pre>\n<h3>Trigger the workflow<\/h3>\n<p>To trigger the workflow, make a small change to any\/all of the code (.NET, Java, Python, or Go), add and commit your changes. For easier understanding, separate workflows are used for each language.<\/p>\n<p>Push your changes to your forked repository on GitHub:<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">git add .\r\n\r\ngit commit -m \"Your commit message\"\r\n\r\ngit push origin main<\/code><\/pre>\n<p>After pushing the changes, GitHub Actions will automatically run the workflow. Go to the\u00a0<strong>Actions<\/strong>\u00a0tab in your repository to see the status and results of the workflows. Review any logs or output to ensure the workflows are running correctly.<\/p>\n<p><img decoding=\"async\" width=\"1379\" height=\"745\" class=\"wp-image-9421\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-3.png\" alt=\"A screenshot of a computer Description automatically generated\" srcset=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-3.png 1379w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-3-300x162.png 300w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-3-1024x553.png 1024w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2025\/02\/a-screenshot-of-a-computer-description-automatica-3-768x415.png 768w\" sizes=\"(max-width: 1379px) 100vw, 1379px\" \/><\/p>\n<h2>GitHub Actions runner considerations<\/h2>\n<p>The\u00a0<a href=\"https:\/\/github.com\/AzureCosmosDB\/cosmosdb-linux-emulator-github-actions\" target=\"_blank\" rel=\"noopener\">sample repository<\/a>\u00a0demonstrated\u00a0<code>ubuntu<\/code>\u00a0based runners (for\u00a0x64\u00a0and\u00a0ARM64\u00a0architectures). This should work for\u00a0<a href=\"https:\/\/github.blog\/news-insights\/product-news\/arm64-on-github-actions-powering-faster-more-efficient-build-systems\/\" target=\"_blank\" rel=\"noopener\">Windows ARM-based runners<\/a>\u00a0as well. If you are considering Windows\u00a0x64\u00a0runners, note that at the time of writing, GitHub Actions service containers are\u00a0<a href=\"https:\/\/github.blog\/news-insights\/product-news\/arm64-on-github-actions-powering-faster-more-efficient-build-systems\/\">not supported in non-Linux runners<\/a>. But you can work around this by adding\u00a0steps\u00a0to install Docker, and manage its lifecycle including starting and stopping the container.<\/p>\n<h2>Wrap up<\/h2>\n<p>As I mentioned earlier, there are a lot of benefits of using Docker container in CI pipelines. GitHub Actions was used as the CI\/CD platform in this case, but these concepts apply to other solutions as well. <a href=\"https:\/\/github.com\/AzureCosmosDB\/cosmosdb-linux-emulator-github-actions\">Try it out<\/a> and let us know what you think!<\/p>\n<h2>Leave a review<\/h2>\n<p>Tell us about your Azure Cosmos DB experience! Leave a review on PeerSpot and we\u2019ll gift you $50. <a href=\"https:\/\/peerspotdotcom.my.site.com\/proReviews\/?SalesOpportunityProduct=00kPy000004TKXJIA4&amp;productPeerspotNumber=30881&amp;CalendlyAccount=peerspot&amp;CalendlyFormLink=peerspot-product-reviews-ps-gc-vi-sf-50&amp;giftCard=50\" target=\"_blank\" rel=\"noopener\">Get started here<\/a>.<\/p>\n<h2>About Azure Cosmos DB<\/h2>\n<p>Azure Cosmos DB is a fully managed and serverless NoSQL and vector database for modern app development, including AI applications. With its SLA-backed speed and availability as well as instant dynamic scalability, it is ideal for real-time NoSQL and MongoDB applications that require high performance and distributed computing over massive volumes of NoSQL and vector data.<\/p>\n<p><a href=\"https:\/\/cosmos.azure.com\/try\/\" target=\"_blank\" rel=\"noopener\">Try Azure Cosmos DB for free here.<\/a> To stay in the loop on Azure Cosmos DB updates, follow us on <a href=\"https:\/\/twitter.com\/AzureCosmosDB\" target=\"_blank\" rel=\"noopener\">X<\/a>, <a href=\"https:\/\/aka.ms\/AzureCosmosDBYouTube\" target=\"_blank\" rel=\"noopener\">YouTube<\/a>, and <a href=\"https:\/\/www.linkedin.com\/company\/azure-cosmos-db\/\" target=\"_blank\" rel=\"noopener\">LinkedIn<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are lot of benefits to using Docker containers in CI\/CD pipelines, especially for stateful systems like databases. For example, when you run integration tests, each CI job can start the database in an isolated container with a clean state, preventing conflicts between tests. This results in a testing environment that is reliable, consistent, and [&hellip;]<\/p>\n","protected":false},"author":181737,"featured_media":9412,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[14],"tags":[539,1933,1783,1738,537,1312],"class_list":["post-9417","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-core-sql-api","tag-net","tag-devops","tag-docker","tag-go","tag-java","tag-python"],"acf":[],"blog_post_summary":"<p>There are lot of benefits to using Docker containers in CI\/CD pipelines, especially for stateful systems like databases. For example, when you run integration tests, each CI job can start the database in an isolated container with a clean state, preventing conflicts between tests. This results in a testing environment that is reliable, consistent, and [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/9417","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/users\/181737"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/comments?post=9417"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/9417\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media\/9412"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media?parent=9417"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/categories?post=9417"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/tags?post=9417"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}