<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dev Rama</title>
    <description>The latest articles on DEV Community by Dev Rama (@devrama).</description>
    <link>https://dev.to/devrama</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3953800%2F78b864e0-924b-4497-85db-0e7f2276254c.png</url>
      <title>DEV Community: Dev Rama</title>
      <link>https://dev.to/devrama</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/devrama"/>
    <language>en</language>
    <item>
      <title>Cara Setup Reverse Proxy dan SSL Let's Encrypt</title>
      <dc:creator>Dev Rama</dc:creator>
      <pubDate>Mon, 01 Jun 2026 08:29:59 +0000</pubDate>
      <link>https://dev.to/devrama/cara-setup-reverse-proxy-dan-ssl-lets-encrypt-4b3h</link>
      <guid>https://dev.to/devrama/cara-setup-reverse-proxy-dan-ssl-lets-encrypt-4b3h</guid>
      <description>&lt;p&gt;Berikut adalah panduan lengkap langkah demi langkah untuk melakukan konfigurasi Reverse Proxy menggunakan Nginx yang diarahkan ke aplikasi di port 3030, menggunakan domain devrama.my.id, dan diamankan dengan SSL gratis dari Let's Encrypt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠️ Langkah 1: Persiapan Awal (Prerequisites)&lt;/strong&gt;&lt;br&gt;
Sebelum memulai, pastikan:&lt;br&gt;
Domain devrama.my.id sudah diarahkan (A Record) ke IP Publik Server/VPS kamu melalui DNS Management (misalnya via Cloudflare/IdCloudHost/Niagahoster).&lt;br&gt;
Aplikasi kamu sudah berjalan di port 3030 (bisa dicek dengan perintah curl localhost:3030).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 Langkah 2: Install Nginx dan Certbot&lt;/strong&gt;&lt;br&gt;
Masuk ke server kamu via SSH, lalu jalankan perintah berikut untuk memperbarui sistem dan menginstal Nginx serta Certbot (alat pengelola SSL Let's Encrypt).&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;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nginx certbot python3-certbot-nginx &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pastikan Nginx sudah berjalan:&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 start nginx
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;📄 Langkah 3: Konfigurasi Reverse Proxy Nginx&lt;/strong&gt;&lt;br&gt;
Kita akan membuat file konfigurasi baru khusus untuk domain kamu.&lt;br&gt;
Hapus default Nginx port 80&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 rm&lt;/span&gt; /etc/nginx/sites-enabled/default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Buat file konfigurasi baru di direktori Nginx:&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;nano /etc/nginx/sites-available/devrama.my.id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Salin dan tempel kode berikut ke dalam file tersebut (konfigurasi HTTP port 80 untuk awal):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;devrama.my.id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://127.0.0.1:3030&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# Mengarahkan trafik ke port aplikasi&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_http_version&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;# Header penting agar aplikasi tahu IP asli dari pengunjung&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Upgrade&lt;/span&gt; &lt;span class="nv"&gt;$http_upgrade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Connection&lt;/span&gt; &lt;span class="s"&gt;'upgrade'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_cache_bypass&lt;/span&gt; &lt;span class="nv"&gt;$http_upgrade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-Proto&lt;/span&gt; &lt;span class="nv"&gt;$scheme&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simpan dan keluar (Tekan CTRL + O, lalu Enter, kemudian CTRL + X).&lt;br&gt;
Aktifkan konfigurasi dengan membuat symlink ke folder sites-enabled:&lt;br&gt;
sudo ln -s /etc/nginx/sites-available/devrama.my.id /etc/nginx/sites-enabled/&lt;/p&gt;

&lt;p&gt;Tes apakah konfigurasi Nginx sudah benar dan tidak ada eror &lt;em&gt;syntax&lt;/em&gt;:&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;nginx &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jika muncul pesan nginx: configuration file ... test is successful, artinya aman!&lt;br&gt;
Restart Nginx untuk menerapkan perubahan:&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 restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🔒 Langkah 4: Install SSL Let's Encrypt&lt;/strong&gt;&lt;br&gt;
Sekarang, kita akan menggunakan Certbot untuk mengamankan domain dengan SSL (HTTPS). Kerennya, Certbot akan otomatis mengubah file konfigurasi Nginx kita tadi agar mendukung HTTPS.&lt;/p&gt;

&lt;p&gt;Jalankan perintah Certbot berikut:&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;certbot &lt;span class="nt"&gt;--nginx&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; devrama.my.id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Certbot akan menanyakan beberapa hal saat pertama kali dijalankan:&lt;br&gt;
Email: Masukkan email aktifmu (untuk notifikasi jika SSL akan kedaluwarsa).&lt;/p&gt;

&lt;p&gt;Terms of Service: Ketik A lalu Enter untuk menyetujui.&lt;br&gt;
Share Email: Ketik Y atau N (bebas).&lt;br&gt;
Redirect HTTP to HTTPS: Jika muncul pilihan untuk mengalihkan otomatis trafik HTTP ke HTTPS, pilih opsi Redirect (biasanya opsi nomor 2).&lt;/p&gt;

&lt;p&gt;Jika berhasil, kamu akan melihat pesan sukses:&lt;br&gt;
Congratulations! You have successfully enabled HTTPS on &lt;a href="https://devrama.my.id" rel="noopener noreferrer"&gt;https://devrama.my.id&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔄 Langkah 5: Otomatisasi Perpanjangan SSL (Auto-Renewal)&lt;/strong&gt;&lt;br&gt;
SSL Let's Encrypt hanya berlaku selama 90 hari. Namun, Certbot secara otomatis membuat cron job di server untuk memperbaruinya sebelum kedaluwarsa.Untuk memastikan fitur auto-renewal ini berfungsi dengan baik, kamu bisa mengujinya dengan perintah:&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;certbot renew &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jika tidak ada eror, maka SSL kamu akan diperbarui otomatis selamanya tanpa perlu kamu urus lagi secara manual.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Selesai!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sekarang kamu bisa membuka browser dan mengakses &lt;a href="https://devrama.my.id" rel="noopener noreferrer"&gt;https://devrama.my.id&lt;/a&gt;. Nginx akan otomatis menerima trafik aman (HTTPS) di port 443, meneruskannya ke aplikasi internal kamu di port 3030, dan mengembalikan responsnya ke pengguna dengan mulus.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Final Project: Cloud Full-Stack Deployment</title>
      <dc:creator>Dev Rama</dc:creator>
      <pubDate>Mon, 01 Jun 2026 05:08:06 +0000</pubDate>
      <link>https://dev.to/devrama/final-project-cloud-full-stack-deployment-1c16</link>
      <guid>https://dev.to/devrama/final-project-cloud-full-stack-deployment-1c16</guid>
      <description>&lt;h2&gt;
  
  
  ☁️ Final Project: Cloud Full-Stack Deployment
&lt;/h2&gt;

&lt;p&gt;Proyek ini mendokumentasikan proses deployment aplikasi web (Node.js + Nginx) ke AWS EC2 menggunakan Docker, CI/CD GitHub Actions, Reverse Proxy dengan SSL otomatis (Let's Encrypt), serta monitoring stack (Prometheus &amp;amp; Grafana).&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠 Tech Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Kategori&lt;/th&gt;
&lt;th&gt;Teknologi&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Runtime/Build&lt;/td&gt;
&lt;td&gt;Node.js 22 (Alpine)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web Server&lt;/td&gt;
&lt;td&gt;Nginx (Alpine)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container&lt;/td&gt;
&lt;td&gt;Docker &amp;amp; Docker Compose&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI/CD&lt;/td&gt;
&lt;td&gt;GitHub Actions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud&lt;/td&gt;
&lt;td&gt;AWS EC2 (Ubuntu 24.04 LTS, t3.micro)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security/Proxy&lt;/td&gt;
&lt;td&gt;Nginx Reverse Proxy, Let's Encrypt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoring&lt;/td&gt;
&lt;td&gt;Prometheus, Grafana, Node Exporter&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;ul&gt;
&lt;li&gt;✅ Akun GitHub &amp;amp; Repository&lt;/li&gt;
&lt;li&gt;✅ Akun DockerHub &amp;amp; Access Token&lt;/li&gt;
&lt;li&gt;✅ Akun AWS &amp;amp; Key Pair (&lt;code&gt;.pem&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;✅ Domain yang sudah diarahkan ke IP EC2 (&lt;code&gt;A Record&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;✅ Docker, Git, dan Node.js 22 terinstall di mesin lokal&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Local Development &amp;amp; Testing
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clone repository&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git clone https://github.com/codebucks27/wibe-studio.git
   &lt;span class="nb"&gt;cd &lt;/span&gt;repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Build &amp;amp; Run Docker container&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   docker build &lt;span class="nt"&gt;-t&lt;/span&gt; wibe-studio &lt;span class="nb"&gt;.&lt;/span&gt;
   docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 wibe-studio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Akses aplikasi&lt;/strong&gt;
Buka browser: &lt;code&gt;http://localhost:8080&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

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




&lt;h2&gt;
  
  
  📦 Registry &amp;amp; Version Control
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔹 Push ke DockerHub
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker login
docker tag wibe-studio devrama404/wibe-studio:latest
docker push devrama404/wibe-studio:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h3&gt;
  
  
  🔹 Push ke GitHub
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"first commit"&lt;/span&gt;
git branch &lt;span class="nt"&gt;-M&lt;/span&gt; main
git remote add origin https://github.com/devrama404/wibe-studio.git
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ☁️ AWS EC2 Setup
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Launch Instance&lt;/strong&gt;
OS: &lt;code&gt;Ubuntu Server 24.04 LTS&lt;/code&gt; | Tipe: &lt;code&gt;t3.micro&lt;/code&gt; | Key Pair: Buat &amp;amp; simpan &lt;code&gt;.pem&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSH ke Server&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;chmod &lt;/span&gt;400 key.pem
   ssh &lt;span class="nt"&gt;-i&lt;/span&gt; key.pem ubuntu@&amp;lt;EC2_PUBLIC_IP&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install Docker &amp;amp; Git&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; ca-certificates curl git
   &lt;span class="nb"&gt;sudo install&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; 0755 &lt;span class="nt"&gt;-d&lt;/span&gt; /etc/apt/keyrings
   &lt;span class="nb"&gt;sudo &lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://download.docker.com/linux/ubuntu/gpg &lt;span class="nt"&gt;-o&lt;/span&gt; /etc/apt/keyrings/docker.asc
   &lt;span class="nb"&gt;sudo chmod &lt;/span&gt;a+r /etc/apt/keyrings/docker.asc
   &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [arch=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dpkg &lt;span class="nt"&gt;--print-architecture&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; /etc/os-release &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;UBUNTU_CODENAME&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;$VERSION_CODENAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; stable"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/docker.list &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
   &lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
   &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
   &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; docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔄 CI/CD Pipeline (GitHub Actions)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Setup Secrets
&lt;/h3&gt;

&lt;p&gt;Masuk ke &lt;code&gt;GitHub Repo → Settings → Secrets and variables → Actions&lt;/code&gt; dan tambahkan:&lt;br&gt;
| Secret Name          | Value Contoh               |&lt;br&gt;
|----------------------|----------------------------|&lt;br&gt;
| &lt;code&gt;DOCKERHUB_USERNAME&lt;/code&gt; | &lt;code&gt;devrama404&lt;/code&gt;               |&lt;br&gt;
| &lt;code&gt;DOCKERHUB_TOKEN&lt;/code&gt;    | &lt;code&gt;dckr_pat_xxxxxxxxxxxxx&lt;/code&gt;   |&lt;br&gt;
| &lt;code&gt;EC2_HOST&lt;/code&gt;           | &lt;code&gt;&amp;lt;IP_EC2&amp;gt;&lt;/code&gt;                 |&lt;br&gt;
| &lt;code&gt;EC2_USER&lt;/code&gt;           | &lt;code&gt;ubuntu&lt;/code&gt;                   |&lt;br&gt;
| &lt;code&gt;SSH_PRIVATE_KEY&lt;/code&gt;    | Isi lengkap &lt;code&gt;key.pem&lt;/code&gt; Anda |&lt;/p&gt;

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

&lt;p&gt;Buat file &lt;code&gt;.github/workflows/deploy.yml&lt;/code&gt;. Pipeline akan menjalankan:&lt;br&gt;&lt;br&gt;
&lt;code&gt;Checkout → Setup Node 22 → Install Deps → Build App → Docker Login → Build &amp;amp; Push Image → SSH Deploy to EC2 (port 80)&lt;/code&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CI-CD Pipeline&lt;/span&gt;

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

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

   &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&lt;/span&gt;
       &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&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;Setup Node&lt;/span&gt;
       &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
       &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;22&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;Install dependencies&lt;/span&gt;
       &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install --legacy-peer-deps&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;Build app&lt;/span&gt;
       &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run build&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;Login Docker Hub&lt;/span&gt;
       &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/login-action@v3&lt;/span&gt;
       &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DOCKERHUB_USERNAME }}&lt;/span&gt;
         &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DOCKERHUB_TOKEN }}&lt;/span&gt;

     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build Docker image&lt;/span&gt;
       &lt;span class="na"&gt;run&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 ${{ secrets.DOCKERHUB_USERNAME }}/wibe-studio:latest .&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;Push Docker image&lt;/span&gt;
       &lt;span class="na"&gt;run&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 push ${{ secrets.DOCKERHUB_USERNAME }}/wibe-studio:latest&lt;/span&gt;

     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to EC2&lt;/span&gt;
       &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appleboy/ssh-action@v1.0.3&lt;/span&gt;
       &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.EC2_HOST }}&lt;/span&gt;
         &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.EC2_USER }}&lt;/span&gt;
         &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_PRIVATE_KEY }}&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 pull ${{ secrets.DOCKERHUB_USERNAME }}/wibe-studio:latest&lt;/span&gt;

           &lt;span class="s"&gt;docker stop wibe-studio || true&lt;/span&gt;
           &lt;span class="s"&gt;docker rm wibe-studio || true&lt;/span&gt;

           &lt;span class="s"&gt;docker run -d \&lt;/span&gt;
             &lt;span class="s"&gt;--name wibe-studio \&lt;/span&gt;
             &lt;span class="s"&gt;-p 8080:80 \&lt;/span&gt;
             &lt;span class="s"&gt;${{ secrets.DOCKERHUB_USERNAME }}/wibe-studio:latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;&lt;strong&gt;Cek Hasilnya&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg6nfhe44dipu80fb4qgj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg6nfhe44dipu80fb4qgj.png" alt=" " width="799" height="301"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  🔒 Reverse Proxy &amp;amp; SSL Setup
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install Nginx &amp;amp; Certbot&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; nginx certbot python3-certbot-nginx
   &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; nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Konfigurasi Reverse Proxy&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo rm&lt;/span&gt; /etc/nginx/sites-enabled/default
   &lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/nginx/sites-available/wibestudio.devrama.my.id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Isi konfigurasi:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;   &lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;wibestudio.devrama.my.id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

       &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://127.0.0.1:8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
           &lt;span class="kn"&gt;proxy_http_version&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
           &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Upgrade&lt;/span&gt; &lt;span class="nv"&gt;$http_upgrade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
           &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Connection&lt;/span&gt; &lt;span class="s"&gt;'upgrade'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
           &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
           &lt;span class="kn"&gt;proxy_cache_bypass&lt;/span&gt; &lt;span class="nv"&gt;$http_upgrade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
           &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
           &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
           &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-Proto&lt;/span&gt; &lt;span class="nv"&gt;$scheme&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /etc/nginx/sites-available/wibestudio.devrama.my.id /etc/nginx/sites-enabled/
   &lt;span class="nb"&gt;sudo &lt;/span&gt;nginx &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Aktifkan SSL (Let's Encrypt)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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;certbot &lt;span class="nt"&gt;--nginx&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; wibestudio.devrama.my.id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Ikuti prompt, pilih &lt;code&gt;Redirect (2)&lt;/code&gt; untuk mengalihkan HTTP ke HTTPS secara otomatis.&lt;/p&gt;

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




&lt;h2&gt;
  
  
  📊 Monitoring Stack
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Buat Folder &amp;amp; File Konfigurasi&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;mkdir &lt;/span&gt;monitoring &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;monitoring
   nano docker-compose.yml
   nano prometheus.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Jalankan Stack&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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;ol&gt;
&lt;li&gt;
&lt;strong&gt;Akses Dashboard&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;📈 &lt;strong&gt;Grafana:&lt;/strong&gt; &lt;code&gt;http://&amp;lt;EC2_IP&amp;gt;:3001&lt;/code&gt; | Default: &lt;code&gt;admin&lt;/code&gt; / &lt;code&gt;admin&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🕵️ &lt;strong&gt;Prometheus:&lt;/strong&gt; &lt;code&gt;http://&amp;lt;EC2_IP&amp;gt;:9090&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hubungkan Grafana ke Prometheus&lt;/strong&gt;
&lt;code&gt;Settings → Data Sources → Add Prometheus → URL: http://prometheus:9090 → Save &amp;amp; Test&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buat Panel Dashboard (Contoh PromQL)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;CPU: &lt;code&gt;node_cpu_seconds_total&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;RAM: &lt;code&gt;node_memory_MemAvailable_bytes&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Load: &lt;code&gt;node_load1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

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




&lt;h2&gt;
  
  
  📁 Project Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📦 repo-root
├── 📂 .github/workflows/
│   └── deploy.yml          # CI/CD Pipeline
├── 📄 Dockerfile           # Node.js Builder → Nginx
├── 📂 monitoring/
│   ├── docker-compose.yml  # Monitoring Stack
│   └── prometheus.yml      # Prometheus Config
└── 📂 src/                 # Source Code Aplikasi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚠️ Troubleshooting &amp;amp; Catatan
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔐 Pastikan &lt;strong&gt;Security Group EC2&lt;/strong&gt; membuka port: &lt;code&gt;80&lt;/code&gt;, &lt;code&gt;443&lt;/code&gt;, &lt;code&gt;8080&lt;/code&gt;, &lt;code&gt;3001&lt;/code&gt;, &lt;code&gt;9090&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;🔄 Port &lt;code&gt;proxy_pass&lt;/code&gt; di Nginx (&lt;code&gt;8080&lt;/code&gt;) harus sesuai dengan port mapping container lokal. Di EC2, CI/CD langsung map ke port &lt;code&gt;80&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;🐳 Token DockerHub bisa dibuat di: DockerHub → Settings → Security → Access Tokens.&lt;/li&gt;
&lt;li&gt;🔑 &lt;code&gt;SSH_PRIVATE_KEY&lt;/code&gt; di GitHub Secrets harus berisi seluruh isi file &lt;code&gt;.pem&lt;/code&gt; (termasuk &lt;code&gt;-----BEGIN...&lt;/code&gt; dan &lt;code&gt;-----END...&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>aws</category>
      <category>cicd</category>
      <category>devops</category>
      <category>docker</category>
    </item>
    <item>
      <title>Serverless Computing</title>
      <dc:creator>Dev Rama</dc:creator>
      <pubDate>Wed, 27 May 2026 07:35:16 +0000</pubDate>
      <link>https://dev.to/devrama/serverless-computing-6i1</link>
      <guid>https://dev.to/devrama/serverless-computing-6i1</guid>
      <description>&lt;p&gt;&lt;strong&gt;Serverless Function&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tulis kode di laptop/Lokal&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;nano lambda_function.py&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Isi Folder &lt;/p&gt;

&lt;p&gt;import json&lt;/p&gt;

&lt;p&gt;def lambda_handler(event, context):&lt;br&gt;
    name = event.get('queryStringParameters', {}).get('name', 'Rama')&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return {
    'statusCode': 200,
    'body': json.dumps({
        "message": f"Hello, {name}!"
    })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Ctrl+o&lt;br&gt;&lt;br&gt;
Ctrl+x&lt;/p&gt;

&lt;p&gt;Buat file menjadi zip&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;zip lambda_function.zip lambda_function.py&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Buka Aws Dan Pilih Menu Lambda&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pilih Create Function&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pilih author from scratch&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isi nama functionnya&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pilih runtime nya&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;![][image1]&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Upload Code yang Telah di buat tadi&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pilih upload file dan pilih file yang telah di buat&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kemudian pilih deploy&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;![][image2]&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tambahkan Trigger&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pilih menu configuration dan pilih add trigger&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trigger Configuration = API GATEWAY&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pilih Create a New API&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API type nya HTTP API&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Klik Add&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;![][image3]&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tes API Gateway apakah sudah berhasil atau belum&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Klik link pada API endpoint&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;![][image4]&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Berhasillll&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kamu Sudah berhasil menjaalan test API Gateway&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;![][image5]&lt;/p&gt;

</description>
      <category>aws</category>
      <category>python</category>
      <category>serverless</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
