<?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: Phillip Lorenzo</title>
    <description>The latest articles on DEV Community by Phillip Lorenzo (@pllearns).</description>
    <link>https://dev.to/pllearns</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%2F720133%2F0e16b1cb-10fd-4f20-b683-fe378ef715d9.jpeg</url>
      <title>DEV Community: Phillip Lorenzo</title>
      <link>https://dev.to/pllearns</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pllearns"/>
    <language>en</language>
    <item>
      <title>Deploy NextJS to AWS EB with Github Actions in 2021</title>
      <dc:creator>Phillip Lorenzo</dc:creator>
      <pubDate>Wed, 06 Oct 2021 05:34:35 +0000</pubDate>
      <link>https://dev.to/pllearns/deploy-nextjs-to-aws-eb-with-github-actions-in-2021-2i8b</link>
      <guid>https://dev.to/pllearns/deploy-nextjs-to-aws-eb-with-github-actions-in-2021-2i8b</guid>
      <description>&lt;p&gt;Before I start, I want to acknowledge my teammates at &lt;a href="https://fyclabs.com/"&gt;FYC Labs&lt;/a&gt;, Zahnen and Adolfo, as well as a post written here in &lt;a href="https://dev.to/mweibel/deploying-next-js-on-aws-elasticbeanstalk-ab4"&gt;June 2020 from Michael Weibel&lt;/a&gt;. This saved me some headaches (although I still had a few in working on this).&lt;/p&gt;

&lt;p&gt;While working on deploying a recent NextJS converted web app, I ran into a few issues, and after additional eyes from my teammates and the article, I was able to put together a current (and I write current since this will evolve eventually) Github Action that can build a NextJS project and get it deployed to AWS Elastic Beanstalk (EB) with minimal fuss. &lt;/p&gt;

&lt;p&gt;Let's review the steps in this example specific to a deploy to a QA/staging environment. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We want to Gzip the latest NextJS build after all approved pull requests are merged into QA. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We want to increment the version for our latest deployment. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We want the app to work. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For brevity's sake I'll note why:&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Beanstalk
&lt;/h3&gt;

&lt;p&gt;EB is a tool that makes it easy to deploy and scale applications. Here is the trick, there's not a lot of customization. You choose the platform, zip up your code and press a button. &lt;/p&gt;

&lt;p&gt;While this is effective in allowing AWS to handle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App health monitoring (complete with downloadable logs)&lt;/li&gt;
&lt;li&gt;Capacity Provisioning&lt;/li&gt;
&lt;li&gt;Load Balancing&lt;/li&gt;
&lt;li&gt;Security Updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't good if you have customization or need to live debug the deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Github Actions
&lt;/h3&gt;

&lt;p&gt;What we want to do, since we are depending on another resource to manage scale and capacity, we should go ahead and employ CI/CD to take care of the deployments for us. &lt;/p&gt;

&lt;p&gt;When running through this, you should of course have already setup your EB Instance and be able to click into the interface to monitor the health of the app (you will be able to in Github Actions too, but using the EB interface does offer some live health updates that Github Actions may not express. &lt;/p&gt;

&lt;p&gt;At the core of this post is the Github Action, this example assumes you have a QA branch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;QA Deploy&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qa"&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;14"&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate build number&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;buildnumber&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;einaregilsson/build-number@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{secrets.github_token}}&lt;/span&gt; 

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate deployment package&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run next-install &amp;amp;&amp;amp; npm run generate-zip&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to EB&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;einaregilsson/beanstalk-deploy@v18&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;aws_access_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_ACCESS_KEY }}&lt;/span&gt;
          &lt;span class="na"&gt;aws_secret_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_SECRET }}&lt;/span&gt;
          &lt;span class="na"&gt;application_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;name-of-your-project&lt;/span&gt;
          &lt;span class="na"&gt;environment_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;name-of-your-project-staging&lt;/span&gt;
          &lt;span class="na"&gt;version_label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;name-of-your-project-${{ steps.buildnumber.outputs.build_number }}&lt;/span&gt;
          &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-1&lt;/span&gt;
          &lt;span class="na"&gt;deployment_package&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy.zip&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This yaml file includes two nice Github action packages from Einar Egilsson: one is a simple build number provider and the other is his beanstalk-deploy, which is great for this exercise. If you'd rather use semver, I plan to update this article in the future with a way to do this. But for this, let's name our deployments with simple English. The version will read like this in the EB application detail view: name-of-your-project-1 (then 2, 3, etc.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Scripts to Build and GZIP the Build
&lt;/h3&gt;

&lt;p&gt;You'll notice two scripts in the generate deployment package, one installs and builds the project, the other zips the final build. I recommend that you create a &lt;code&gt;scripts&lt;/code&gt; folder with these &lt;code&gt;sh&lt;/code&gt; scripts in them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scripts
  - generate-zip.sh
  - next-install.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our &lt;code&gt;next-install&lt;/code&gt; script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; .next &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We want to be sure that we are generating a fresh next build, removing the build directory before the new build should overwrite errors that may have appeared in previous builds. &lt;/p&gt;

&lt;p&gt;Placing these commands in script files cleans up the deploy script and ensures sound organization and steps to the process. &lt;/p&gt;

&lt;p&gt;Here is the &lt;code&gt;generate-zip&lt;/code&gt; script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zip deploy.zip &lt;span class="nt"&gt;-r&lt;/span&gt; .next package.json next.config.js public .npmrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason we are including the public folder is so that the build has access to the assets that you have placed inside of it. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.npmrc&lt;/code&gt; file is in here in case you have any private or paid packages that you need to provide the auth for. If you don't the EB won't install those packages and your deployment will break.&lt;/p&gt;

&lt;p&gt;If you have additional configs from other plugins that you are using, include those in the script so they can be compressed as well.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Next Steps and Notes
&lt;/h3&gt;

&lt;p&gt;For troubleshooting, try building locally and running &lt;code&gt;next start&lt;/code&gt;. Then try a manual deployment by clicking upload in the EB application detail interface.&lt;/p&gt;

&lt;p&gt;Make sure that your &lt;code&gt;package.json&lt;/code&gt; provides a node version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"engines"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"14"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, in your &lt;code&gt;package.json&lt;/code&gt; make sure that you have the scripts you need in the action setup, and set the port to &lt;code&gt;8080&lt;/code&gt; for &lt;code&gt;next start&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next build"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next start -p 8080"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next lint"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"generate-zip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sh ./scripts/generate-zip.sh"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"next-install"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sh ./scripts/next-install.sh"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  This was brief, sorry!
&lt;/h3&gt;

&lt;p&gt;This works for a sound CI/CD process. In this example we used &lt;code&gt;qa&lt;/code&gt;, but if you need this for a production deployment on a &lt;code&gt;main&lt;/code&gt; branch, simply copy the yaml file and paste it into a &lt;code&gt;productionDeploy.yml&lt;/code&gt; or however you name your production deployments. You would only need to change the environment name and the branch you are pushing to. &lt;/p&gt;

&lt;p&gt;Again, this was meant as a brief intro to this, but one that hopefully prevents and/or won't lead to headaches when working in this unique stack.&lt;/p&gt;

&lt;p&gt;Shoutouts (I don't know you Einar, but thanks for the GH Action Packages):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/einaregilsson"&gt;Einar Egilsson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mweibel"&gt;Michael Weibel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;My teammates Zahnen and Adolfo!&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>github</category>
      <category>nextjs</category>
      <category>elasticbeanstalk</category>
    </item>
  </channel>
</rss>
