<?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: Dean Andreakis</title>
    <description>The latest articles on DEV Community by Dean Andreakis (@deanandreakis).</description>
    <link>https://dev.to/deanandreakis</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%2F267036%2F3d6368a3-6064-4779-bbb3-a123c1a713b3.jpg</url>
      <title>DEV Community: Dean Andreakis</title>
      <link>https://dev.to/deanandreakis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/deanandreakis"/>
    <language>en</language>
    <item>
      <title>Principles of Software Architecture</title>
      <dc:creator>Dean Andreakis</dc:creator>
      <pubDate>Tue, 28 Jan 2025 03:35:00 +0000</pubDate>
      <link>https://dev.to/deanandreakis/principles-of-software-architecture-420a</link>
      <guid>https://dev.to/deanandreakis/principles-of-software-architecture-420a</guid>
      <description>&lt;h3&gt;
  
  
  Principles of Software Architecture
&lt;/h3&gt;

&lt;p&gt;In the fast-paced world of technology, crafting a solid software architecture is crucial for creating applications that stand the test of time. If you're in the software development arena, you've likely come across three key principles: scalability, maintainability, and modularity. These principles are the backbone of any successful software system, helping ensure it remains robust and adaptable. Let's break these concepts down in a way that's both practical and relatable.&lt;/p&gt;

&lt;h4&gt;
  
  
  Scalability
&lt;/h4&gt;

&lt;p&gt;Scalability is all about ensuring your software can handle growth, whether it's a surge in users or an increase in data volume. Imagine your favorite app suddenly slows down or crashes when it becomes popular—that's a scalability issue.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Horizontal Scaling&lt;/strong&gt; : The ability to add more machines or instances to distribute the load, often employing techniques such as load balancing and clustering to spread traffic effectively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Vertical Scaling&lt;/strong&gt; : Enhancing the capabilities of an existing machine, such as increasing CPU or RAM, which is generally simpler but eventually hits physical limitations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Design Considerations&lt;/strong&gt; : Architect systems using stateless components where possible, allowing for easier distribution across multiple machines. Opt for technologies and frameworks that natively support scaling.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Below is a simplified diagram of an example of Scalability. By prioritizing scalability, architects can ensure long-term performance and user satisfaction as demands increase.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.some.pics%2Fdwa%2F679854d9621ef.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.some.pics%2Fdwa%2F679854d9621ef.png" title="Scalability" alt="Scalability" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Maintainability
&lt;/h4&gt;

&lt;p&gt;Maintainability deals with how easy it is to update and fix your software over time. Think of it like organizing a closet—easy-to-reach shelves and clearly labeled boxes make finding things a breeze.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Separation of Concerns&lt;/strong&gt; : Break down functionality into distinct sections, each responsible for a specific aspect of the application. This approach reduces complexity and makes code easier to understand and maintain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Clean Code Practices&lt;/strong&gt; : Write code that is not only functional but also readable and well-organized. Use meaningful variable names, consistent formatting, and comprehensive comments where necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automated Testing&lt;/strong&gt; : Incorporate unit and integration tests to catch bugs early and make refactoring less risky. Tests should be automated to ensure they are run consistently.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A maintainable architecture facilitates quicker updates and reduces the risk of introducing errors during enhancements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.some.pics%2Fdwa%2F679856d97cea1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.some.pics%2Fdwa%2F679856d97cea1.png" title="Maintainability" alt="Maintainability" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Modularity
&lt;/h4&gt;

&lt;p&gt;Modularity is about dividing your software into separate, interchangeable parts, much like building something with LEGO bricks. Each piece is self-contained, but together, they create your masterpiece.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Decoupling&lt;/strong&gt; : Design modules with minimal dependencies on each other. When modules are loosely coupled, changes to one module have minimal impact on others.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reusability&lt;/strong&gt; : A well-modularized system enables reusing components in different parts of the application or even in different projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Plug-and-Play&lt;/strong&gt; : Design systems where new modules can be easily integrated, and existing modules can be replaced with minimal impact on the overall system.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By embracing modularity, architects enable flexibility in development and deployment, allowing systems to adapt more quickly to change.&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;Whether you're sketching out a new project or refining an existing one, keeping these principles in mind will guide you toward building stronger software. Scalability, maintainability, and modularity aren’t just buzzwords—they’re the stepping stones to creating systems that are ready for whatever the future holds. By weaving these principles into your work, you're setting your software up for success, both today and in the long haul.&lt;/p&gt;

</description>
      <category>architecture</category>
    </item>
    <item>
      <title>Secrets Management w/ Firebase App Hosting and NextJS</title>
      <dc:creator>Dean Andreakis</dc:creator>
      <pubDate>Mon, 20 Jan 2025 21:00:00 +0000</pubDate>
      <link>https://dev.to/deanandreakis/secrets-management-w-firebase-app-hosting-and-nextjs-idl</link>
      <guid>https://dev.to/deanandreakis/secrets-management-w-firebase-app-hosting-and-nextjs-idl</guid>
      <description>&lt;h2&gt;
  
  
  Definition
&lt;/h2&gt;

&lt;p&gt;I am using &lt;a href="https://firebase.google.com/docs/app-hosting" rel="noopener noreferrer"&gt;Firebase App Hosting&lt;/a&gt; as a backend for a NextJS app that I am developing. I am also using the &lt;a href="https://firebase.google.com/docs/cli" rel="noopener noreferrer"&gt;Firebase CLI&lt;/a&gt; to configure and manage my Firebase project. One of the many challenges along the way was how to manage secrets within the app. Secrets can be anything you determine to be sensitive information such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;API Keys: Tokens used to authenticate requests to an Application Programming Interface (API). They grant access to services and should be kept confidential.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passwords: Credentials used for user authentication to access systems or services. These should be stored securely, usually hashed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Private Keys: Cryptographic keys used for encryption, signing, or authentication processes. These should be kept confidential at all times.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Encryption Keys: Keys used to encrypt and decrypt data. These must be securely stored to prevent unauthorized access to sensitive data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Access Tokens: Tokens that grant access to specific resources or systems, often used in OAuth and other authentication protocols.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database Credentials: Usernames and passwords used to connect to databases. These should be kept secure to prevent unauthorized database access.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Certificates: Digital certificates that authenticate the identity of systems and encrypt data. Private certificates should be kept secret.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SSH Keys: Used for secure shell (SSH) access to servers. The private SSH key should remain confidential to ensure secure server access.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Webhooks Secrets: Tokens or keys used to validate and secure webhooks communication.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Personal Identifiable Information (PII): When it's part of the application code or logs, it's considered sensitive.  &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;Common best-practice is to not commit secrets to a repository and instead use a method to allow for referencing of the secret in production that does not reveal the actual secret value. &lt;/p&gt;

&lt;p&gt;It is common during development to put secrets in a local environment file that is not committed to a repository. One way to do this is to include a reference to the environment file in the .gitignore file of the project. This method is less than ideal during production as the environment file containing the secrets would have to be managed outside of git (or whatever configuration management tool used).&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;The solution for production is to use the Secret Manager service that is part of Google Cloud Platform. If you login to the &lt;a href="https://console.cloud.google.com" rel="noopener noreferrer"&gt;GCP console&lt;/a&gt; and search for "Secret Manager" you should see something similar to the below screenshot:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.some.pics%2Fdwa%2F678ec18ac97c1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.some.pics%2Fdwa%2F678ec18ac97c1.png" title="GCP Secret Manager" alt="GCP Secret Manager" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on "Create Secret" and it should take you to a page where you can add the necessary information as seen below: &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.some.pics%2Fdwa%2F678ecc19e3c49.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.some.pics%2Fdwa%2F678ecc19e3c49.png" title="Add a new secret" alt="Add a new secret" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you add a new secret in the GCP secret manager then you can go back to your project directory and enter the following command in a terminal using the firebase cli tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;firebase apphosting:secrets:grantaccess -b &amp;lt;firebase-project-backend-name&amp;gt; &amp;lt;name-of secret&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, you can then add a reference to the secret in your projects apphosting.yaml file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;env:
  - variable: &amp;lt;name referenced by your code&amp;gt;
    secret: &amp;lt;name of secret from GCP secret manager&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your code can now reference the secret as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const secret = process.env.&amp;lt;name-of-secret&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>nextjs</category>
      <category>firebase</category>
      <category>secret</category>
    </item>
    <item>
      <title>Deploying a Shopify Node App Docker Image to GCP</title>
      <dc:creator>Dean Andreakis</dc:creator>
      <pubDate>Fri, 10 Sep 2021 15:36:58 +0000</pubDate>
      <link>https://dev.to/deanandreakis/deploying-a-shopify-node-app-docker-image-to-gcp-417d</link>
      <guid>https://dev.to/deanandreakis/deploying-a-shopify-node-app-docker-image-to-gcp-417d</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/deanandreakis/dockerizing-a-shopify-node-app-1djf"&gt;my last post&lt;/a&gt; I showed how to take a Shopify node app and dockerize it. In this post I will show you how to take that docker image and deploy it to GCP using Google Artifact Registry and Google Cloud Run services. I will also show the Shopify app configuration, installation and execution in a Shopify development store used for testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;We will assume that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A GCP account has been created at console.cloud.google.com&lt;/li&gt;
&lt;li&gt;A project has been created in GCP for your Shopify app&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://cloud.google.com/sdk/gcloud" rel="noopener noreferrer"&gt;gcloud CLI&lt;/a&gt; has been installed&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://docs.docker.com/engine/reference/commandline/cli/" rel="noopener noreferrer"&gt;docker CLI&lt;/a&gt; has been installed&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Setup Google Cloud Platform (GCP)
&lt;/h2&gt;

&lt;p&gt;We will first setup GCP to accept and store the docker container image and then to deploy and run that image on Google Cloud Run.&lt;/p&gt;

&lt;p&gt;An overview of these steps can be found &lt;a href="https://cloud.google.com/artifact-registry/docs/transition/changes-docker" rel="noopener noreferrer"&gt;here&lt;/a&gt; but I will show the specific commands for my dockerized Shopify node app named "shnode":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In IAM add the Artifact Registry Administrator role to your GCP user.&lt;/li&gt;
&lt;li&gt;Go to the Artifact Registry service and make sure the API is enabled.&lt;/li&gt;
&lt;li&gt;In the Artifact Registry select the "create a repository" button. Make sure you select type "Docker" for the repository type.&lt;/li&gt;
&lt;li&gt;Authenticate to the repository as follows:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gcloud auth configure-docker us-west4-docker.pkg.dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where us-west4-docker.pkg.dev is the location of the repository we created. We can see this information in the list of repositories:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ujr3xjtc6uz69nhrc6o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ujr3xjtc6uz69nhrc6o.png" alt="Screen Shot 2021-09-09 at 4.59.13 PM" width="800" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tag your docker image as follows:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker tag shnode us-west4-docker.pkg.dev/shopify-319117/shnode/shnode:1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where the format is us-west4-docker.pkg.dev/my-gcp-project/my-repo/my-image:tag1&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Push the container to GCP Artifact Registry:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker push us-west4-docker.pkg.dev/shopify-319117/shnode/shnode:1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a GCP Cloud Run service: Go to GCP Cloud Run and select the "create a service" button. Once you create a service you will be able to see the URL of the service. We will refer to this URL as &lt;strong&gt;HOST&lt;/strong&gt; in the next section where we setup the Shopify app itself:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj17w0q0ryguhux4fbq60.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj17w0q0ryguhux4fbq60.png" alt="Screen Shot 2021-09-09 at 5.33.46 PM" width="800" height="178"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deploy the image to GCP Cloud Run and start it up:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gcloud run deploy --image us-west4-docker.pkg.dev/shopify-319117/shnode/shnode:1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup Shopify App
&lt;/h2&gt;

&lt;p&gt;The Shopify node app must be setup properly in order for it to be installed and executed in a Shopify store. We will assume that the Shopify app has already been created in your Shopify partner account. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the App setup page for your app in your Shopify partner account and make sure the URL's in the URLs section match the &lt;strong&gt;HOST&lt;/strong&gt; URL from above when we created the GCP Cloud Run service:
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4pwjvj29xza0vv9vt2it.png" alt="Screen Shot 2021-09-09 at 5.23.46 PM" width="800" height="323"&gt;
&lt;/li&gt;
&lt;li&gt;In your Shopify partner account install the app to your development store using the "test your app" section of the app details page:
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgx22kb5bvlwjykap9b6p.png" alt="Screen Shot 2021-09-09 at 5.44.01 PM" width="800" height="614"&gt;
&lt;/li&gt;
&lt;li&gt;The Shopify app source tree itself includes a .env file that has a HOST environment variable. Make sure this matches the &lt;strong&gt;HOST&lt;/strong&gt; URL from above when we created the GCP Cloud Run service. If you update this .env file then you will have to rebuild your docker image and re-deploy. To rebuild go to the root of your Shopify app source tree and issue the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t shnode .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where "shnode" is the image name. At this point you can continue the deployment from the above section "Setup Google Cloud Platform (GCP)" where we tag the docker image.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>node</category>
      <category>googlecloud</category>
      <category>shopify</category>
    </item>
    <item>
      <title>Dockerizing a Shopify Node App</title>
      <dc:creator>Dean Andreakis</dc:creator>
      <pubDate>Thu, 08 Jul 2021 21:17:08 +0000</pubDate>
      <link>https://dev.to/deanandreakis/dockerizing-a-shopify-node-app-1djf</link>
      <guid>https://dev.to/deanandreakis/dockerizing-a-shopify-node-app-1djf</guid>
      <description>&lt;p&gt;I am in the process of learning to develop apps for the Shopify platform. In doing so, I wanted to establish early on how I would be deploying and managing my apps. I recently earned my &lt;a href="https://www.credential.net/6554ea1d-24f7-4373-acf9-04cdc1504619#gs.5w943v" rel="noopener noreferrer"&gt;GCP Professional Cloud Architect certification&lt;/a&gt; so I was pretty sure I would be using GCP in production. I decided that the easiest way to deploy and manage my apps in production would be to containerize them using &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;. If your not familiar with what a container is I highly recommend reading &lt;a href="https://www.docker.com/resources/what-container" rel="noopener noreferrer"&gt;this overview&lt;/a&gt; on the docker site. TLDR; a container packages a software application and its dependencies so that it can execute across different environments without the need to pre-configure those environments.&lt;/p&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requisites:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; v16.4.2&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.docker.com/products/docker-desktop" rel="noopener noreferrer"&gt;Docker desktop&lt;/a&gt; v3.5&lt;/li&gt;
&lt;li&gt;&lt;a href="https://shopify.dev/apps/tools/cli/installation" rel="noopener noreferrer"&gt;Shopify CLI&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Initial Steps
&lt;/h2&gt;

&lt;p&gt;I started by following along the &lt;a href="https://shopify.dev/apps/getting-started/create" rel="noopener noreferrer"&gt;Shopify quick start guide&lt;/a&gt; that shows you how to use the Shopify CLI tool to quickly create an app and install and run it on a Shopify development store. I won't go thru the steps here but I do recommend going thru them yourself.&lt;/p&gt;

&lt;p&gt;Once you have followed the Shopify quick start guide as described above, you will have used the Shopify CLI tool to create an example app and then to also serve it up on your local development system. The commands that the quick start guide uses are as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;shopify node create&lt;/li&gt;
&lt;li&gt;shopify node serve&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first command scaffolds a new Node.js app in a subdirectory and creates your app in the Shopify Partner Dashboard.&lt;/p&gt;

&lt;p&gt;The second command starts an ngrok tunnel, updates the .env file in your app project, updates information about the app in the Shopify Partner dashboard and then actually starts the app locally.&lt;/p&gt;

&lt;p&gt;Go ahead and issue these two commands per the guide and see that your app is running in your development store. Next, stop the app from executing locally once you have verified it working in your development store.&lt;/p&gt;

&lt;p&gt;In our case we want to package our app into a docker container and then execute that container. &lt;/p&gt;

&lt;h2&gt;
  
  
  Docker
&lt;/h2&gt;

&lt;p&gt;We first need to create a file called 'Dockerfile' in the root of our apps project directory. Here is a Dockerfile that I created that will work with the Shopify quickstart app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:16.4&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package.json /app&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--production&lt;/span&gt; &lt;span class="nt"&gt;--legacy-peer-deps&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /app&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; npm run start&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8081&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is also good practice to create a .dockerignore file also in the app project root so unnecessary items don't end up in the docker image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dockerfile
.dockerignore
node_modules
npm-debug.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we have these files in place, go ahead and issue the following command in the root of your project app directory. This will create the Docker image for the app:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker build -t &amp;lt;project_name&amp;gt; .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here is a screenshot of the command output:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgev3liezcisrwe4hop3u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgev3liezcisrwe4hop3u.png" alt="Docker build command output" width="800" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point the Docker image for the app has been created. We can now run the app in the container with the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run -p 8081:8081 &amp;lt;project_name&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You should be able to go back to your Shopify development store and see the app running. Note that the '8081:8081' part of the command specifies the PORT that the Docker image will listen on. In the case of the Shopify quick-start example the PORT is defaulted to 8081.&lt;/p&gt;

&lt;p&gt;We now have a Docker image of our Shopify app that we can either run locally using the Docker desktop tool or deploy to the cloud and execute there. This makes the job of deploying the app much easier as we won't have to worry about configuring a server. In my &lt;a href="https://dev.to/deanandreakis/deploying-a-shopify-node-app-docker-image-to-gcp-417d"&gt;next post&lt;/a&gt; I will talk about using GCP Container Registry and GCP Cloud Run to manage and execute my app containers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Last Notes and Gotchas
&lt;/h2&gt;

&lt;p&gt;It is important to note that because we worked-thru the Shopify quick-start example first, the details of creating an app locally, configuring the app in the Shopify Partner dashboard, starting ngrok, updating the .env file in the project etc. are taken care of behind the scenes by the two (2) shopify CLI commands I mentioned earlier:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;shopify node create&lt;/li&gt;
&lt;li&gt;shopify node serve&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If we were starting a new app and wanted to create a Docker image for that app we could just issue the commands above first as in the guide and then go back and create the Dockerfile and build the image as defined above.&lt;/p&gt;

&lt;p&gt;Alternatively, we may just want to issue the first command (shopify node create) and then take care of everything else ourselves instead of issuing the second command (shopify node serve). In that case we have a few things to take care of before building the Docker image:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Execute &lt;code&gt;ngrok http &amp;lt;PORT&amp;gt;&lt;/code&gt; where PORT is the port your apps server is listening on.&lt;/li&gt;
&lt;li&gt;Update the .env file in the app project: The 'HOST' variable needs to be updated with the URL that ngrok displayed above.&lt;/li&gt;
&lt;li&gt;Update the .env file in the app project: The 'SHOPIFY_API_KEY' and 'SHOPIFY_API_SECRET' must match the values from the app information in the Shopify Partner dashboard.&lt;/li&gt;
&lt;li&gt;Update the app information in the Shopify Partner dashboard. The app url and app redirect url(s) must be updated to match the ngrok url:
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fajk5jhwankz7hruns0f7.png" alt="App URls" width="800" height="348"&gt;
&lt;/li&gt;
&lt;li&gt;Install the app into your Shopify development store by visiting the following url in your browser:
&lt;code&gt;https://&amp;lt;ngrok_url&amp;gt;/auth?shop=&amp;lt;store_name&amp;gt;.myshopify.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>node</category>
      <category>docker</category>
      <category>shopify</category>
      <category>react</category>
    </item>
    <item>
      <title>Great SVG Resource for your next Web App</title>
      <dc:creator>Dean Andreakis</dc:creator>
      <pubDate>Tue, 16 Feb 2021 21:33:41 +0000</pubDate>
      <link>https://dev.to/deanandreakis/great-svg-resource-for-your-next-web-app-85d</link>
      <guid>https://dev.to/deanandreakis/great-svg-resource-for-your-next-web-app-85d</guid>
      <description>&lt;p&gt;I found myself working on a React app the other day and needing to add some style and interest with images. I am not a designer so any help I can get in making a web app look professional is greatly appreciated. I decided since the web app should be responsive I would use SVG images. &lt;a href="https://en.wikipedia.org/wiki/Scalable_Vector_Graphics" rel="noopener noreferrer"&gt;SVG (or Scaleable Vector Graphics)&lt;/a&gt; is an XML-based vector image format for 2D images.&lt;/p&gt;

&lt;p&gt;Using them in a React app is fairly easy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;example&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../assets/img/example.svg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./example.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Example&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;img-part&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Advantages to using SVG images are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;They rescale perfectly as a user resizes the application. &lt;/li&gt;
&lt;li&gt;Since SVG is XML-based it is a good candidate for lossless data compression algorithms which can mean much smaller file sizes for your images.&lt;/li&gt;
&lt;li&gt;Since SVG is XML-based the image file is directly editable and is also easily edited by vector image programs such as &lt;a href="https://inkscape.org" rel="noopener noreferrer"&gt;Inkscape&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In my search for a good set of SVG images I came across &lt;a href="//undraw.co"&gt;unDraw&lt;/a&gt;. Undraw is a set of SVG images from designers that wish to contribute to the open source community. I was very impressed with the beauty, style, and huge selection of SVG images. An example of one of the images is the cover photo of this blog post. &lt;/p&gt;

&lt;p&gt;One of the unique things about this set of SVG images is that you can adjust the color of the images as seen here: &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw3j9e3dqgnul47naqteq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw3j9e3dqgnul47naqteq.png" alt="unDraw color chooser" width="800" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;unDraw also includes a very good keyword search tool which makes it easy to find images that fit with the subject matter of your app: &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hgfxp4i051p8w5hhjjb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hgfxp4i051p8w5hhjjb.png" alt="unDraw image search" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://undraw.co/license" rel="noopener noreferrer"&gt;license for unDraw&lt;/a&gt; is very permissive as the TLDR; is &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;you can use the illustrations in any project, commercial or personal without attribution or any costs. Just don’t try to replicate unDraw, redistribute in packs the illustrations or create integrations for it.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
