<?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>Forem: chauhoangminhnguyen</title>
    <description>The latest articles on Forem by chauhoangminhnguyen (@chauhoangminhnguyen).</description>
    <link>https://forem.com/chauhoangminhnguyen</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%2F1269808%2F5efb3b0e-293f-49a2-8649-70f0a5845eee.jpeg</url>
      <title>Forem: chauhoangminhnguyen</title>
      <link>https://forem.com/chauhoangminhnguyen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/chauhoangminhnguyen"/>
    <language>en</language>
    <item>
      <title>Kubernetes Horizontal Pod Autoscaling</title>
      <dc:creator>chauhoangminhnguyen</dc:creator>
      <pubDate>Tue, 24 Sep 2024 14:00:00 +0000</pubDate>
      <link>https://forem.com/chauhoangminhnguyen/kubernetes-horizontal-pod-autoscaling-35io</link>
      <guid>https://forem.com/chauhoangminhnguyen/kubernetes-horizontal-pod-autoscaling-35io</guid>
      <description>&lt;p&gt;&lt;a href="https://media.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%2Fz8ph6epl1753b7d90fup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fz8ph6epl1753b7d90fup.png" alt="K8s HPA"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;There are two common scaling methods: &lt;strong&gt;Vertical scaling&lt;/strong&gt; and &lt;strong&gt;Horizontal scaling&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vertical scaling&lt;/strong&gt; involves adding more hardware, such as &lt;strong&gt;RAM or CPU&lt;/strong&gt;, or increasing the number of server nodes. &lt;strong&gt;Horizontal scaling&lt;/strong&gt;, on the other hand, means adding more instances of an app to fully utilize the available resources on a node or server.&lt;/p&gt;

&lt;p&gt;However, horizontal scaling has its limits. Once a node's resources are maxed out, vertical scaling becomes necessary. This article will focus on horizontal scaling using &lt;strong&gt;Kubernetes Horizontal Pod Autoscaling (HPA)&lt;/strong&gt;, which automatically scales resources up or down based on system demands.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F2sn1qlq4thm4g68k7t30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F2sn1qlq4thm4g68k7t30.png" alt="Horizontal/Vertical scale"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation Process
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;1. Build a Docker image for your application.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;2. Deploy the image using a Deployment and LoadBalancer service.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;3. Configure HPA to automatically scale resources.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To use &lt;strong&gt;HPA&lt;/strong&gt; for auto-scaling based on &lt;strong&gt;CPU/Memory&lt;/strong&gt;, &lt;strong&gt;Kubernetes&lt;/strong&gt; must have the &lt;strong&gt;metrics-server&lt;/strong&gt; installed. If you’re using a cloud provider, the &lt;strong&gt;metrics-server&lt;/strong&gt; is usually installed by default. For local Kubernetes setups, you need to manually install the &lt;strong&gt;metrics-server&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/06/setting-up-kubernetes-dashboard-with-kind.html" rel="noopener noreferrer"&gt;If you’re using &lt;strong&gt;Kind&lt;/strong&gt; for a &lt;strong&gt;local Kubernetes&lt;/strong&gt; setup&lt;/a&gt;, follow these steps to install the &lt;strong&gt;metrics-server&lt;/strong&gt; after successfully creating the cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or install with &lt;strong&gt;Helm&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add k8s-dashboard https://kubernetes.github.io/dashboard
helm upgrade &lt;span class="nt"&gt;--install&lt;/span&gt; kubernetes-dashboard k8s-dashboard/kubernetes-dashboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Build a Docker Image for the Application
&lt;/h3&gt;

&lt;p&gt;Use the following code block to create a &lt;strong&gt;NodeJS Express Server&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&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;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is NodeJS Typescript Application! Current time is &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&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="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/sum&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&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="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server is running http://localhost:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's build the &lt;strong&gt;Docker image&lt;/strong&gt; and push it to &lt;strong&gt;Google Artifact Registry&lt;/strong&gt; or &lt;strong&gt;Docker Hub&lt;/strong&gt;. &lt;a href="https://howtodevez.blogspot.com/2024/05/deploying-a-nodejs-server-on-google-kubernetes-engine.html" rel="noopener noreferrer"&gt;You can refer to my guide on how to do this here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Deploy the image using a Deployment and a LoadBalancer service
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;deployment.yml\&lt;/code&gt; file that includes the configuration for the Deployment to deploy the image you built, along with a LoadBalancer service, as shown below:&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;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&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;deployment-name&lt;/span&gt;
  &lt;span class="na"&gt;labels&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;label-name&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;label-name&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;label-name&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;restartPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Always&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&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;express-ts&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;express-ts&lt;/span&gt;
          &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# min&lt;/span&gt;
              &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;100Mi"&lt;/span&gt;
              &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;100m"&lt;/span&gt;
            &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# max&lt;/span&gt;
              &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;300Mi"&lt;/span&gt;
              &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;300m"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&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;service-name&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;label-name&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;label-name&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LoadBalancer&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt; &lt;span class="c1"&gt;# port service&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3000&lt;/span&gt; &lt;span class="c1"&gt;# port pod&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/05/deploying-a-nodejs-server-on-google-kubernetes-engine.html" rel="noopener noreferrer"&gt;I've explained the details about deployment and the LoadBalancer service in this article.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, we also cover resource configuration. You can choose to configure CPU, Memory, or both, depending on which parameters you want to scale.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If you define resource values, you can scale by a percentage of the initially defined resources.&lt;/li&gt;
&lt;li&gt;  If you don't define resource values, you must specify the exact resource values to scale.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Configuring HPA for Auto-scaling Resources
&lt;/h3&gt;

&lt;p&gt;You can include the HPA configuration either in your &lt;code&gt;deployment.yml\&lt;/code&gt; file or in a separate file with the following content:&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;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;autoscaling/v2&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HorizontalPodAutoscaler&lt;/span&gt;
&lt;span class="na"&gt;metadata&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;hpa-name&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;scaleTargetRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
    &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&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;deployment-name&lt;/span&gt; &lt;span class="c1"&gt;# target to deployment&lt;/span&gt;
  &lt;span class="na"&gt;minReplicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;maxReplicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
  &lt;span class="na"&gt;metrics&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Resource&lt;/span&gt;
      &lt;span class="na"&gt;resource&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;cpu&lt;/span&gt; &lt;span class="c1"&gt;# scale base on CPU&lt;/span&gt;
        &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Utilization&lt;/span&gt;
          &lt;span class="na"&gt;averageUtilization&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt; &lt;span class="c1"&gt;# target 80%&lt;/span&gt;
  &lt;span class="na"&gt;behavior&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;scaleDown&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;policies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pods&lt;/span&gt;
          &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;
          &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
      &lt;span class="na"&gt;stabilizationWindowSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;120&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;minReplicas&lt;/strong&gt;, &lt;strong&gt;maxReplicas&lt;/strong&gt;: min and max scaling resource&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;metrics&lt;/strong&gt;: Define the type of resource you want to scale; in this case, it's the CPU.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;averageUtilization&lt;/strong&gt;: This is a percentage. When it exceeds this value, the system will scale up.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;behavior&lt;/strong&gt;: This is optional. Here, it's used to define the scale-down behavior, allowing a maximum of 3 Pods to scale down in 30 seconds.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;stabilizationWindowSeconds&lt;/strong&gt;: When the system remains stable for this duration, it will scale down (the default value is 5 minutes).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, apply to create the resource as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; deployment.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: I've defined all resources in a single file for simplicity, but in practice, you should separate each resource into individual &lt;strong&gt;YAML&lt;/strong&gt; files for better management.&lt;/p&gt;

&lt;p&gt;Information on the resource once created:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fjo2sk7qqi5aj5cjx6u58.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fjo2sk7qqi5aj5cjx6u58.png" alt="kubectl get all"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please ensure that this API is working so we can continue testing the HPA.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F10iwmt280sqefen32b8y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F10iwmt280sqefen32b8y.png" alt="Deployed"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing HPA
&lt;/h2&gt;

&lt;p&gt;You can test the API using any method you know. Here, I provide a code block to send 10 requests every second. Replace the URL with the EXTERNAL-IP of the LoadBalancer service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numOfRequest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://172.23.0.3/sum?value=10000000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numOfRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Completed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&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="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After executing, the server resources will gradually increase, triggering the auto-scaling process.&lt;/p&gt;

&lt;p&gt;You can check if HPA has performed the auto-scaling as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fr6hri4p0w92zg8ke1cl9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fr6hri4p0w92zg8ke1cl9.png" alt="kubectl get hpa"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will notice that the number of Replicas will gradually increase when the CPU usage exceeds the 80% target (field value &lt;strong&gt;averageUtilization&lt;/strong&gt;) and will gradually decrease after a period of time (field value &lt;strong&gt;stabilizationWindowSeconds&lt;/strong&gt;) when the system stabilizes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;See you in the next articles!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you found this content helpful, please visit &lt;a href="https://howtodevez.blogspot.com/2024/06/kubernetes-horizontal-pod-autoscaling.html" rel="noopener noreferrer"&gt;the original article on my blog&lt;/a&gt; to support the author and explore more interesting content.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/03/sitemap.html" rel="noreferrer noopener"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2FBlogger-FF5722%3Fstyle%3Dfor-the-badge%26logo%3Dblogger%26logoColor%3Dwhite" alt="Blogspot"&gt;&lt;/a&gt;&lt;a href="https://howtodevez.medium.com" rel="noreferrer noopener"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2FMedium-12100E%3Fstyle%3Dfor-the-badge%26logo%3Dmedium%26logoColor%3Dwhite" alt="Blogspot"&gt;&lt;/a&gt;&lt;a href="https://dev.to/chauhoangminhnguyen" rel="noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2Fdev.to-0A0A0A%3Fstyle%3Dfor-the-badge%26logo%3Ddev.to%26logoColor%3Dwhite" alt="Dev.to"&gt;&lt;/a&gt;&lt;a href="https://www.facebook.com/profile.php?id=61557154776384" rel="noreferrer noopener"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2FFacebook-1877F2%3Fstyle%3Dfor-the-badge%26logo%3Dfacebook%26logoColor%3Dwhite" alt="Facebook"&gt;&lt;/a&gt;&lt;a href="https://x.com/DavidNguyenSE" rel="noreferrer noopener"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2FX-000000%3Fstyle%3Dfor-the-badge%26logo%3Dx%26logoColor%3Dwhite" alt="X"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Some series you might find interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/nodejs-practice-series.html" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://howtodevez.blogspot.com/2024/08/react-practice-series.html" rel="noopener noreferrer"&gt;React&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://howtodevez.blogspot.com/2024/08/docker-practice-series.html" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/kubernetes-practice-series.html" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/google-cloud-platform-practice-series.html" rel="noopener noreferrer"&gt;Google Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/devops-practice-series.html" rel="noopener noreferrer"&gt;DevOps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>beginners</category>
      <category>autoscale</category>
    </item>
    <item>
      <title>SSH to Google Compute Engine</title>
      <dc:creator>chauhoangminhnguyen</dc:creator>
      <pubDate>Mon, 23 Sep 2024 14:00:00 +0000</pubDate>
      <link>https://forem.com/chauhoangminhnguyen/ssh-to-google-compute-engine-1naj</link>
      <guid>https://forem.com/chauhoangminhnguyen/ssh-to-google-compute-engine-1naj</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/05/using-terraform-to-create-vm-instances-and-connect-via-ssh.html" rel="noopener noreferrer"&gt;I previously wrote a guide on creating a &lt;strong&gt;Virtual Machine (VM) instance&lt;/strong&gt; on &lt;strong&gt;Google Cloud&lt;/strong&gt; and accessing it via &lt;strong&gt;gcloud&lt;/strong&gt;&lt;/a&gt;. However, if your &lt;strong&gt;Google Cloud&lt;/strong&gt; account lacks permission to manage VM instances, or if you want to create a &lt;strong&gt;VM instance&lt;/strong&gt; that allows &lt;strong&gt;SSH&lt;/strong&gt; for easy sharing with other users and compatibility with various &lt;strong&gt;SSH&lt;/strong&gt; tools, follow the steps below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjrd4hl8sld4loli8doso.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjrd4hl8sld4loli8doso.png" alt="SSH to VM instance" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure SSH access for VM instance
&lt;/h2&gt;

&lt;p&gt;Firstly, you need to create a compute instance as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud compute instances create &lt;span class="o"&gt;{&lt;/span&gt;instance name&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--zone&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;zone&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--machine-type&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;machine &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# ex:&lt;/span&gt;
gcloud compute instances create instance-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;asia-southeast1-a &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--machine-type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;e2-micro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, &lt;strong&gt;SSH&lt;/strong&gt; into this &lt;strong&gt;VM&lt;/strong&gt; to perform the necessary configurations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjodvb6kk226ieho2tduw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjodvb6kk226ieho2tduw.png" alt="VM instances" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Typically, a &lt;strong&gt;Google VM instance&lt;/strong&gt; will have a &lt;strong&gt;Distributor ID&lt;/strong&gt; of &lt;strong&gt;Debian&lt;/strong&gt;. Use the following command to check this before proceeding with the next steps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lsb_release &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4922wpatnhfqrerln824.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4922wpatnhfqrerln824.png" alt="lsb_release" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, set the password for the root account as follows:&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;sudo &lt;/span&gt;passwd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, use the &lt;strong&gt;Vim editor&lt;/strong&gt; to change the settings in the &lt;strong&gt;&lt;em&gt;sshd_config&lt;/em&gt;&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vi /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz81iw43ms4rs34kuq184.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz81iw43ms4rs34kuq184.png" alt="Edit sshd_config" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Find and change the following fields to the following values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PermitRootLogin yes
PasswordAuthentication yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're not familiar with using the &lt;strong&gt;Vim editor&lt;/strong&gt;, you can use the following commands to edit the &lt;strong&gt;&lt;em&gt;sshd_config&lt;/em&gt;&lt;/strong&gt; file:&lt;/p&gt;

&lt;p&gt;- &lt;strong&gt;&lt;em&gt;i&lt;/em&gt;&lt;/strong&gt;: Switch to interactive mode (allows editing)&lt;/p&gt;

&lt;p&gt;- &lt;strong&gt;&lt;em&gt;Esc&lt;/em&gt;&lt;/strong&gt;: Switch to normal mode (allows using commands)&lt;/p&gt;

&lt;p&gt;- &lt;strong&gt;&lt;em&gt;:wq&lt;/em&gt;&lt;/strong&gt;: Write then quit (saves and closes the file)&lt;/p&gt;

&lt;p&gt;After successfully updating the configuration, restart the service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl restart sshd.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  SSH to a VM Instance
&lt;/h2&gt;

&lt;p&gt;First, you need to obtain the &lt;strong&gt;External IP&lt;/strong&gt; of the &lt;strong&gt;VM instance&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fosnmbvphgnhsm5cazx00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fosnmbvphgnhsm5cazx00.png" alt="VM instances" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To &lt;strong&gt;SSH&lt;/strong&gt; into the &lt;strong&gt;VM instance&lt;/strong&gt;, use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh root@34.126.104.206
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After entering your password, the &lt;strong&gt;SSH&lt;/strong&gt; connection will be successful.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Farywj1k2cs852mfiddp3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Farywj1k2cs852mfiddp3.png" alt="ssh" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also use SSH tools or file managers like &lt;strong&gt;WinSCP&lt;/strong&gt;, &lt;strong&gt;PuTTY&lt;/strong&gt;, or &lt;strong&gt;Remmina&lt;/strong&gt;, depending on your needs. These tools make it easy to work with your &lt;strong&gt;VM&lt;/strong&gt; and allow you to save your &lt;strong&gt;SSH&lt;/strong&gt; info for future connections.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fttq2gpkqzzzijld8436f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fttq2gpkqzzzijld8436f.png" alt="Remmina connected" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Feel free to leave your thoughts in the comments, and don’t forget to like, share, and follow for more great content!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you found this content helpful, please visit &lt;a href="https://howtodevez.blogspot.com/2024/06/ssh-to-google-compute-engine.html" rel="noopener noreferrer"&gt;the original article on my blog&lt;/a&gt; to support the author and explore more interesting content.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/03/sitemap.html" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Rehh51y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Blogger-FF5722%3Fstyle%3Dfor-the-badge%26logo%3Dblogger%26logoColor%3Dwhite" alt="Blogspot" width="102" height="28"&gt;&lt;/a&gt;&lt;a href="https://howtodevez.medium.com" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NabPkFNQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Medium-12100E%3Fstyle%3Dfor-the-badge%26logo%3Dmedium%26logoColor%3Dwhite" alt="Blogspot" width="94" height="28"&gt;&lt;/a&gt;&lt;a href="https://dev.to/chauhoangminhnguyen" rel="noreferrer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xz2MGu8c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/dev.to-0A0A0A%3Fstyle%3Dfor-the-badge%26logo%3Ddev.to%26logoColor%3Dwhite" alt="Dev.to" width="88" height="28"&gt;&lt;/a&gt;&lt;a href="https://www.facebook.com/profile.php?id=61557154776384" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hohnj5TU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Facebook-1877F2%3Fstyle%3Dfor-the-badge%26logo%3Dfacebook%26logoColor%3Dwhite" alt="Facebook" width="111" height="28"&gt;&lt;/a&gt;&lt;a href="https://x.com/DavidNguyenSE" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tT2E75Wa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/X-000000%3Fstyle%3Dfor-the-badge%26logo%3Dx%26logoColor%3Dwhite" alt="X" width="52" height="28"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Some series you might find interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/nodejs-practice-series.html" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://howtodevez.blogspot.com/2024/08/react-practice-series.html" rel="noopener noreferrer"&gt;React&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://howtodevez.blogspot.com/2024/08/docker-practice-series.html" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/kubernetes-practice-series.html" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/google-cloud-platform-practice-series.html" rel="noopener noreferrer"&gt;Google Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/devops-practice-series.html" rel="noopener noreferrer"&gt;DevOps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>googlecloud</category>
      <category>virtualmachine</category>
      <category>beginners</category>
      <category>gcp</category>
    </item>
    <item>
      <title>Setting Up an EXTERNAL-IP for Local LoadBalancer Service</title>
      <dc:creator>chauhoangminhnguyen</dc:creator>
      <pubDate>Sun, 22 Sep 2024 14:00:00 +0000</pubDate>
      <link>https://forem.com/chauhoangminhnguyen/setting-up-an-external-ip-for-local-loadbalancer-service-4914</link>
      <guid>https://forem.com/chauhoangminhnguyen/setting-up-an-external-ip-for-local-loadbalancer-service-4914</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/05/deploying-a-nodejs-server-on-google-kubernetes-engine.html" rel="noopener noreferrer"&gt;If you've used a &lt;strong&gt;LoadBalancer&lt;/strong&gt; service from a &lt;strong&gt;Cloud Provider&lt;/strong&gt;&lt;/a&gt;, you'll know how convenient it is to have an &lt;strong&gt;EXTERNAL-IP&lt;/strong&gt; assigned automatically. However, when using &lt;strong&gt;local&lt;/strong&gt; &lt;strong&gt;Kubernetes&lt;/strong&gt;, the default setting doesn't provide an &lt;strong&gt;EXTERNAL-IP&lt;/strong&gt;. Building on our previous discussion, this guide will show you how to use &lt;strong&gt;&lt;em&gt;cloud-provider-kind&lt;/em&gt;&lt;/strong&gt; to assign an &lt;strong&gt;EXTERNAL-IP&lt;/strong&gt; to your &lt;strong&gt;local LoadBalancer service&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;First, make sure you've &lt;a href="https://howtodevez.blogspot.com/2024/06/setting-up-kubernetes-dashboard-with-kind.html" rel="noopener noreferrer"&gt;set up your &lt;strong&gt;local Kubernetes&lt;/strong&gt; using &lt;strong&gt;Kind&lt;/strong&gt;&lt;/a&gt; as outlined in my previous guide. This is necessary to proceed with the next steps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4e5911q1yz9z1gebtzn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4e5911q1yz9z1gebtzn.png" alt="Local Load Balancer" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing cloud-provider-kind
&lt;/h2&gt;

&lt;p&gt;Since this is a &lt;strong&gt;Go package&lt;/strong&gt;, you'll need to install &lt;strong&gt;Go&lt;/strong&gt; first. Then, you can install the package with the following steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go &lt;span class="nb"&gt;install &lt;/span&gt;sigs.k8s.io/cloud-provider-kind@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then execute command to use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cloud-provider-kind
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep in mind that you need to keep the terminal running while using &lt;strong&gt;Kubernetes&lt;/strong&gt; to create the &lt;strong&gt;EXTERNAL-IP&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing with local EXTERNAL-IP
&lt;/h2&gt;

&lt;p&gt;Create a &lt;strong&gt;&lt;em&gt;deployment&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;expose&lt;/em&gt;&lt;/strong&gt; a &lt;strong&gt;LoadBalancer&lt;/strong&gt; &lt;strong&gt;service&lt;/strong&gt; to check if the &lt;strong&gt;EXTERNAL-IP&lt;/strong&gt; has been generated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create deploy &lt;span class="nb"&gt;whoami&lt;/span&gt; &lt;span class="nt"&gt;--image&lt;/span&gt; traefik/whoami
kubectl expose deploy &lt;span class="nb"&gt;whoami&lt;/span&gt; &lt;span class="nt"&gt;--port&lt;/span&gt; 80 &lt;span class="nt"&gt;--type&lt;/span&gt; LoadBalancer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The results will be as follows:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F39ce0dmhsxnd6ua08qn3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F39ce0dmhsxnd6ua08qn3.png" alt="kubectl get all" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can access the &lt;strong&gt;EXTERNAL-IP&lt;/strong&gt; to use it locally.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2kaekb6pnuo16k6fdkum.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2kaekb6pnuo16k6fdkum.png" alt="Result deployed" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Using cloud-provider-kind as a service
&lt;/h2&gt;

&lt;p&gt;If you're on &lt;strong&gt;Ubuntu&lt;/strong&gt;, there's a way to automatically run &lt;strong&gt;&lt;em&gt;cloud-provider-kind&lt;/em&gt;&lt;/strong&gt; when you start your machine as a service, so you don't have to manually start it every time you want to use it.&lt;/p&gt;

&lt;p&gt;First, navigate to the directory &lt;strong&gt;&lt;em&gt;/etc/systemd/system&lt;/em&gt;&lt;/strong&gt; and create a file called &lt;strong&gt;&lt;em&gt;cloud-provider-kind.service&lt;/em&gt;&lt;/strong&gt; with the following content:&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;cd&lt;/span&gt; /etc/systemd/system
&lt;span class="nb"&gt;touch &lt;/span&gt;cloud-provider-kind.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Unit]
Description = Your description
After = docker.service

[Service]
Type = simple
ExecStart = {direction to cloud-provider-kind}
StandardOutput = journal
User = {user id}
Group = {group id}

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;ExecStart&lt;/strong&gt;: Use the command &lt;strong&gt;&lt;em&gt;which cloud-provider-kind&lt;/em&gt;&lt;/strong&gt; to replace your directory.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;User&lt;/strong&gt;, &lt;strong&gt;Group&lt;/strong&gt;: Use the command &lt;strong&gt;&lt;em&gt;id&lt;/em&gt;&lt;/strong&gt; to get the appropriate values.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To start the service:&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;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--now&lt;/span&gt; cloud-provider-kind
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then check status:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff5i6q3t0pu6dnlnwvrvm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff5i6q3t0pu6dnlnwvrvm.png" alt="symtemctl status" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you have any suggestions or questions regarding the content of the article, please don't hesitate to leave a comment below!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you found this content helpful, please visit &lt;a href="https://howtodevez.blogspot.com/2024/06/setting-up-an-external-ip-for-local-loadbalancer-service.html" rel="noopener noreferrer"&gt;the original article on my blog&lt;/a&gt; to support the author and explore more interesting content.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/03/sitemap.html" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Rehh51y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Blogger-FF5722%3Fstyle%3Dfor-the-badge%26logo%3Dblogger%26logoColor%3Dwhite" alt="Blogspot" width="102" height="28"&gt;&lt;/a&gt;&lt;a href="https://howtodevez.medium.com" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NabPkFNQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Medium-12100E%3Fstyle%3Dfor-the-badge%26logo%3Dmedium%26logoColor%3Dwhite" alt="Blogspot" width="94" height="28"&gt;&lt;/a&gt;&lt;a href="https://dev.to/chauhoangminhnguyen" rel="noreferrer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xz2MGu8c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/dev.to-0A0A0A%3Fstyle%3Dfor-the-badge%26logo%3Ddev.to%26logoColor%3Dwhite" alt="Dev.to" width="88" height="28"&gt;&lt;/a&gt;&lt;a href="https://www.facebook.com/profile.php?id=61557154776384" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hohnj5TU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Facebook-1877F2%3Fstyle%3Dfor-the-badge%26logo%3Dfacebook%26logoColor%3Dwhite" alt="Facebook" width="111" height="28"&gt;&lt;/a&gt;&lt;a href="https://x.com/DavidNguyenSE" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tT2E75Wa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/X-000000%3Fstyle%3Dfor-the-badge%26logo%3Dx%26logoColor%3Dwhite" alt="X" width="52" height="28"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Some series you might find interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/nodejs-practice-series.html" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://howtodevez.blogspot.com/2024/08/react-practice-series.html" rel="noopener noreferrer"&gt;React&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://howtodevez.blogspot.com/2024/08/docker-practice-series.html" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/kubernetes-practice-series.html" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/google-cloud-platform-practice-series.html" rel="noopener noreferrer"&gt;Google Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/devops-practice-series.html" rel="noopener noreferrer"&gt;DevOps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>beginners</category>
      <category>loadbalancer</category>
      <category>devops</category>
    </item>
    <item>
      <title>Setting up Kubernetes Dashboard with Kind</title>
      <dc:creator>chauhoangminhnguyen</dc:creator>
      <pubDate>Sat, 21 Sep 2024 14:00:00 +0000</pubDate>
      <link>https://forem.com/chauhoangminhnguyen/setting-up-kubernetes-dashboard-with-kind-5he5</link>
      <guid>https://forem.com/chauhoangminhnguyen/setting-up-kubernetes-dashboard-with-kind-5he5</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/06/helm-for-beginer-deploy-nginx-to-google-kubernetes-engine.html" rel="noopener noreferrer"&gt;In a previous article, I guided you through using Helm to deploy on &lt;strong&gt;Google Kubernetes Engine&lt;/strong&gt;&lt;/a&gt;. However, if you want to cut down costs by using &lt;strong&gt;Kubernetes&lt;/strong&gt; in your local environment instead of relying on a cloud provider during development, then &lt;strong&gt;Kind&lt;/strong&gt; is your go-to.&lt;/p&gt;

&lt;p&gt;There are several tools to help set up &lt;strong&gt;Kubernetes&lt;/strong&gt; locally, such as &lt;strong&gt;MiniKube&lt;/strong&gt;, &lt;strong&gt;Kind&lt;/strong&gt;, &lt;strong&gt;K3S&lt;/strong&gt;, &lt;strong&gt;KubeAdm&lt;/strong&gt;, and more. Each tool has its own pros and cons. In this article, I'll walk you through using &lt;strong&gt;Kind&lt;/strong&gt; to quickly set up a &lt;strong&gt;Kubernetes&lt;/strong&gt; cluster on &lt;strong&gt;Docker&lt;/strong&gt;. Kind stands out for its compactness, making &lt;strong&gt;Kubernetes&lt;/strong&gt; start up quickly, being user-friendly, and supporting the latest &lt;strong&gt;Kubernetes&lt;/strong&gt; versions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2uwarru2lduoudaafilj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2uwarru2lduoudaafilj.png" alt="Helm Kind K8s" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Working with Kind
&lt;/h2&gt;

&lt;p&gt;Firstly, follow the instructions here to install Kind according to your operating system.&lt;/p&gt;

&lt;p&gt;If you're using &lt;strong&gt;Ubuntu&lt;/strong&gt;, execute the command:&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="o"&gt;[&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; x86_64 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; curl &lt;span class="nt"&gt;-Lo&lt;/span&gt; ./kind https://kind.sigs.k8s.io/dl/v0.23.0/kind-linux-amd64
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x ./kind
&lt;span class="nb"&gt;sudo mv&lt;/span&gt; ./kind /usr/local/bin/kind
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After successfully installing &lt;strong&gt;Kind&lt;/strong&gt;, you can check its version with the following command:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F71zuqrw0j9foujqm7syx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F71zuqrw0j9foujqm7syx.png" alt="Kind version" width="383" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To create a cluster, use this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kind create cluster &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;cluster name&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# ex&lt;/span&gt;
kind create cluster &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="nb"&gt;local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnifu17dheddyokvirk0d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnifu17dheddyokvirk0d.png" alt="Kind create cluster" width="800" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Helm to set up the Kubernetes Dashboard
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Kubernetes Dashboard&lt;/strong&gt; is a tool for managing &lt;strong&gt;Kubernetes clusters&lt;/strong&gt; with an easy-to-use web UI.&lt;/p&gt;

&lt;p&gt;First, add the &lt;strong&gt;Kubernetes Dashboard&lt;/strong&gt; repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add &lt;span class="o"&gt;{&lt;/span&gt;repo name&lt;span class="o"&gt;}&lt;/span&gt; https://kubernetes.github.io/dashboard

&lt;span class="c"&gt;# ex&lt;/span&gt;
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, install the chart:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm upgrade &lt;span class="nt"&gt;--install&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;release name&lt;span class="o"&gt;}&lt;/span&gt; k8s-dashboard/kubernetes-dashboard &lt;span class="nt"&gt;--create-namespace&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;namespace&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# ex&lt;/span&gt;
helm upgrade &lt;span class="nt"&gt;--install&lt;/span&gt; kubernetes-dashboard k8s-dashboard/kubernetes-dashboard &lt;span class="nt"&gt;--create-namespace&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; kubernetes-dashboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please note that you need to successfully create a Kubernetes cluster before you can install a &lt;strong&gt;Helm chart&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;-n {namespace}&lt;/em&gt;&lt;/strong&gt;: Setting a namespace is optional, but organizing resources by namespace can be helpful, especially if you need to install multiple &lt;strong&gt;Helm charts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once you've successfully installed the Helm chart, the result will be as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz11azkr5gahx72pepiqx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz11azkr5gahx72pepiqx.png" alt="Helm upgrade" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check if the resources were created successfully like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get all &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;namespace&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# ex&lt;/span&gt;
kubectl get all &lt;span class="nt"&gt;-n&lt;/span&gt; kubernetes-dashboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhssxskgzmlyxydfusdii.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhssxskgzmlyxydfusdii.png" alt="kubectl get all" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, forward the port for the service so it can be accessed from &lt;strong&gt;&lt;em&gt;localhost&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fljmvt1ibla4d8xhdsnz3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fljmvt1ibla4d8xhdsnz3.png" alt="kubectl port forward" width="800" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a result, you can access the &lt;strong&gt;Kubernetes Dashboard&lt;/strong&gt; like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fssnvn9kq29wf2fqrjw26.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fssnvn9kq29wf2fqrjw26.png" alt="K8s dashboard" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To generate a token, create a file named &lt;strong&gt;&lt;em&gt;service-account.yml&lt;/em&gt;&lt;/strong&gt; with the following content:&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;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ServiceAccount&lt;/span&gt;
&lt;span class="na"&gt;metadata&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;admin-user&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kube-system&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterRoleBinding&lt;/span&gt;
&lt;span class="na"&gt;metadata&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;admin-user&lt;/span&gt;
&lt;span class="na"&gt;roleRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;apiGroup&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rbac.authorization.k8s.io&lt;/span&gt;
  &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterRole&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;cluster-admin&lt;/span&gt;
&lt;span class="na"&gt;subjects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ServiceAccount&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;admin-user&lt;/span&gt;
    &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kube-system&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply to Create Resources:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9wvihddet9ag3rg5g8q1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9wvihddet9ag3rg5g8q1.png" alt="kubectl apply" width="687" height="76"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, generate a token like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqs02vrjz61gv1u9dim03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqs02vrjz61gv1u9dim03.png" alt="Generate token" width="800" height="82"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use that token to login to the &lt;strong&gt;Kubernetes Dashboard&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3uknofcnam93sovcswcn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3uknofcnam93sovcswcn.png" alt="K8s dashboard homepage" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;See you again in the next articles!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you found this content helpful, please visit &lt;a href="https://howtodevez.blogspot.com/2024/06/setting-up-kubernetes-dashboard-with-kind.html" rel="noopener noreferrer"&gt;the original article on my blog&lt;/a&gt; to support the author and explore more interesting content.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/03/sitemap.html" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Rehh51y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Blogger-FF5722%3Fstyle%3Dfor-the-badge%26logo%3Dblogger%26logoColor%3Dwhite" alt="Blogspot" width="102" height="28"&gt;&lt;/a&gt;&lt;a href="https://howtodevez.medium.com" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NabPkFNQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Medium-12100E%3Fstyle%3Dfor-the-badge%26logo%3Dmedium%26logoColor%3Dwhite" alt="Blogspot" width="94" height="28"&gt;&lt;/a&gt;&lt;a href="https://dev.to/chauhoangminhnguyen" rel="noreferrer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xz2MGu8c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/dev.to-0A0A0A%3Fstyle%3Dfor-the-badge%26logo%3Ddev.to%26logoColor%3Dwhite" alt="Dev.to" width="88" height="28"&gt;&lt;/a&gt;&lt;a href="https://www.facebook.com/profile.php?id=61557154776384" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hohnj5TU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Facebook-1877F2%3Fstyle%3Dfor-the-badge%26logo%3Dfacebook%26logoColor%3Dwhite" alt="Facebook" width="111" height="28"&gt;&lt;/a&gt;&lt;a href="https://x.com/DavidNguyenSE" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tT2E75Wa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/X-000000%3Fstyle%3Dfor-the-badge%26logo%3Dx%26logoColor%3Dwhite" alt="X" width="52" height="28"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Some series you might find interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/nodejs-practice-series.html" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://howtodevez.blogspot.com/2024/08/react-practice-series.html" rel="noopener noreferrer"&gt;React&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://howtodevez.blogspot.com/2024/08/docker-practice-series.html" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/kubernetes-practice-series.html" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/google-cloud-platform-practice-series.html" rel="noopener noreferrer"&gt;Google Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/devops-practice-series.html" rel="noopener noreferrer"&gt;DevOps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>beginners</category>
      <category>devops</category>
      <category>k8s</category>
    </item>
    <item>
      <title>Helm for beginer - Deploy nginx to Google Kubernetes Engine</title>
      <dc:creator>chauhoangminhnguyen</dc:creator>
      <pubDate>Fri, 20 Sep 2024 14:00:00 +0000</pubDate>
      <link>https://forem.com/chauhoangminhnguyen/helm-for-beginer-deploy-nginx-to-google-kubernetes-engine-3hek</link>
      <guid>https://forem.com/chauhoangminhnguyen/helm-for-beginer-deploy-nginx-to-google-kubernetes-engine-3hek</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Helm&lt;/strong&gt; is a package manager for &lt;strong&gt;Kubernetes&lt;/strong&gt;, which simplifies the process of deploying and managing applications on &lt;strong&gt;Kubernetes&lt;/strong&gt; clusters. &lt;strong&gt;Helm&lt;/strong&gt; uses a packaging format called &lt;strong&gt;charts&lt;/strong&gt;, which are collections of files that describe a related set of &lt;strong&gt;Kubernetes&lt;/strong&gt; resources.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F0v2g27dizeq0dt12bidw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F0v2g27dizeq0dt12bidw.png" alt="Helm"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Components of Helm
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Charts&lt;/strong&gt;: &lt;strong&gt;Helm&lt;/strong&gt; packages are called charts. A chart is a collection of files that describe a related set of Kubernetes resources. A single chart might be used to deploy something simple, like a memcached pod, or something complex, like a full web app stack with &lt;strong&gt;HTTP servers&lt;/strong&gt;, databases, caches, and so on.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Values&lt;/strong&gt;: &lt;strong&gt;Charts&lt;/strong&gt; can be customized with values, which are configuration settings that specify how the chart should be installed on the cluster. These values can be set in a &lt;strong&gt;values.yaml&lt;/strong&gt; file or passed on the command line.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Releases&lt;/strong&gt;: When you install a chart, a new release is created. This means that one chart can be installed multiple times into the same cluster, and each can be independently managed and upgraded.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;To get started, you'll need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Have some knowledge about &lt;strong&gt;Kubernetes&lt;/strong&gt;. &lt;a href="https://howtodevez.blogspot.com/2024/04/practicing-with-google-cloud-platform-google-kubernetes-engine-to-deploy-nginx.html" rel="noopener noreferrer"&gt;You can check out this article for basic information&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  A &lt;strong&gt;Google Account&lt;/strong&gt; with the necessary permissions to use &lt;strong&gt;Kubernetes&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  Installed &lt;strong&gt;gcloud&lt;/strong&gt; and &lt;strong&gt;kubectl&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Practical Steps
&lt;/h2&gt;

&lt;p&gt;First, use &lt;strong&gt;gcloud&lt;/strong&gt; to create a cluster like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud container clusters create &lt;span class="o"&gt;{&lt;/span&gt;cluster name&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--project&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;project &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--zone&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;zone &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--machine-type&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;machine &lt;span class="nb"&gt;type id&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--num-nodes&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;number of node&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# ex:&lt;/span&gt;
gcloud container clusters create k8s-cluster &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--project&lt;/span&gt; project-id &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--zone&lt;/span&gt; asia-southeast1-a &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--machine-type&lt;/span&gt; e2-micro &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--num-nodes&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To install &lt;strong&gt;helm&lt;/strong&gt;, use the following command:&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To create a &lt;strong&gt;helm&lt;/strong&gt; chart, use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm create chart-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After executing, a template is created that includes files like &lt;strong&gt;development.yaml&lt;/strong&gt;, &lt;strong&gt;service.yaml&lt;/strong&gt;, and others, similar to working with &lt;strong&gt;Kubernetes&lt;/strong&gt;. Among these files, pay special attention to &lt;strong&gt;values.yaml&lt;/strong&gt;. The values in this file are bound to the template when Helm is installed. By simply changing these values according to your needs, you can easily modify the deployment configuration.&lt;/p&gt;

&lt;p&gt;Next, in the &lt;strong&gt;values.yaml&lt;/strong&gt; file, look for the following information:&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;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;

&lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterIP&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  The repository is a &lt;strong&gt;Docker image&lt;/strong&gt; used for deployment, which you can customize as needed. &lt;/li&gt;
&lt;li&gt;  The current service type is &lt;strong&gt;ClusterIP&lt;/strong&gt;, using port &lt;strong&gt;80&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here, you can change the service type to &lt;strong&gt;LoadBalancer&lt;/strong&gt;. Then, install &lt;strong&gt;helm chart&lt;/strong&gt; as follows:&lt;br&gt;
&lt;a href="https://media.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%2Fqmnfgxkjt93hep46kmv5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fqmnfgxkjt93hep46kmv5.png" alt="helm install chart"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The change to a &lt;strong&gt;LoadBalancer&lt;/strong&gt; service type allows your cloud provider to supply an &lt;strong&gt;EXTERNAL-IP&lt;/strong&gt;. You can then retrieve the &lt;strong&gt;EXTERNAL-IP&lt;/strong&gt; information as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fhyz9vawx22vudrccrbyb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fhyz9vawx22vudrccrbyb.png" alt="kubectl get all"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you keep the original content of the &lt;strong&gt;values.yaml&lt;/strong&gt; file, you can install &lt;strong&gt;helm chart&lt;/strong&gt; and change the service type to &lt;strong&gt;LoadBalancer&lt;/strong&gt; like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F50edur0cpli9zke1nhbj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F50edur0cpli9zke1nhbj.png" alt="helm install chart with type"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Access the &lt;strong&gt;EXTERNAL-IP&lt;/strong&gt; to see the following results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F6lx2h1dqpm97f6jckbtt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F6lx2h1dqpm97f6jckbtt.png" alt="Deployed"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Result&lt;br&gt;
To uninstall &lt;strong&gt;helm chart&lt;/strong&gt; and clear up resources, you can use the following command:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fzhc1ta4574myw93gt3k6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fzhc1ta4574myw93gt3k6.png" alt="Helm uninstall chart"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Feel free to share your thoughts in the comments!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you found this content helpful, please visit &lt;a href="https://howtodevez.blogspot.com/2024/06/helm-for-beginer-deploy-nginx-to-google-kubernetes-engine.html" rel="noopener noreferrer"&gt;the original article on my blog&lt;/a&gt; to support the author and explore more interesting content.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/03/sitemap.html" rel="noreferrer noopener"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2FBlogger-FF5722%3Fstyle%3Dfor-the-badge%26logo%3Dblogger%26logoColor%3Dwhite" alt="Blogspot"&gt;&lt;/a&gt;&lt;a href="https://howtodevez.medium.com" rel="noreferrer noopener"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2FMedium-12100E%3Fstyle%3Dfor-the-badge%26logo%3Dmedium%26logoColor%3Dwhite" alt="Blogspot"&gt;&lt;/a&gt;&lt;a href="https://dev.to/chauhoangminhnguyen" rel="noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2Fdev.to-0A0A0A%3Fstyle%3Dfor-the-badge%26logo%3Ddev.to%26logoColor%3Dwhite" alt="Dev.to"&gt;&lt;/a&gt;&lt;a href="https://www.facebook.com/profile.php?id=61557154776384" rel="noreferrer noopener"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2FFacebook-1877F2%3Fstyle%3Dfor-the-badge%26logo%3Dfacebook%26logoColor%3Dwhite" alt="Facebook"&gt;&lt;/a&gt;&lt;a href="https://x.com/DavidNguyenSE" rel="noreferrer noopener"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2FX-000000%3Fstyle%3Dfor-the-badge%26logo%3Dx%26logoColor%3Dwhite" alt="X"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Some series you might find interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/nodejs-practice-series.html" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://howtodevez.blogspot.com/2024/08/react-practice-series.html" rel="noopener noreferrer"&gt;React&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://howtodevez.blogspot.com/2024/08/docker-practice-series.html" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/kubernetes-practice-series.html" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/google-cloud-platform-practice-series.html" rel="noopener noreferrer"&gt;Google Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/devops-practice-series.html" rel="noopener noreferrer"&gt;DevOps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>beginners</category>
      <category>nginx</category>
      <category>gke</category>
    </item>
    <item>
      <title>Setup Gitlab CI</title>
      <dc:creator>chauhoangminhnguyen</dc:creator>
      <pubDate>Thu, 19 Sep 2024 14:00:00 +0000</pubDate>
      <link>https://forem.com/chauhoangminhnguyen/setup-gitlab-ci-1pc1</link>
      <guid>https://forem.com/chauhoangminhnguyen/setup-gitlab-ci-1pc1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Gitlab&lt;/strong&gt; is a comprehensive platform designed for software development and version control using git. It provides a user-friendly web interface that enhances the speed of working with git, making it easier to manage Git repositories. &lt;strong&gt;Gitlab&lt;/strong&gt; offers a range of features including:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Free public and private repositories: You can host your code securely and privately or share it with the world.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Continuous Integration/Continuous Deployment (CI/CD)&lt;/strong&gt;: Automate the testing and deployment of your code.&lt;/li&gt;
&lt;li&gt;  Free private docker image storage on &lt;strong&gt;Container Registry&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, I'll guide you on how to push a &lt;strong&gt;Docker&lt;/strong&gt; image to the &lt;strong&gt;Gitlab Container Registry&lt;/strong&gt; and set up &lt;strong&gt;CI&lt;/strong&gt; to automatically build and push &lt;strong&gt;Docker&lt;/strong&gt; images when you push code to a &lt;strong&gt;Gitlab&lt;/strong&gt; repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejvedp4euemh0zzcdmp1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejvedp4euemh0zzcdmp1.png" alt="Gitlab CI" width="320" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pushing a Docker Image to the Gitlab Container Registry
&lt;/h2&gt;

&lt;p&gt;First, you'll need a &lt;strong&gt;Gitlab&lt;/strong&gt; account and a repository (either public or private will work).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/05/deploying-a-nodejs-server-on-google-kubernetes-engine.html" rel="noopener noreferrer"&gt;Use the &lt;strong&gt;NodeJS Typescript Server&lt;/strong&gt; project I introduced earlier&lt;/a&gt;, or any project you have that includes a &lt;strong&gt;Dockerfile&lt;/strong&gt; for building a &lt;strong&gt;Docker&lt;/strong&gt; image.&lt;/p&gt;

&lt;p&gt;Next, create a &lt;strong&gt;Personal Access Token&lt;/strong&gt; to prepare for pushing the image to the &lt;strong&gt;Container Registry&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After building your Docker image, tag the image appropriately to ensure it can be pushed to the &lt;strong&gt;Container Registry&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker tag &lt;span class="o"&gt;{&lt;/span&gt;image name after build&lt;span class="o"&gt;}&lt;/span&gt; registry.gitlab.com/&lt;span class="o"&gt;{&lt;/span&gt;gitlab username&lt;span class="o"&gt;}&lt;/span&gt;/&lt;span class="o"&gt;{&lt;/span&gt;repository&lt;span class="o"&gt;}&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;version&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;#ex:&lt;/span&gt;
docker tag express-ts registry.gitlab.com/username/express-ts:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Logging into the &lt;strong&gt;Gitlab Container Registry&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker login &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;gitlab username&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;access token&lt;span class="o"&gt;}&lt;/span&gt; registry.gitlab.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Push image to &lt;strong&gt;Registry Container&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker push registry.gitlab.com/&lt;span class="o"&gt;{&lt;/span&gt;gitlab username&lt;span class="o"&gt;}&lt;/span&gt;/&lt;span class="o"&gt;{&lt;/span&gt;repository&lt;span class="o"&gt;}&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;version&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;#ex:&lt;/span&gt;
docker push registry.gitlab.com/username/express-ts:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The results are as follows:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3n4w5xp24g5dczncd72p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3n4w5xp24g5dczncd72p.png" alt="Container registry" width="800" height="288"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up Gitlab CI
&lt;/h2&gt;

&lt;p&gt;To set up steps that run whenever you push code to your &lt;strong&gt;Gitlab&lt;/strong&gt; repository, add a &lt;strong&gt;&lt;em&gt;.gitlab-ci.yml&lt;/em&gt;&lt;/strong&gt; file to your project with the following content:&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;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker:24.0.7&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker:24.0.7-dind&lt;/span&gt;

&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;

&lt;span class="na"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY&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;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -t $CI_REGISTRY_IMAGE:latest .&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker image push --all-tags $CI_REGISTRY_IMAGE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;p&gt;- &lt;strong&gt;image&lt;/strong&gt; and &lt;strong&gt;services&lt;/strong&gt;: Define the Docker environment to execute Docker commands.&lt;/p&gt;

&lt;p&gt;- &lt;strong&gt;stages&lt;/strong&gt;: Specify the stages that will execute when code is pushed. Here, there's only one stage: build.&lt;/p&gt;

&lt;p&gt;- &lt;strong&gt;before_script&lt;/strong&gt;: Runs before each stage. This step logs into the &lt;strong&gt;Container Registry&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;- &lt;strong&gt;stage build&lt;/strong&gt;: Builds the image with two tags: the &lt;strong&gt;SHA commit ID&lt;/strong&gt; and "&lt;strong&gt;latest&lt;/strong&gt;", then pushes all tags to the &lt;strong&gt;Container Registry&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gitlab&lt;/strong&gt; provides environment variables, which are information that can be used when stages are executed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;CI_REGISTRY_USER&lt;/strong&gt;: username&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CI_REGISTRY_PASSWORD&lt;/strong&gt;: password&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CI_REGISTRY&lt;/strong&gt;: &lt;strong&gt;Gitlab&lt;/strong&gt; register&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CI_REGISTRY_IMAGE&lt;/strong&gt;: image name&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CI_COMMIT_SHA&lt;/strong&gt;: SHA commit id&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After that, just push the code to the &lt;strong&gt;Gitlab&lt;/strong&gt; repository to automatically trigger the &lt;strong&gt;CI&lt;/strong&gt; process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyog1k951ystxkda5c1cn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyog1k951ystxkda5c1cn.png" alt="Job running" width="800" height="97"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo6wlsbjoyhgr2d5j04ge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo6wlsbjoyhgr2d5j04ge.png" alt="Job done" width="800" height="95"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1t3npa5ffew6gj5qjj7z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1t3npa5ffew6gj5qjj7z.png" alt="Job detail" width="507" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;See you in the next articles!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you found this content helpful, please visit &lt;a href="https://howtodevez.blogspot.com/2024/06/setup-gitlab-ci.html" rel="noopener noreferrer"&gt;the original article on my blog&lt;/a&gt; to support the author and explore more interesting content.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/03/sitemap.html" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Rehh51y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Blogger-FF5722%3Fstyle%3Dfor-the-badge%26logo%3Dblogger%26logoColor%3Dwhite" alt="Blogspot" width="102" height="28"&gt;&lt;/a&gt;&lt;a href="https://howtodevez.medium.com" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NabPkFNQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Medium-12100E%3Fstyle%3Dfor-the-badge%26logo%3Dmedium%26logoColor%3Dwhite" alt="Blogspot" width="94" height="28"&gt;&lt;/a&gt;&lt;a href="https://dev.to/chauhoangminhnguyen" rel="noreferrer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xz2MGu8c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/dev.to-0A0A0A%3Fstyle%3Dfor-the-badge%26logo%3Ddev.to%26logoColor%3Dwhite" alt="Dev.to" width="88" height="28"&gt;&lt;/a&gt;&lt;a href="https://www.facebook.com/profile.php?id=61557154776384" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hohnj5TU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Facebook-1877F2%3Fstyle%3Dfor-the-badge%26logo%3Dfacebook%26logoColor%3Dwhite" alt="Facebook" width="111" height="28"&gt;&lt;/a&gt;&lt;a href="https://x.com/DavidNguyenSE" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tT2E75Wa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/X-000000%3Fstyle%3Dfor-the-badge%26logo%3Dx%26logoColor%3Dwhite" alt="X" width="52" height="28"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Some series you might find interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/nodejs-practice-series.html" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://howtodevez.blogspot.com/2024/08/react-practice-series.html" rel="noopener noreferrer"&gt;React&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://howtodevez.blogspot.com/2024/08/docker-practice-series.html" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/kubernetes-practice-series.html" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/google-cloud-platform-practice-series.html" rel="noopener noreferrer"&gt;Google Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/devops-practice-series.html" rel="noopener noreferrer"&gt;DevOps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gitlab</category>
      <category>ci</category>
      <category>beginners</category>
      <category>devops</category>
    </item>
    <item>
      <title>Github CI/CD with Google Cloud Build</title>
      <dc:creator>chauhoangminhnguyen</dc:creator>
      <pubDate>Wed, 18 Sep 2024 14:00:00 +0000</pubDate>
      <link>https://forem.com/chauhoangminhnguyen/github-cicd-with-google-cloud-build-2532</link>
      <guid>https://forem.com/chauhoangminhnguyen/github-cicd-with-google-cloud-build-2532</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Continuous Integration (CI)&lt;/strong&gt;: This is the process of building, testing, and performing necessary actions to ensure code quality before it gets merged into the main branch for deployment.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Continuous Delivery (CD)&lt;/strong&gt;: This usually happens after CI and includes steps to deploy the source code to various environments like &lt;strong&gt;staging&lt;/strong&gt; and &lt;strong&gt;production&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This guide will show you how to set up &lt;strong&gt;CI/CD&lt;/strong&gt; on &lt;strong&gt;Github&lt;/strong&gt; using &lt;strong&gt;Google Cloud Build&lt;/strong&gt;. While &lt;strong&gt;Github&lt;/strong&gt; provides shared runners, if you or your organization have many jobs that need executing during development, setting up your own runner is a better choice.&lt;/p&gt;

&lt;p&gt;Before proceeding, you should understand some basics about &lt;strong&gt;Google Cloud Run&lt;/strong&gt; to build and deploy Docker images. You can refer to this article for more details: &lt;a href="https://howtodevez.blogspot.com/2024/05/deploying-a-nodejs-server-on-google-kubernetes-engine.html" rel="noopener noreferrer"&gt;Build Docker image for NodeJS Typescript Server&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fku2ry0afb6k300gptces.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fku2ry0afb6k300gptces.png" alt="Google cloud build Github" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up GitHub CI/CD
&lt;/h2&gt;

&lt;p&gt;First, create a &lt;strong&gt;Github&lt;/strong&gt; repository. You can choose either a public or private repository.&lt;/p&gt;

&lt;p&gt;You can use a &lt;strong&gt;NodeJS TypeScript&lt;/strong&gt; application, following my guide on building a Docker image, or use your existing source code (make sure to include a &lt;strong&gt;&lt;em&gt;Dockerfile&lt;/em&gt;&lt;/strong&gt; to build the Docker image).&lt;/p&gt;

&lt;p&gt;Next, in your source code, create a &lt;strong&gt;&lt;em&gt;cloudbuild.yaml&lt;/em&gt;&lt;/strong&gt; file as follows:&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;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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gcr.io/cloud-builders/docker'&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;build'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-t'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gcr.io/project-id/express-ts:$SHORT_SHA'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-t'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gcr.io/project-id/express-ts:latest'&lt;/span&gt;&lt;span class="pi"&gt;]&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="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gcr.io/cloud-builders/docker'&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;image'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;push'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;--all-tags'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gcr.io/project-id/express-ts'&lt;/span&gt;&lt;span class="pi"&gt;]&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="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gcr.io/cloud-builders/gcloud'&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;run&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--region=asia-southeast1&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--image=gcr.io/project-id/express-ts:latest&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--max-instances=1&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--platform=managed&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--port=3000&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--allow-unauthenticated&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;express-ts&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file outlines the steps that &lt;strong&gt;Google Cloud Build&lt;/strong&gt; will take when you push code to a specified branch on &lt;strong&gt;Github&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;- '&lt;strong&gt;&lt;em&gt;gcr.io/cloud-builders/docker&lt;/em&gt;&lt;/strong&gt;' and '&lt;strong&gt;&lt;em&gt;gcr.io/cloud-builders/gcloud&lt;/em&gt;&lt;/strong&gt;' are used to execute &lt;strong&gt;Docker&lt;/strong&gt; and &lt;strong&gt;Google Cloud&lt;/strong&gt; commands.&lt;/p&gt;

&lt;p&gt;- &lt;strong&gt;&lt;em&gt;$SHORT_SHA&lt;/em&gt;&lt;/strong&gt; represents the short commit ID.&lt;/p&gt;

&lt;p&gt;- The first step is to build a &lt;strong&gt;Docker&lt;/strong&gt; image with two tags: the &lt;strong&gt;&lt;em&gt;short commit ID&lt;/em&gt;&lt;/strong&gt; and '&lt;em&gt;&lt;strong&gt;latest&lt;/strong&gt;&lt;/em&gt;'.&lt;/p&gt;

&lt;p&gt;- Step 2 involves pushing the &lt;strong&gt;Docker&lt;/strong&gt; image with both tags to &lt;strong&gt;Google Artifact Registry&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;- Step 3 is deploying via &lt;strong&gt;Google Cloud Run&lt;/strong&gt;, &lt;a href="https://howtodevez.blogspot.com/2024/06/using-google-cloud-run-to-deploy-a-docker-image.html" rel="noopener noreferrer"&gt;as instructed in the previous article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Note: Remember to replace the &lt;strong&gt;project ID&lt;/strong&gt; and other parameters according to your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a Trigger
&lt;/h2&gt;

&lt;p&gt;Next, navigate to &lt;strong&gt;Google Cloud Build&lt;/strong&gt; &amp;gt; &lt;strong&gt;Create trigger&lt;/strong&gt;. Then, input the required information, paying attention to the following fields:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2x82lfrksuhc0uaupjeb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2x82lfrksuhc0uaupjeb.png" alt="Create trigger 1" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvpguisszwq7qpcj2ubw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvpguisszwq7qpcj2ubw.png" alt="Create trigger 2" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;- &lt;strong&gt;Repository&lt;/strong&gt;: Connect to your repository, supporting both &lt;strong&gt;Github&lt;/strong&gt; and &lt;strong&gt;Bitbucket&lt;/strong&gt;. After successful account connection, you can configure for both &lt;strong&gt;public&lt;/strong&gt; and &lt;strong&gt;private&lt;/strong&gt; repositories.&lt;/p&gt;

&lt;p&gt;- &lt;strong&gt;Branch&lt;/strong&gt;: Specify the branch name that will trigger &lt;strong&gt;Cloud Build&lt;/strong&gt; upon action. Branch names support regex.&lt;/p&gt;

&lt;p&gt;- &lt;strong&gt;Cloud Build Configuration File Location&lt;/strong&gt;: Specify the file name used to define the steps &lt;strong&gt;Cloud Build&lt;/strong&gt; will execute. You can use the default or customize it as needed.&lt;/p&gt;

&lt;p&gt;- &lt;strong&gt;Service Account&lt;/strong&gt;: Choose the account corresponding to the &lt;strong&gt;project ID&lt;/strong&gt; used to push &lt;strong&gt;Docker&lt;/strong&gt; images to &lt;strong&gt;Google Artifact Registry&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Note that currently, there are usage limits for &lt;strong&gt;Google Cloud Build&lt;/strong&gt; based on region. &lt;a href="https://cloud.google.com/build/docs/locations#restricted_regions_for_some_projects" rel="noopener noreferrer"&gt;Check here for more information&lt;/a&gt;. You can request an increase in quota or switch to a suitable region to use &lt;strong&gt;Cloud Build&lt;/strong&gt; effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test CI/CD
&lt;/h2&gt;

&lt;p&gt;Push your source code to &lt;strong&gt;Github&lt;/strong&gt; to test the &lt;strong&gt;CI/CD&lt;/strong&gt; process.&lt;/p&gt;

&lt;p&gt;A successful result will be as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjij5ifr51as8t69vmae4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjij5ifr51as8t69vmae4.png" alt="Job running" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fge8dz6vbfgxejku51xgy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fge8dz6vbfgxejku51xgy.png" alt="Job done" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also access &lt;strong&gt;Google Cloud Build&lt;/strong&gt; to check the results.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F400ovxkx7aeh0ri5lml9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F400ovxkx7aeh0ri5lml9.png" alt="Google cloud build result" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Results after deployment:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F693hc7p46xcb9yhn123s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F693hc7p46xcb9yhn123s.png" alt="Deployed" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;See you again in the next articles!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you found this content helpful, please visit &lt;a href="https://howtodevez.blogspot.com/2024/06/github-cicd-with-google-cloud-build.html" rel="noopener noreferrer"&gt;the original article on my blog&lt;/a&gt; to support the author and explore more interesting content.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/03/sitemap.html" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Rehh51y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Blogger-FF5722%3Fstyle%3Dfor-the-badge%26logo%3Dblogger%26logoColor%3Dwhite" alt="Blogspot" width="102" height="28"&gt;&lt;/a&gt;&lt;a href="https://howtodevez.medium.com" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NabPkFNQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Medium-12100E%3Fstyle%3Dfor-the-badge%26logo%3Dmedium%26logoColor%3Dwhite" alt="Blogspot" width="94" height="28"&gt;&lt;/a&gt;&lt;a href="https://dev.to/chauhoangminhnguyen" rel="noreferrer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xz2MGu8c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/dev.to-0A0A0A%3Fstyle%3Dfor-the-badge%26logo%3Ddev.to%26logoColor%3Dwhite" alt="Dev.to" width="88" height="28"&gt;&lt;/a&gt;&lt;a href="https://www.facebook.com/profile.php?id=61557154776384" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hohnj5TU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Facebook-1877F2%3Fstyle%3Dfor-the-badge%26logo%3Dfacebook%26logoColor%3Dwhite" alt="Facebook" width="111" height="28"&gt;&lt;/a&gt;&lt;a href="https://x.com/DavidNguyenSE" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tT2E75Wa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/X-000000%3Fstyle%3Dfor-the-badge%26logo%3Dx%26logoColor%3Dwhite" alt="X" width="52" height="28"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Some series you might find interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/nodejs-practice-series.html" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://howtodevez.blogspot.com/2024/08/react-practice-series.html" rel="noopener noreferrer"&gt;React&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://howtodevez.blogspot.com/2024/08/docker-practice-series.html" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/kubernetes-practice-series.html" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/google-cloud-platform-practice-series.html" rel="noopener noreferrer"&gt;Google Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/devops-practice-series.html" rel="noopener noreferrer"&gt;DevOps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>github</category>
      <category>cicd</category>
      <category>googlecloud</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Using Google Cloud Run to Deploy Docker Image</title>
      <dc:creator>chauhoangminhnguyen</dc:creator>
      <pubDate>Sat, 14 Sep 2024 14:00:00 +0000</pubDate>
      <link>https://forem.com/chauhoangminhnguyen/using-google-cloud-run-to-deploy-docker-image-2im3</link>
      <guid>https://forem.com/chauhoangminhnguyen/using-google-cloud-run-to-deploy-docker-image-2im3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Google Cloud Run (GCR)&lt;/strong&gt; makes deploying a &lt;strong&gt;Docker&lt;/strong&gt; image as easy as running it locally. &lt;strong&gt;GCR&lt;/strong&gt; also includes customizable configuration options for managing services, simplifying the deployment process significantly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16144klollv0m1xmgcp5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16144klollv0m1xmgcp5.png" alt="Google cloud run" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Build Docker Image
&lt;/h2&gt;

&lt;p&gt;The key step in deploying with a &lt;strong&gt;Docker image&lt;/strong&gt; is successfully building that image. In this guide, we’ll use a &lt;a href="https://howtodevez.blogspot.com/2024/05/deploying-a-nodejs-server-on-google-kubernetes-engine.html" rel="noopener noreferrer"&gt;&lt;strong&gt;NodeJS&lt;/strong&gt; server &lt;strong&gt;Docker image&lt;/strong&gt; created in this article&lt;/a&gt;. Follow the steps to build your Docker image (or use an existing one), and push it to &lt;strong&gt;Google Artifact Registry&lt;/strong&gt; before proceeding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy Docker Image
&lt;/h2&gt;

&lt;p&gt;To deploy a &lt;strong&gt;Docker image&lt;/strong&gt; using &lt;strong&gt;Google Cloud Run&lt;/strong&gt;, simply use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud run deploy express-ts &lt;span class="nt"&gt;--image&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;docker image&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--port&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;port container&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;region &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--max-instances&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;number of instance&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--allow-unauthenticated&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;--image&lt;/em&gt;&lt;/strong&gt;: is the link to the &lt;strong&gt;Docker image&lt;/strong&gt; on &lt;strong&gt;Google Artifact Registry&lt;/strong&gt; or &lt;strong&gt;Docker Hub&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;--port&lt;/em&gt;&lt;/strong&gt;: is the container port you are exposing&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;em&gt;--max-instances&lt;/em&gt;&lt;/strong&gt;: is the number of instances&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Formzp7bvu55nq62adgy9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Formzp7bvu55nq62adgy9.png" alt="gcloud run deploy" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a successful deployment, the &lt;strong&gt;Service URL&lt;/strong&gt; will be created, and you can access it immediately to start using the service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ydmzptbe1iza0aru4it.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ydmzptbe1iza0aru4it.png" alt="gcloud deploy result" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To list the available services, execute the following command:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyq1ntmsd5kbt9lp8oh4z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyq1ntmsd5kbt9lp8oh4z.png" alt="gcloud service list" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To delete a service:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnr8e4by1ukvtwevguapo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnr8e4by1ukvtwevguapo.png" alt="delete service" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;See you again in the next articles!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you found this content helpful, please visit &lt;a href="https://howtodevez.blogspot.com/2024/06/using-google-cloud-run-to-deploy-a-docker-image.html" rel="noopener noreferrer"&gt;the original article on my blog&lt;/a&gt; to support the author and explore more interesting content.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/03/sitemap.html" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Rehh51y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Blogger-FF5722%3Fstyle%3Dfor-the-badge%26logo%3Dblogger%26logoColor%3Dwhite" alt="Blogspot" width="102" height="28"&gt;&lt;/a&gt;&lt;a href="https://howtodevez.medium.com" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NabPkFNQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Medium-12100E%3Fstyle%3Dfor-the-badge%26logo%3Dmedium%26logoColor%3Dwhite" alt="Blogspot" width="94" height="28"&gt;&lt;/a&gt;&lt;a href="https://dev.to/chauhoangminhnguyen" rel="noreferrer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xz2MGu8c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/dev.to-0A0A0A%3Fstyle%3Dfor-the-badge%26logo%3Ddev.to%26logoColor%3Dwhite" alt="Dev.to" width="88" height="28"&gt;&lt;/a&gt;&lt;a href="https://www.facebook.com/profile.php?id=61557154776384" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hohnj5TU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Facebook-1877F2%3Fstyle%3Dfor-the-badge%26logo%3Dfacebook%26logoColor%3Dwhite" alt="Facebook" width="111" height="28"&gt;&lt;/a&gt;&lt;a href="https://x.com/DavidNguyenSE" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tT2E75Wa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/X-000000%3Fstyle%3Dfor-the-badge%26logo%3Dx%26logoColor%3Dwhite" alt="X" width="52" height="28"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Some series you might find interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/nodejs-practice-series.html" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://howtodevez.blogspot.com/2024/08/react-practice-series.html" rel="noopener noreferrer"&gt;React&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://howtodevez.blogspot.com/2024/08/docker-practice-series.html" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/kubernetes-practice-series.html" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/google-cloud-platform-practice-series.html" rel="noopener noreferrer"&gt;Google Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/devops-practice-series.html" rel="noopener noreferrer"&gt;DevOps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>beginners</category>
      <category>googlecloud</category>
      <category>node</category>
    </item>
    <item>
      <title>Monitoring with Grafana</title>
      <dc:creator>chauhoangminhnguyen</dc:creator>
      <pubDate>Fri, 13 Sep 2024 14:00:00 +0000</pubDate>
      <link>https://forem.com/chauhoangminhnguyen/monitoring-with-grafana-59l5</link>
      <guid>https://forem.com/chauhoangminhnguyen/monitoring-with-grafana-59l5</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In my previous article, I guided you through &lt;a href="https://howtodevez.blogspot.com/2024/05/monitoring-with-cadvisor-prometheus-and-grafana-on-docker.html" rel="noopener noreferrer"&gt;setting up &lt;strong&gt;cAdvisor&lt;/strong&gt;, &lt;strong&gt;Prometheus&lt;/strong&gt; and &lt;strong&gt;Grafana&lt;/strong&gt; on &lt;strong&gt;Docker&lt;/strong&gt;&lt;/a&gt;, which are widely used for system monitoring. Now that you've successfully started &lt;strong&gt;Grafana&lt;/strong&gt;, follow these next steps to start using it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fexjdinxpbhybw9cq7w5e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fexjdinxpbhybw9cq7w5e.png" alt="Grafana monitor" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Grafana
&lt;/h2&gt;

&lt;p&gt;When you access the &lt;strong&gt;Grafana&lt;/strong&gt; login page, use the following default credentials for your first login. You can change them later as needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;username: admin
password: admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb64utrm2069kl1vebijr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb64utrm2069kl1vebijr.png" alt="Grafana login" width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's how the homepage looks.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fchuthss3e5uplewgbr9a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fchuthss3e5uplewgbr9a.png" alt="Grafana homepage" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, you need to add &lt;strong&gt;Prometheus&lt;/strong&gt; as a data source:&lt;/p&gt;

&lt;p&gt;1. Go to &lt;strong&gt;Connections&lt;/strong&gt; &amp;gt; &lt;strong&gt;Add new connection&lt;/strong&gt; &amp;gt; select &lt;strong&gt;Prometheus&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3o5fuunkj9yt7p3ehk6t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3o5fuunkj9yt7p3ehk6t.png" alt="Add new connection" width="800" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2. Enter the &lt;strong&gt;Prometheus server URL&lt;/strong&gt; that you defined when starting &lt;strong&gt;Docker Compose&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4pkli8r22jf37ryl490n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4pkli8r22jf37ryl490n.png" alt="Connect to Prometheus" width="800" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the data source is successfully added, create a new dashboard:&lt;/p&gt;

&lt;p&gt;1. Click on &lt;strong&gt;New&lt;/strong&gt; &amp;gt; &lt;strong&gt;New dashboard&lt;/strong&gt; &amp;gt; &lt;strong&gt;Add visualization&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F65gjbkbz1unojwdyfcm3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F65gjbkbz1unojwdyfcm3.png" alt="Add visualization" width="800" height="140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjk3jytcap0kswxh5ajdp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjk3jytcap0kswxh5ajdp.png" alt="New Dashboard" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2. Select &lt;strong&gt;Prometheus&lt;/strong&gt; as the data source and choose a metric to use, such as &lt;strong&gt;&lt;em&gt;container_memory_cache&lt;/em&gt;&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbuhsrlwa654gngzowqcs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbuhsrlwa654gngzowqcs.png" alt="Config datasource" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After saving, you can view the results on your dashboard as follows:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85bq9zkhmvgkb1p13nth.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85bq9zkhmvgkb1p13nth.png" alt="Grafana chart" width="800" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Dashboard Templates
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Grafana&lt;/strong&gt; offers a variety of dashboard templates suitable for data sources like Prometheus. You can browse these &lt;a href="https://grafana.com/grafana/dashboards/?dataSource=prometheus" rel="noopener noreferrer"&gt;templates to find one that fits your needs here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once you've found a suitable template, import it into &lt;strong&gt;Grafana&lt;/strong&gt; as follows:&lt;/p&gt;

&lt;p&gt;1. Go to &lt;strong&gt;Dashboards&lt;/strong&gt; &amp;gt; &lt;strong&gt;New&lt;/strong&gt; &amp;gt; &lt;strong&gt;Import&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;2. Enter the &lt;strong&gt;Dashboard URL&lt;/strong&gt; or &lt;strong&gt;ID&lt;/strong&gt; and click &lt;strong&gt;Load&lt;/strong&gt;. For example, if the &lt;strong&gt;Dashboard URL&lt;/strong&gt; is &lt;a href="https://grafana.com/grafana/dashboards/14900-nginx" rel="noopener noreferrer"&gt;https://grafana.com/grafana/dashboards/14900-nginx&lt;/a&gt;, the &lt;strong&gt;ID&lt;/strong&gt; would be &lt;strong&gt;14900&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6swree3ph34d1skyzso8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6swree3ph34d1skyzso8.png" alt="Import dashboard" width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After successfully loading the dashboard template, save it for easy access in the future.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fen51yk3f8aqkd58f4gzl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fen51yk3f8aqkd58f4gzl.png" alt="Dashboard result" width="800" height="426"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;What do you think? Leave a comment below!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you found this content helpful, please visit &lt;a href="https://howtodevez.blogspot.com/2024/05/monitoring-with-grafana.html" rel="noopener noreferrer"&gt;the original article on my blog&lt;/a&gt; to support the author and explore more interesting content.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/03/sitemap.html" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Rehh51y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Blogger-FF5722%3Fstyle%3Dfor-the-badge%26logo%3Dblogger%26logoColor%3Dwhite" alt="Blogspot" width="102" height="28"&gt;&lt;/a&gt;&lt;a href="https://howtodevez.medium.com" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NabPkFNQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Medium-12100E%3Fstyle%3Dfor-the-badge%26logo%3Dmedium%26logoColor%3Dwhite" alt="Blogspot" width="94" height="28"&gt;&lt;/a&gt;&lt;a href="https://dev.to/chauhoangminhnguyen" rel="noreferrer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xz2MGu8c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/dev.to-0A0A0A%3Fstyle%3Dfor-the-badge%26logo%3Ddev.to%26logoColor%3Dwhite" alt="Dev.to" width="88" height="28"&gt;&lt;/a&gt;&lt;a href="https://www.facebook.com/profile.php?id=61557154776384" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hohnj5TU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Facebook-1877F2%3Fstyle%3Dfor-the-badge%26logo%3Dfacebook%26logoColor%3Dwhite" alt="Facebook" width="111" height="28"&gt;&lt;/a&gt;&lt;a href="https://x.com/DavidNguyenSE" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tT2E75Wa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/X-000000%3Fstyle%3Dfor-the-badge%26logo%3Dx%26logoColor%3Dwhite" alt="X" width="52" height="28"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Some series you might find interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/nodejs-practice-series.html" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://howtodevez.blogspot.com/2024/08/react-practice-series.html" rel="noopener noreferrer"&gt;React&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://howtodevez.blogspot.com/2024/08/docker-practice-series.html" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/kubernetes-practice-series.html" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/google-cloud-platform-practice-series.html" rel="noopener noreferrer"&gt;Google Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/devops-practice-series.html" rel="noopener noreferrer"&gt;DevOps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>grafana</category>
      <category>prometheus</category>
      <category>monitoring</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Monitoring with cAdvisor, Prometheus and Grafana on Docker</title>
      <dc:creator>chauhoangminhnguyen</dc:creator>
      <pubDate>Thu, 12 Sep 2024 14:00:00 +0000</pubDate>
      <link>https://forem.com/chauhoangminhnguyen/monitoring-with-cadvisor-prometheus-and-grafana-on-docker-1feo</link>
      <guid>https://forem.com/chauhoangminhnguyen/monitoring-with-cadvisor-prometheus-and-grafana-on-docker-1feo</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Monitoring a system is crucial after deploying a product to a production environment. Keeping an eye on system metrics like &lt;strong&gt;logs&lt;/strong&gt;, &lt;strong&gt;CPU&lt;/strong&gt;, &lt;strong&gt;RAM&lt;/strong&gt;, &lt;strong&gt;disks&lt;/strong&gt;, etc, helps identify the system's status, performance issues, and provides timely solutions to ensure stable operations.&lt;/p&gt;

&lt;p&gt;While cloud providers like &lt;strong&gt;Google&lt;/strong&gt;, &lt;strong&gt;Amazon&lt;/strong&gt;, or &lt;strong&gt;Azure&lt;/strong&gt; offer built-in monitoring systems, if your company needs to manage multiple applications/systems/containers and desires a centralized monitoring system for easier management, using &lt;strong&gt;cAdvisor&lt;/strong&gt;, &lt;strong&gt;Prometheus&lt;/strong&gt;, and &lt;strong&gt;Grafana&lt;/strong&gt; is a sensible choice. These three popular &lt;strong&gt;open-source&lt;/strong&gt; tools are widely used by &lt;strong&gt;DevOps&lt;/strong&gt; teams, especially for monitoring container applications.&lt;br&gt;
&lt;a href="https://media.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%2Fclhx2pe1k3gp38cqt2il.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fclhx2pe1k3gp38cqt2il.png" alt="Prometheus Grafana"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  cAdvisor
&lt;/h2&gt;

&lt;p&gt;Developed by &lt;strong&gt;Google&lt;/strong&gt;, &lt;strong&gt;cAdvisor&lt;/strong&gt; is an open-source project used to analyze resource usage, performance, and other metrics from container applications, providing an overview of all running containers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/google/cadvisor" rel="noopener noreferrer"&gt;Find more details here&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Prometheus
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Prometheus&lt;/strong&gt; is a toolkit for system monitoring and alerting based on system metrics. It supports organizing data over time, sending alerts via email, SMS, etc. &lt;strong&gt;Prometheus&lt;/strong&gt; can integrate with various tools, including &lt;strong&gt;cAdvisor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;While &lt;strong&gt;cAdvisor&lt;/strong&gt; fetches system information, &lt;strong&gt;Prometheus&lt;/strong&gt; provides functionalities to manipulate that information such as visualizing data and triggering alerts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://prometheus.io" rel="noopener noreferrer"&gt;Find more details here&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Grafana
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Grafana&lt;/strong&gt; is a platform specialized in data visualization, supporting the creation of beautiful dashboards for web viewing, facilitating professional data analysis. &lt;strong&gt;Grafana&lt;/strong&gt; can integrate with various data sources like &lt;strong&gt;MySQL&lt;/strong&gt;, &lt;strong&gt;MongoDB&lt;/strong&gt;, and &lt;strong&gt;Prometheus,&lt;/strong&gt; etc.&lt;/p&gt;

&lt;p&gt;So, the combination of &lt;strong&gt;cAdvisor&lt;/strong&gt;, &lt;strong&gt;Prometheus&lt;/strong&gt;, and &lt;strong&gt;Grafana&lt;/strong&gt; works like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;cAdvisor&lt;/strong&gt; gathers system info.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Prometheus&lt;/strong&gt; scrapes data from &lt;strong&gt;cAdvisor&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Grafana&lt;/strong&gt; is used to visualize data from &lt;strong&gt;Prometheus&lt;/strong&gt; (while &lt;strong&gt;Prometheus&lt;/strong&gt; has monitoring dashboards, &lt;strong&gt;Grafana&lt;/strong&gt; excels in data visualization, hence the need for &lt;strong&gt;Grafana&lt;/strong&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Setup Docker
&lt;/h2&gt;

&lt;p&gt;First, let's create a &lt;strong&gt;docker-compose.yml&lt;/strong&gt; file as follows:&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;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cAdvisor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gcr.io/cadvisor/cadvisor&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cAdvisor&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;8080:8080&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/:/rootfs:ro&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run:/var/run:ro&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/sys:/sys:ro&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/lib/docker/:/var/lib/docker:ro&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/dev/disk/:/dev/disk:ro&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock:ro&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/etc/machine-id:/etc/machine-id:ro&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/lib/dbus/machine-id:/var/lib/dbus/machine-id:ro&lt;/span&gt;
  &lt;span class="na"&gt;prometheus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prom/prometheus&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;9090:9090&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--config.file=/etc/prometheus/prometheus.yml&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./prometheus.yml:/etc/prometheus/prometheus.yml:ro&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cAdvisor&lt;/span&gt;
  &lt;span class="na"&gt;grafana&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;grafana/grafana&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;3000:3000&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;prometheus&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that I’ve defined three services corresponding to &lt;strong&gt;cAdvisor&lt;/strong&gt;, &lt;strong&gt;Prometheus&lt;/strong&gt;, and &lt;strong&gt;Grafana&lt;/strong&gt;. In this setup, &lt;strong&gt;Prometheus&lt;/strong&gt; depends on &lt;strong&gt;cAdvisor&lt;/strong&gt;, and &lt;strong&gt;Grafana&lt;/strong&gt; depends on &lt;strong&gt;Prometheus&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Next, create a &lt;strong&gt;prometheus.yml&lt;/strong&gt; file in the same location as your &lt;strong&gt;docker-compose.yml&lt;/strong&gt;. This file will configure &lt;strong&gt;Prometheus&lt;/strong&gt; to scrape data from &lt;strong&gt;cAdvisor&lt;/strong&gt;.&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;scrape_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cAdvisor&lt;/span&gt;
  &lt;span class="na"&gt;scrape_interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
  &lt;span class="na"&gt;static_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;targets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cAdvisor:8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The content of this file defines a job where &lt;strong&gt;Prometheus&lt;/strong&gt; will scrape data from &lt;strong&gt;cAdvisor&lt;/strong&gt; every 10 seconds, using &lt;strong&gt;&lt;em&gt;cAdvisor:8080&lt;/em&gt;&lt;/strong&gt; as defined in the &lt;strong&gt;docker-compose.yml&lt;/strong&gt; file.&lt;/p&gt;

&lt;p&gt;Next, start the services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After successfully executing, you can access each service as follows:&lt;br&gt;
&lt;a href="https://media.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%2Fwzj4ecd5dyb3lf6w6pd6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fwzj4ecd5dyb3lf6w6pd6.png" alt="cAdvisor homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ffudk67i8zlscstws0oga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ffudk67i8zlscstws0oga.png" alt="Prometheus"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fcizy4cx9e8sqpadceyec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fcizy4cx9e8sqpadceyec.png" alt="Grafana"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, the main platform you need to use is &lt;strong&gt;Grafana&lt;/strong&gt;, so it's fine to just focus on learning how to use &lt;strong&gt;Grafana&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you found this post helpful, please show your appreciation by sharing and commenting!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you found this content helpful, please visit &lt;a href="https://howtodevez.blogspot.com/2024/05/monitoring-with-cadvisor-prometheus-and-grafana-on-docker.html" rel="noopener noreferrer"&gt;the original article on my blog&lt;/a&gt; to support the author and explore more interesting content.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/03/sitemap.html" rel="noreferrer noopener"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2FBlogger-FF5722%3Fstyle%3Dfor-the-badge%26logo%3Dblogger%26logoColor%3Dwhite" alt="Blogspot"&gt;&lt;/a&gt;&lt;a href="https://howtodevez.medium.com" rel="noreferrer noopener"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2FMedium-12100E%3Fstyle%3Dfor-the-badge%26logo%3Dmedium%26logoColor%3Dwhite" alt="Blogspot"&gt;&lt;/a&gt;&lt;a href="https://dev.to/chauhoangminhnguyen" rel="noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2Fdev.to-0A0A0A%3Fstyle%3Dfor-the-badge%26logo%3Ddev.to%26logoColor%3Dwhite" alt="Dev.to"&gt;&lt;/a&gt;&lt;a href="https://www.facebook.com/profile.php?id=61557154776384" rel="noreferrer noopener"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2FFacebook-1877F2%3Fstyle%3Dfor-the-badge%26logo%3Dfacebook%26logoColor%3Dwhite" alt="Facebook"&gt;&lt;/a&gt;&lt;a href="https://x.com/DavidNguyenSE" rel="noreferrer noopener"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2FX-000000%3Fstyle%3Dfor-the-badge%26logo%3Dx%26logoColor%3Dwhite" alt="X"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Some series you might find interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/nodejs-practice-series.html" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://howtodevez.blogspot.com/2024/08/react-practice-series.html" rel="noopener noreferrer"&gt;React&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://howtodevez.blogspot.com/2024/08/docker-practice-series.html" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/kubernetes-practice-series.html" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/google-cloud-platform-practice-series.html" rel="noopener noreferrer"&gt;Google Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/devops-practice-series.html" rel="noopener noreferrer"&gt;DevOps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>prometheus</category>
      <category>grafana</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Deploy React Application to Google Kubernetes Engine</title>
      <dc:creator>chauhoangminhnguyen</dc:creator>
      <pubDate>Wed, 11 Sep 2024 14:00:00 +0000</pubDate>
      <link>https://forem.com/chauhoangminhnguyen/deploy-react-application-to-google-kubernetes-engine-1h94</link>
      <guid>https://forem.com/chauhoangminhnguyen/deploy-react-application-to-google-kubernetes-engine-1h94</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this article, I will guide you through deploying a &lt;strong&gt;React Application&lt;/strong&gt; to &lt;strong&gt;Google Kubernetes Engine (GKE)&lt;/strong&gt;. Previously, I wrote an &lt;a href="https://howtodevez.blogspot.com/2024/05/deploying-a-nodejs-server-on-google-kubernetes-engine.html" rel="noopener noreferrer"&gt;article about deploying a &lt;strong&gt;NodeJS Application&lt;/strong&gt; to &lt;strong&gt;GKE&lt;/strong&gt;&lt;/a&gt;, which you can refer to for some basic information before continuing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc47ff6pxat023z67usdq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc47ff6pxat023z67usdq.png" alt="Deploy React to GKE" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps to Follow
&lt;/h2&gt;

&lt;p&gt;The process is quite similar to deploying a &lt;strong&gt;NodeJS&lt;/strong&gt; &lt;strong&gt;Application&lt;/strong&gt; and includes the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Create a &lt;strong&gt;React Application&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; Build a &lt;strong&gt;Docker image&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; Push the &lt;strong&gt;Docker image&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; Deploy the &lt;strong&gt;Docker image&lt;/strong&gt; to &lt;strong&gt;GKE&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You will notice that when working with &lt;strong&gt;Kubernetes&lt;/strong&gt;, the main difference is in the step where you build the &lt;strong&gt;Docker image&lt;/strong&gt;. Depending on the application you need to deploy, there are different ways to build the &lt;strong&gt;Docker image&lt;/strong&gt;. However, the common point is that once you build the &lt;strong&gt;Docker image&lt;/strong&gt;, you have completed almost half of the process. This is because the subsequent steps involving &lt;strong&gt;Kubernetes&lt;/strong&gt; are entirely the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detailed Process
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create a React Application
&lt;/h3&gt;

&lt;p&gt;In this step, you can either use an existing React project or create a new one.&lt;/p&gt;

&lt;p&gt;I will use &lt;strong&gt;Vite&lt;/strong&gt; to create a &lt;strong&gt;React&lt;/strong&gt; project as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn create vite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, select the basic information to initialize the project. Once the project starts successfully, proceed to the next step.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Build Docker Image
&lt;/h3&gt;

&lt;p&gt;First, create a &lt;strong&gt;Dockerfile&lt;/strong&gt;:&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="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build-stage&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 yarn.lock ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;yarn &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--silent&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;yarn build

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;nginx:alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;production-stage&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build-stage /app/dist /usr/share/nginx/html&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["nginx", "-g", "daemon off;"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The image build process is divided into two stages. In the build step, pay attention to the line &lt;strong&gt;&lt;em&gt;RUN yarn build&lt;/em&gt;&lt;/strong&gt; to replace the command with the one that builds your source code into static files corresponding to your project.&lt;/p&gt;

&lt;p&gt;Next, in the &lt;strong&gt;&lt;em&gt;production-stage&lt;/em&gt;&lt;/strong&gt;, pay attention to the line &lt;strong&gt;&lt;em&gt;COPY --from=build-stage /app/dist /usr/share/nginx/html&lt;/em&gt;&lt;/strong&gt; to replace the directory with the static files after the build. In this case, my folder is &lt;strong&gt;&lt;em&gt;dist&lt;/em&gt;&lt;/strong&gt;. Here, I am copying the static files into the &lt;strong&gt;&lt;em&gt;Nginx web server&lt;/em&gt;&lt;/strong&gt;. If you need to &lt;a href="https://howtodevez.blogspot.com/2024/05/using-nginx-on-docker.html" rel="noopener noreferrer"&gt;learn the basics of Nginx, you can refer to this guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next, create a .&lt;strong&gt;&lt;em&gt;dockerignore&lt;/em&gt;&lt;/strong&gt; file to ignore any files that should not be copied during the &lt;strong&gt;Docker image&lt;/strong&gt; build process.&lt;/p&gt;

&lt;p&gt;To build the image, execute the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; react-ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Push Docker Image
&lt;/h3&gt;

&lt;p&gt;To push your &lt;strong&gt;Docker image&lt;/strong&gt; to &lt;strong&gt;Google Cloud Artifact Registry&lt;/strong&gt;, &lt;a href="https://howtodevez.blogspot.com/2024/05/deploying-a-nodejs-server-on-google-kubernetes-engine.html" rel="noopener noreferrer"&gt;check out this article I mentioned earlier&lt;/a&gt;. Alternatively, you can also push it to &lt;strong&gt;Docker Hub&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Deploy Docker Image to GKE
&lt;/h3&gt;

&lt;p&gt;Now, let's create a cluster with the following command:&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="c"&gt;# gcloud container clusters create {cluster name} \&lt;/span&gt;
&lt;span class="c"&gt;#   --project {project id} \&lt;/span&gt;
&lt;span class="c"&gt;#   --zone {zone id} \&lt;/span&gt;
&lt;span class="c"&gt;#   --machine-type {machine type}&lt;/span&gt;

&lt;span class="c"&gt;# ex:&lt;/span&gt;
gcloud container clusters create k8s-cluster &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--project&lt;/span&gt; project-id &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--zone&lt;/span&gt; asia-southeast1-a &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--machine-type&lt;/span&gt; e2-micro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the placeholders for the cluster name, project ID, zone, and machine type as needed.&lt;/p&gt;

&lt;p&gt;As mentioned earlier, when deploying projects to &lt;strong&gt;Kubernetes&lt;/strong&gt;, the main difference lies in how you build the &lt;strong&gt;Docker image&lt;/strong&gt;, which varies by project type. Once you have the Docker image, the content of the &lt;strong&gt;&lt;em&gt;deployment.yml&lt;/em&gt;&lt;/strong&gt; file will be &lt;a href="https://howtodevez.blogspot.com/2024/05/deploying-a-nodejs-server-on-google-kubernetes-engine.html" rel="noopener noreferrer"&gt;similar to the one used for deploying a NodeJS application&lt;/a&gt;. You just need to update the &lt;strong&gt;&lt;em&gt;image&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;port&lt;/em&gt;&lt;/strong&gt; information accordingly.&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;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&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;deployment-name&lt;/span&gt;
  &lt;span class="na"&gt;labels&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;label-name&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;label-name&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;label-name&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&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;react-ts&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gcr.io/{project id}/react-ts&lt;/span&gt; &lt;span class="c1"&gt;# or use image from docker hub&lt;/span&gt;
      &lt;span class="na"&gt;restartPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Always&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&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;service-name&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;label-name&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;label-name&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LoadBalancer&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt; &lt;span class="c1"&gt;# port service&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt; &lt;span class="c1"&gt;# port pod&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that if the &lt;strong&gt;Docker image&lt;/strong&gt; built earlier uses &lt;strong&gt;Nginx&lt;/strong&gt;, it will default to using port &lt;strong&gt;80&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After that, apply to initialize the resources:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdsllu5zas22ccwwygfgj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdsllu5zas22ccwwygfgj.png" alt="Kubectl apply" width="531" height="95"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wait a moment to check that the &lt;strong&gt;pod&lt;/strong&gt;, &lt;strong&gt;service&lt;/strong&gt;, and &lt;strong&gt;deployment&lt;/strong&gt; have been successfully created:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjx85bi4o53ik9c2bwl2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjx85bi4o53ik9c2bwl2.png" alt="Kubectl get all" width="800" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, access the &lt;strong&gt;EXTERNAL-IP&lt;/strong&gt; of the &lt;strong&gt;LoadBalancer&lt;/strong&gt; to see the results.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0kqm5pfjaudk19upvaqm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0kqm5pfjaudk19upvaqm.png" alt="Access external-ip" width="744" height="797"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To delete the resources, use the following command:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvrel50zooeg12teepdy8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvrel50zooeg12teepdy8.png" alt="Delete resources" width="550" height="97"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Through this article, you've learned how to deploy a &lt;strong&gt;React&lt;/strong&gt; project to &lt;strong&gt;Google Kubernetes Engine&lt;/strong&gt;. You can apply the same process to deploy other front-end projects like &lt;strong&gt;Angular&lt;/strong&gt; and &lt;strong&gt;VueJS&lt;/strong&gt;. Just build the project into static files and successfully build the &lt;strong&gt;Docker image.&lt;/strong&gt; The following steps will be the same.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Feel free to share your thoughts in the comments!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you found this content helpful, please visit &lt;a href="https://howtodevez.blogspot.com/2024/05/deploy-react-application-to-google-kubernetes-engine.html" rel="noopener noreferrer"&gt;the original article on my blog&lt;/a&gt; to support the author and explore more interesting content.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/03/sitemap.html" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Rehh51y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Blogger-FF5722%3Fstyle%3Dfor-the-badge%26logo%3Dblogger%26logoColor%3Dwhite" alt="Blogspot" width="102" height="28"&gt;&lt;/a&gt;&lt;a href="https://howtodevez.medium.com" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NabPkFNQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Medium-12100E%3Fstyle%3Dfor-the-badge%26logo%3Dmedium%26logoColor%3Dwhite" alt="Blogspot" width="94" height="28"&gt;&lt;/a&gt;&lt;a href="https://dev.to/chauhoangminhnguyen" rel="noreferrer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xz2MGu8c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/dev.to-0A0A0A%3Fstyle%3Dfor-the-badge%26logo%3Ddev.to%26logoColor%3Dwhite" alt="Dev.to" width="88" height="28"&gt;&lt;/a&gt;&lt;a href="https://www.facebook.com/profile.php?id=61557154776384" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hohnj5TU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Facebook-1877F2%3Fstyle%3Dfor-the-badge%26logo%3Dfacebook%26logoColor%3Dwhite" alt="Facebook" width="111" height="28"&gt;&lt;/a&gt;&lt;a href="https://x.com/DavidNguyenSE" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tT2E75Wa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/X-000000%3Fstyle%3Dfor-the-badge%26logo%3Dx%26logoColor%3Dwhite" alt="X" width="52" height="28"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Some series you might find interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/nodejs-practice-series.html" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://howtodevez.blogspot.com/2024/08/react-practice-series.html" rel="noopener noreferrer"&gt;React&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://howtodevez.blogspot.com/2024/08/docker-practice-series.html" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/kubernetes-practice-series.html" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/google-cloud-platform-practice-series.html" rel="noopener noreferrer"&gt;Google Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/09/devops-practice-series.html" rel="noopener noreferrer"&gt;DevOps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>gke</category>
      <category>googlecloud</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Using Nginx on Docker</title>
      <dc:creator>chauhoangminhnguyen</dc:creator>
      <pubDate>Tue, 10 Sep 2024 14:00:00 +0000</pubDate>
      <link>https://forem.com/chauhoangminhnguyen/using-nginx-on-docker-3472</link>
      <guid>https://forem.com/chauhoangminhnguyen/using-nginx-on-docker-3472</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Nginx&lt;/strong&gt; is a popular open-source web server known for its superior performance compared to the &lt;strong&gt;Apache&lt;/strong&gt; web server. &lt;strong&gt;Nginx&lt;/strong&gt; supports various functionalities, including deploying an &lt;strong&gt;API gateway (reverse proxy)&lt;/strong&gt;, &lt;strong&gt;load balancer&lt;/strong&gt;, and &lt;strong&gt;email proxy&lt;/strong&gt;. It was initially developed to build a web server capable of efficiently handling &lt;strong&gt;10,000&lt;/strong&gt; concurrent connections with low memory usage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xs4pcpwjqb14ykxredz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xs4pcpwjqb14ykxredz.png" alt="Nginx on docker" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Run Nginx with Docker
&lt;/h2&gt;

&lt;p&gt;To use &lt;strong&gt;Nginx&lt;/strong&gt; with &lt;strong&gt;Docker&lt;/strong&gt;, simply execute the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-dp&lt;/span&gt; 8080:80 nginx:alpine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, &lt;strong&gt;Nginx&lt;/strong&gt; uses port &lt;strong&gt;80&lt;/strong&gt;, but you can map it to a different port if needed.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpkuob8493cx9kxu1hjjq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpkuob8493cx9kxu1hjjq.png" alt="Welcome to nginx" width="620" height="291"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Custom Nginx Configuration
&lt;/h2&gt;

&lt;p&gt;To customize the &lt;strong&gt;Nginx&lt;/strong&gt; configuration, first, create a &lt;strong&gt;docker-compose.yml&lt;/strong&gt; file with the following content:&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;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;serviceName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:alpine&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;8080:80&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./default.conf:/etc/nginx/conf.d/default.conf&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./index.html:/usr/share/nginx/html/index.html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;volumes&lt;/strong&gt; field, note that I have mapped two files: &lt;strong&gt;default.conf&lt;/strong&gt; to change the default &lt;strong&gt;Nginx&lt;/strong&gt; configuration and &lt;strong&gt;index.html&lt;/strong&gt; to customize the default interface when accessing the &lt;strong&gt;Nginx&lt;/strong&gt; web view.&lt;/p&gt;

&lt;p&gt;The content of the &lt;strong&gt;default.conf&lt;/strong&gt; file is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;server&lt;/span&gt; {
  &lt;span class="n"&gt;listen&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt; &lt;span class="n"&gt;default_server&lt;/span&gt;;
  &lt;span class="n"&gt;listen&lt;/span&gt; [::]:&lt;span class="m"&gt;80&lt;/span&gt; &lt;span class="n"&gt;default_server&lt;/span&gt;;

  &lt;span class="n"&gt;server_name&lt;/span&gt; &lt;span class="err"&gt;_&lt;/span&gt;;
  &lt;span class="n"&gt;root&lt;/span&gt; /&lt;span class="n"&gt;usr&lt;/span&gt;/&lt;span class="n"&gt;share&lt;/span&gt;/&lt;span class="n"&gt;nginx&lt;/span&gt;/&lt;span class="n"&gt;html&lt;/span&gt;;

  &lt;span class="n"&gt;location&lt;/span&gt; / {
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the content of the &lt;strong&gt;index.html&lt;/strong&gt; file, which you can modify as needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Nginx&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;This is custom index page&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, run Docker Compose with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result will be as follows:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7kyuyreffru0debzfb0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7kyuyreffru0debzfb0w.png" alt="Custom index page" width="378" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you found value in this post, show your appreciation by sharing and commenting!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you found this content helpful, please visit &lt;a href="https://howtodevez.blogspot.com/2024/05/using-nginx-on-docker.html" rel="noopener noreferrer"&gt;the original article on my blog&lt;/a&gt; to support the author and explore more interesting content.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://howtodevez.blogspot.com/2024/03/sitemap.html" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Rehh51y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Blogger-FF5722%3Fstyle%3Dfor-the-badge%26logo%3Dblogger%26logoColor%3Dwhite" alt="Blogspot" width="102" height="28"&gt;&lt;/a&gt;&lt;a href="https://howtodevez.medium.com" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NabPkFNQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Medium-12100E%3Fstyle%3Dfor-the-badge%26logo%3Dmedium%26logoColor%3Dwhite" alt="Blogspot" width="94" height="28"&gt;&lt;/a&gt;&lt;a href="https://dev.to/chauhoangminhnguyen" rel="noreferrer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xz2MGu8c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/dev.to-0A0A0A%3Fstyle%3Dfor-the-badge%26logo%3Ddev.to%26logoColor%3Dwhite" alt="Dev.to" width="88" height="28"&gt;&lt;/a&gt;&lt;a href="https://www.facebook.com/profile.php?id=61557154776384" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hohnj5TU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/Facebook-1877F2%3Fstyle%3Dfor-the-badge%26logo%3Dfacebook%26logoColor%3Dwhite" alt="Facebook" width="111" height="28"&gt;&lt;/a&gt;&lt;a href="https://x.com/DavidNguyenSE" rel="noreferrer noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tT2E75Wa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/X-000000%3Fstyle%3Dfor-the-badge%26logo%3Dx%26logoColor%3Dwhite" alt="X" width="52" height="28"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Some series you might find interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/nodejs-practice-series.html" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://howtodevez.blogspot.com/2024/08/react-practice-series.html" rel="noopener noreferrer"&gt;React&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://howtodevez.blogspot.com/2024/08/docker-practice-series.html" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://howtodevez.blogspot.com/2024/08/kubernetes-practice-series.html" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nginx</category>
      <category>docker</category>
      <category>beginners</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
