{"id":16227431,"url":"https://github.com/simonaco/simona-pbp","last_synced_at":"2025-08-02T16:35:04.833Z","repository":{"id":52210334,"uuid":"132874378","full_name":"simonaco/simona-pbp","owner":"simonaco","description":"Build a CICD pipeline for your Angular app using CircleCI, Docker and Azure","archived":false,"fork":false,"pushed_at":"2021-05-05T02:59:30.000Z","size":105,"stargazers_count":7,"open_issues_count":7,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-14T19:31:08.345Z","etag":null,"topics":["angular","azure","cicd","circleci","docker"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/simonaco.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-05-10T08:52:24.000Z","updated_at":"2020-07-03T10:52:23.000Z","dependencies_parsed_at":"2022-08-24T12:31:09.134Z","dependency_job_id":null,"html_url":"https://github.com/simonaco/simona-pbp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonaco%2Fsimona-pbp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonaco%2Fsimona-pbp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonaco%2Fsimona-pbp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonaco%2Fsimona-pbp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simonaco","download_url":"https://codeload.github.com/simonaco/simona-pbp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243989730,"owners_count":20379648,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","azure","cicd","circleci","docker"],"created_at":"2024-10-10T12:52:44.156Z","updated_at":"2025-03-19T13:31:05.438Z","avatar_url":"https://github.com/simonaco.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"### Build and deploy Angular to the Cloud \n\nThis article was originally posted on the ng-conf blog at https://www.ng-conf.org/build-deploy-angular-cloud/ \n\n### Starring Angular CLI, CircleCI and Azure\n\nAs a developer, I want to write code. I want to push my changes to git, get\nnotified when I break the build or tests, fix and then repeat. Is that too much\nto ask? Apparently, because setting this up in 2017 is still kind of a\nnightmare. But does it have to be? \n\nIn this post we’ll see how we can achieve it all through a series of simple\nsteps:\n\n1.  Configure [CircleCI](http://circleci.com) to build and test your app on each\nchange pushed to Github\n1.  Build a Docker image with updated code and push it to Azure Container Registry\n1.  Host your app on Azure and continuously deploy new changes using webhooks\n\n*****\n\n\u003e But CICD is terrifying!\n\n\u003e — Possibly You. Possibly just now.\n\nYou might also think it’s not your job and you need to know all things about\nDocker and Kubernetes and Swarm and .. and .. Spoiler alert! Continuous\nIntegration / Delivery (CI/CD) can help you **save time** and it’s not that hard\nto get started!\n\n![](https://cdn-images-1.medium.com/max/1600/1*JduUEwnZ8rru_y0wFScFaA.png)\n\u003cspan class=\"figcaption_hack\"\u003eCICD\u003c/span\u003e\n\n\u003e **Continuous Integration** (CI) is a development practice that requires\n\u003e developers to **integrate** code into a shared repository several times a day.\n\n\u003e **Continuous Delivery **(CD)** **is a software development discipline where you\n\u003e build software in such a way that the software can be released to production at\nany time.\n\nTo start building your CICD pipeline, you could write your own shell scripts\nfrom scratch. But if you like **easy**, there are a lot of tools that can make\nyour your life a lot **easier**.\n\n![](https://cdn-images-1.medium.com/max/1600/1*e7Pz5PJ7hryOYD15QQ4TUg.png)\n\u003cspan class=\"figcaption_hack\"\u003eContinuous Integration Tools\u003c/span\u003e\n\nOne of my favourite tools is CircleCI because it has a nice UI and it’s free for\nopen source projects. All you need to get started with CircleCI is a GitHub or\nBitbucket account. Go to [https://circleci.com/](https://circleci.com/) and sign\nup for a new account.\n\n*****\n\n#### Setup CircleCI \n\nLet’s create a new project using the Angular CLI and push it to GitHub. If you\nhave an existing project, you can move on to the next steps.\n\n    $ ng new awesome-app\n\nIn CircleCI, configure your new awesome project to build and run tests by\nfollowing the steps bellow.\n\n1.  Go to Projects tab and click ‘Add project”\n1.  Choose the ‘awesome-app’ project and click ‘Setup project’\n1.  Leave defaults for operating system and version \n1.  Pick your language of choice, for example Node\n\nIn the root of your project, create a folder named *.circleci* and add a file\n*config.yml*. Copy and paste the gist bellow in the new file.\n\n```\nversion: 2\njobs:\n  build:\n    docker:\n      - image: circleci/node:6-browsers\n\n    working_directory: ~/repo\n\n    steps:\n      - checkout\n\n      - restore_cache:\n          keys:\n          - v1-dependencies-{{ checksum \"package.json\" }}\n          # fallback to using the latest cache if no exact match is found\n          - v1-dependencies-\n\n      - run: yarn install\n\n      - save_cache:\n          paths:\n            - node_modules\n          key: v1-dependencies-{{ checksum \"package.json\" }}\n\n      - run: yarn ng build --prod --build-optimizer --no-progress\n      - run: yarn ng test --single-run --no-progress\n```\n\nThere’s a few key things happening here:\n\n1.  In CircleCI, a run is comprised of one or more named jobs. At the moment our\nconfig only defines one job, called `build`. This job is the default entry-point\nfor a run that is triggered by a push to Github.\n1.  We also need to define a **place** where our jobs will run . This is called an\n**executor** in CircleCI and there are two options: use docker or a full virtual\nmachine. Let’s use docker for now and use the circleci/node:6-browsers image.\n1.  A job is a collection of **steps** that run commands for us\n1.  CircleCI can make our builds faster by caching our node_modules\n1.  Finally, we run commands to build our project for production and run tests using\nAngular CLI\n\nAt this point we have automated the build and test runs so let’s go ahead and\nsee some results! Push the config file to GitHub and in CircleCI click ‘Start\nbuilding’. You will be redirected to a page where you can see the status of your\nrunning build. If everything is correct, your run should complete successfully\nin about a minute.\n\n![](https://cdn-images-1.medium.com/max/1600/1*KKYq81wBfbgi-8bfcq__GQ.png)\n\u003cspan class=\"figcaption_hack\"\u003eCircleCI first run result\u003c/span\u003e\n\n*****\n\nAwesome! Let’s next look into configuring [Docker](https://www.docker.com/) and\n[Azure](https://aka.ms/K8ktki)\n\n![](https://cdn-images-1.medium.com/max/1600/1*H--QYmkysfKP7KN0r4KcTA.png)\n\nNext we’ll need an Azure account. If you don’t have one, go ahead and register\nat [https://azure.microsoft.com/free](https://azure.microsoft.com/free). \n\n#### Build and push Docker image\n\nCreate a new file named Dockerfile and save it in the root of your project.\n\n```\nFROM nginx:alpine\nLABEL author=\"Simona Cotin\"\nCOPY ./dist /usr/share/nginx/html\nEXPOSE 80 443\nENTRYPOINT [\"nginx\",\"-g\",\"daemon off;\"]\n```\n\nTo store your docker images, open the Azure portal and create new [Azure\nContainer Registry](https://aka.ms/Bbq47b) (ACR).\n\n\u003e Azure Container Registry allows you to store images for all types of container\n\u003e deployments including DC/OS, Docker Swarm, Kubernetes, and Azure services such\nas App Service, Batch, Service Fabric, and others. Your DevOps team can manage\nthe configuration of apps isolated from the configuration of the hosting\nenvironment.\n\n\u003ca href=\"https://youtu.be/fGhhEQzeksI\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/simonaco/deploy-angular-cloud/blob/master/CreateAzureContainerRegistry.png\" \nalt=\"Create Azure Container Registry\" /\u003e\u003c/a\u003e\n\nEdit *config.yml* to build and push docker images to ACR. Copy and paste the\nconfig bellow and replace *awesomeapp.azurecr.io *with your own Login Server\nvalue. You can find it on the Overview page of your new container registry.\n\n```\nversion: 2\njobs:\n  build:\n    docker:\n      - image: circleci/node:6-browsers\n\n    working_directory: ~/repo\n\n    steps:\n      - checkout\n      - setup_remote_docker\n\n      - restore_cache:\n          keys:\n          - v1-dependencies-{{ checksum \"package.json\" }}\n          # fallback to using the latest cache if no exact match is found\n          - v1-dependencies-\n\n      - run: yarn install\n\n      - save_cache:\n          paths:\n            - node_modules\n          key: v1-dependencies-{{ checksum \"package.json\" }}\n\n      - run: yarn ng build --prod --build-optimizer --no-progress\n      - run: yarn ng test --single-run --no-progress\n      - run:\n          command: |\n            docker build -t awesomeapp.azurecr.io/angular-cli-nginx:1.0 .\n      - run:\n          command: |\n            docker login --username $DOCKER_USER --password $DOCKER_PASS awesomeapp.azurecr.io\n      - run:\n          command: |\n            docker push awesomeapp.azurecr.io/angular-cli-nginx:1.0\n```\n\u003cspan class=\"figcaption_hack\"\u003eUpdated config.yml including docker config\u003c/span\u003e\n\nTo retrieve your container registry login details go to the Access Keys tab in\nthe Azure Portal. On this page, copy the user name field. Go to CircleCI,\nproject settings, environment variables. Click Add Variable, give it the name\nDOCKER_USER and paste the user name you copied earlier. Follow the same steps to\nsetup DOCKER_PASS, but this time copy the password field.\n\n#### Host your app and continuously deploy changes\n\nTo host your awesome-app you need to create new [Azure Web App for\nContainers](https://aka.ms/Bmrs81). \n\n\u003e [Web\n\u003e App](https://docs.microsoft.com/en-us/azure/app-service/app-service-web-overview)\nis a fully managed compute platform that is optimized for hosting websites and\nweb applications.\n\n\u003ca href=\"https://youtu.be/x3f_NBzY7kY\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/simonaco/deploy-angular-cloud/blob/master/CreateAzureWebAppContainer.png\" \nalt=\"Create Azure Web App for Containers\" /\u003e\u003c/a\u003e\n\nConfigure continuous deployment of your app using webhooks. The first thing you\nneed to do is create a new Webhook. Open the portal and go to your new container\nregistry. Click on the webhooks link in the left hand side menu and add a new\nwebhook. You need to define a name, a ‘Service URI’ and a few other values. You\ncan build your service uri by downloading the publish profile config from the\nweb app overview page. It should look like this\n\n*https://\u003cuserName\u003e:\u003cuserPwd\u003e@\u003cmsDeploySite\u003e.scm.azurewebsites.net/docker/hook*\n\nReplace the placeholders with the actual values from your publish profile. Once\nyou have this configured you need to specify which events will trigger the\nwebhook. Choose push to listen to docker push events.\n\nThe final step after creating this webhook is enabling CI in your web app. In\nthe portal, choose the awesome-app and click on the Application Settings link.\nOn this page add a new variable called DOCKER_ENABLE_CI with the value true and\nthen Save.\n\n\u003ca href=\"https://youtu.be/OgljPlsZPVQ\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/simonaco/deploy-angular-cloud/blob/master/CreateAzureWebhook.png\" \nalt=\"Create Azure Webhook\" /\u003e\u003c/a\u003e\n\nPush the updated config.yml file to GitHub to trigger a new build with the new\nchanges. \n\nAt this point, whenever we push a new change to GitHub, a new CircleCI run\nshould start. This will build your app, run tests against the new code and\nfinally deploy it to the cloud.\n\n\n*****\n\n![](https://cdn-images-1.medium.com/max/1600/1*kpKg54C0HjOSE3Nucuuydw.jpeg)\n\nThere! CICD superpowers unlocked!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimonaco%2Fsimona-pbp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimonaco%2Fsimona-pbp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimonaco%2Fsimona-pbp/lists"}