<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Betim Shala</title>
    <description>The latest articles on DEV Community by Betim Shala (@betimshala).</description>
    <link>https://dev.to/betimshala</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F519029%2F001d0185-c544-4550-8837-726937441c45.png</url>
      <title>DEV Community: Betim Shala</title>
      <link>https://dev.to/betimshala</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/betimshala"/>
    <language>en</language>
    <item>
      <title>Deploy .NET Core &amp; React to Heroku using Github Actions
</title>
      <dc:creator>Betim Shala</dc:creator>
      <pubDate>Sun, 09 Jan 2022 23:14:53 +0000</pubDate>
      <link>https://dev.to/betimshala/deploy-net-core-react-to-heroku-using-github-actions-j1b</link>
      <guid>https://dev.to/betimshala/deploy-net-core-react-to-heroku-using-github-actions-j1b</guid>
      <description>&lt;h2&gt;
  
  
  Deploy .NET Core &amp;amp; React to Heroku using Github Actions
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4g2UkLCe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kh3c4sg9hmnkan8dn7f2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4g2UkLCe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kh3c4sg9hmnkan8dn7f2.png" alt="Main image" width="880" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.heroku.com/"&gt;Heroku&lt;/a&gt; is a cloud Platform-as-a-Service (PaaS) used to build and deploy applications of &lt;a href="https://www.heroku.com/languages#languages"&gt;different languages&lt;/a&gt; on the cloud.&lt;/p&gt;

&lt;p&gt;.NET Core is not officially supported by Heroku which means we cannot deploy/run our C# code directly on it. Fortunately, Heroku does support Docker containers, so in this tutorial, we are going to explain how to deploy a containerized .NET Core application on Heroku.&lt;/p&gt;

&lt;p&gt;We can do this process locally on our machine by using Docker CLI and Heroku CLI but we need to repeat the entire flow every time we do a change even a small one. To avoid this we have to use and implement CI/CD workflow and for doing that we are going to use &lt;a href="https://docs.github.com/en/free-pro-team@latest/actions"&gt;Github Actions&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Dockerfile
&lt;/h2&gt;

&lt;p&gt;I assume you’ve already created the application, if not you can follow this &lt;a href="https://www.roundthecode.com/dotnet/add-a-react-app-to-your-asp-net-core-application"&gt;tutorial&lt;/a&gt; on how to create a .NET Core application with React.&lt;/p&gt;

&lt;p&gt;After we’ve created our application we can add Dockerfile to it. Our application structure will be like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fQH1Bl6q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AiZb90rqOqKIZEnavqcxgSw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fQH1Bl6q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AiZb90rqOqKIZEnavqcxgSw.png" alt="Application structure" width="247" height="594"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see we’ve added Dockerfile to our solution and this is how it initially looks like&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
As you can see in our solution we have ClientApp folder which contains all files of React application and the current Dockerfile builds only .NET Core solution so we need to modify it in order to build the React app.

&lt;p&gt;In line &lt;strong&gt;1&lt;/strong&gt; we’ve declared .NET Core base image but besides that, we also need to add a Node.js base image (line &lt;strong&gt;16&lt;/strong&gt;— for building React app) and copy the build folder (line &lt;strong&gt;30&lt;/strong&gt;)&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
By default .NET Core application runs on port 5000 and 5001, on the other side Heroku provides a &lt;em&gt;single&lt;/em&gt; port for you to use and expects your app to run on the port Heroku gives, so basically that means our app should listen to only HTTP connections on that port and Heroku will take care of HTTPS part, so we have to replace the line:

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENTRYPOINT ["dotnet", "NetCoreReactHeroku.dll"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;with this:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CMD ASPNETCORE_URLS=http://*:$PORT dotnet NetCoreReactHeroku.dll
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;By using the initial template of Dockerfile we usually face the error &lt;strong&gt;npm: not found&lt;/strong&gt; while building the Docker image because NodeJs don’t exist on the Docker image of the SDK, and to get rid of this error we need to prevent the &lt;strong&gt;PublishRunWebpack&lt;/strong&gt; task of csproj to be executed. To do that we replace this line:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;with this one:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish" Condition=" '$(BuildingDocker)' == '' "&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;As you can see we’ve added a &lt;strong&gt;Condition&lt;/strong&gt; to csproj which accepts the parameter BuildingDocker and this parameter should be on Dockerfile as well as an environment variable (line &lt;strong&gt;8&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;Now we are all set with Dockerizing our solution, and if you want to test/build the solution and see if Dockerfile works simply run this command.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build . -t $YOUR_APP_NAME -f Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X7TLJ8nh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AYTT_RAGR6pTzrUC30oomHg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X7TLJ8nh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AYTT_RAGR6pTzrUC30oomHg.png" alt="Successful Docker image build" width="880" height="527"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Create a Heroku App
&lt;/h2&gt;

&lt;p&gt;First of all, you need to have an account on Heroku, and then you go to your dashboard (&lt;a href="http://dashboar.heroku.com/new-app"&gt;dashboard.heroku.com/new-app&lt;/a&gt;) to create your application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZukFj-Wt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ADucR2KquxzW0vPJ6P69siw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZukFj-Wt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ADucR2KquxzW0vPJ6P69siw.png" alt="New Heroku App" width="797" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After we create our Heroku app we need to get an API key which we’ll use later on our Github Actions. We can get this key by going to &lt;em&gt;&lt;a href="https://dashboard.heroku.com/account"&gt;Account Settings&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZA7WxdjB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2428/1%2A56NeoSV9RxN5vR5YtGVFQg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZA7WxdjB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2428/1%2A56NeoSV9RxN5vR5YtGVFQg.png" alt="api-key-settings" width="880" height="220"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up Github Actions
&lt;/h2&gt;

&lt;p&gt;After we added Dockerfile and created the Heroku application now we are ready to deploy our image to the Heroku container and release our web application. To make this happens we are going to use Github Actions. Github Actions provides an automated way to trigger custom workflows in response to events on Github (push, pull_request, etc).&lt;/p&gt;

&lt;p&gt;Go to the main directory of your application and add .github folder and inside it also create another folder called workflows as shown in the screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F80oxKEe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A_n8Q5P6WSo_jVOOM_m1NlA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F80oxKEe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A_n8Q5P6WSo_jVOOM_m1NlA.png" alt="Project files" width="246" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now inside workflows folder create workflow file which is ayml file.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
This workflow should have one name (line &lt;strong&gt;1&lt;/strong&gt;) and should define the events that are going to be triggered. In our case, we’ve told the workflow to be triggered only when we push to &lt;strong&gt;master&lt;/strong&gt; branch. In line &lt;strong&gt;9&lt;/strong&gt; you can see the Heroku API key env variable which is used to login into our Heroku registry, and you can notice the keyword secrets which means we should go to our repository secrets and add this variable (see screenshot below).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6WRwWccC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2556/1%2AlXNCSVV61XSeh13NecToFw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6WRwWccC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2556/1%2AlXNCSVV61XSeh13NecToFw.png" alt="Secrets" width="880" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every workflow is made up of &lt;strong&gt;jobs&lt;/strong&gt; (line &lt;strong&gt;12&lt;/strong&gt;) and every job is composed of individual steps. In our case, we’ve declared only &lt;strong&gt;build&lt;/strong&gt; job which has 3 &lt;strong&gt;steps&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cloning the repository using &lt;strong&gt;checkout&lt;/strong&gt; action (line &lt;strong&gt;20&lt;/strong&gt;) that checks-out our repository under &lt;code&gt;$GITHUB_WORKSPACE&lt;/code&gt;, so our workflow can access it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Building our Docker image by running the command on runner (line &lt;strong&gt;25&lt;/strong&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pushing the Docker image to Heroku Container by running a set of Heroku commands (lines &lt;strong&gt;30&lt;/strong&gt; and &lt;strong&gt;31&lt;/strong&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, you just have to commit and push those changes and go to the Actions tab under your Github repository where you can see the build process going on. When the build complete successfully you can visit your deployed app on Heroku &lt;em&gt;(https://{YOUR_APP_NAME}.herokuapp.com)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The complete solution of this tutorial can be found in this &lt;a href="https://github.com/BetimShala/NetCoreReactHeroku"&gt;Github repository&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Thank you for reading. I hope you enjoyed this tutorial and learned something new 😊.&lt;/p&gt;

&lt;p&gt;If you liked this article and want to see more you can find me at&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.linkedin.com/in/betimshala/"&gt;https://www.linkedin.com/in/betimshala&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>react</category>
      <category>docker</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
