<?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: Yues IT</title>
    <description>The latest articles on DEV Community by Yues IT (@yues_it).</description>
    <link>https://dev.to/yues_it</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%2F1971369%2F5b591f64-34e1-434a-a517-e253597da2bd.png</url>
      <title>DEV Community: Yues IT</title>
      <link>https://dev.to/yues_it</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yues_it"/>
    <language>en</language>
    <item>
      <title>[YuIT Docs📜]⚛️FrontEnd System Design</title>
      <dc:creator>Yues IT</dc:creator>
      <pubDate>Sun, 16 Nov 2025 16:55:56 +0000</pubDate>
      <link>https://dev.to/yues_it/yuit-docsfrontend-system-design-od4</link>
      <guid>https://dev.to/yues_it/yuit-docsfrontend-system-design-od4</guid>
      <description>&lt;h2&gt;
  
  
  All source files and library &lt;a href="https://github.com/YuesIt17/yuit-docs-system-design/" rel="noopener noreferrer"&gt;👉in this repo&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Let's see some approaches for authorization of an app via &lt;strong&gt;FrontEnd System Design&lt;/strong&gt; using the following technologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.keycloak.org/" rel="noopener noreferrer"&gt;Keycloak&lt;/a&gt; is Open Source Identity and Access Management. Add authentication to applications and secure services with minimum effort. No need to deal with storing users or authenticating users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://gogatekeeper.github.io/gatekeeper/" rel="noopener noreferrer"&gt;Gogatekeeper&lt;/a&gt; is a proxy which integrates with Keycloak IDP Provider, it supports both access tokens in a browser cookie or bearer tokens.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.npmjs.com/package/keycloak-js" rel="noopener noreferrer"&gt;Keycloak JS&lt;/a&gt; is secure web applications. The adapter uses OpenID Connect protocol under the covers. You can take a look at the Securing applications and services with OpenID Connect guide for the more generic information about OpenID Connect endpoints and capabilities. &lt;a href="https://www.keycloak.org/securing-apps/javascript-adapter" rel="noopener noreferrer"&gt;The specific guide for this client&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Let's drawing those approaches via Component design
&lt;/h2&gt;

&lt;p&gt;1️⃣ Component &lt;a href="https://github.com/YuesIt17/yuit-docs-system-design/blob/main/frontend/sd_frontend_gogatekeeper.png" rel="noopener noreferrer"&gt;diagram for authorization via Gogatekeeper + Keycloak&lt;/a&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%2Frhrvnuiqi9n3icd7s3s4.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%2Frhrvnuiqi9n3icd7s3s4.png" alt="sd_frontend_gogatekeeper" width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2️⃣ Component &lt;a href="https://github.com/YuesIt17/yuit-docs-system-design/blob/main/frontend/sd_frontend_keycloak_js.png" rel="noopener noreferrer"&gt;diagram for authorization via Keycloak.js&lt;/a&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%2F7is0jlbbxyx1w9jwx6ju.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%2F7is0jlbbxyx1w9jwx6ju.png" alt="sd_frontend_keycloak_js" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>frontend</category>
      <category>documentation</category>
      <category>architecture</category>
    </item>
    <item>
      <title>[YuIT Docs📜]📐System Design</title>
      <dc:creator>Yues IT</dc:creator>
      <pubDate>Sat, 12 Jul 2025 13:12:02 +0000</pubDate>
      <link>https://dev.to/yues_it/system-design-courses-in-practice-for-beginners-334g</link>
      <guid>https://dev.to/yues_it/system-design-courses-in-practice-for-beginners-334g</guid>
      <description>&lt;h2&gt;
  
  
  All source files and library &lt;a href="https://github.com/YuesIt17/yuit-docs-system-design/" rel="noopener noreferrer"&gt;👉in this repo&lt;/a&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is System Design?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;System design is the process of developing and planning the architecture, components, modules, and interfaces for creating complex software, hardware, or information systems.&lt;/p&gt;

&lt;p&gt;There is the good tutorial about System Design in &lt;a href="https://www.geeksforgeeks.org/system-design/system-design-tutorial/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article I want to show how to apply SD in practice -&amp;gt; step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's try to create a system design for the &lt;strong&gt;Dating Service&lt;/strong&gt; (analog of Tinder, Bumble, Badoo, etc.)
&lt;/h2&gt;

&lt;p&gt;1️⃣ &lt;strong&gt;&lt;a href="https://www.geeksforgeeks.org/system-design/what-is-requirements-gathering-process/" rel="noopener noreferrer"&gt;Requirements Gathering Process&lt;/a&gt;&lt;/strong&gt;. &lt;br&gt;
In this step, let's consider &lt;strong&gt;&lt;a href="https://www.geeksforgeeks.org/functional-vs-non-functional-requirements/" rel="noopener noreferrer"&gt;Functional vs. Non Functional Requirements&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Functional requirements&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the user can register in the application&lt;/li&gt;
&lt;li&gt;the user can create/edit a personal profile&lt;/li&gt;
&lt;li&gt;users can receive notifications when receiving dating offers or when two users are automatically matched&lt;/li&gt;
&lt;li&gt;the user can accept/reject dating offers&lt;/li&gt;
&lt;li&gt;the user can view a list of other users according to their preferences and their location&lt;/li&gt;
&lt;li&gt;the user can upload photos/small videos&lt;/li&gt;
&lt;li&gt;administrators should have their own functionality for moderation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Non-functional requirements&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System responsiveness (so that the user can quickly view the list of potential candidates for dating)&lt;/li&gt;
&lt;li&gt;High availability (as the load increases, the application must scale and be available, otherwise users will go to another similar service)&lt;/li&gt;
&lt;li&gt;Consistency (when accepting/rejecting offers between users)&lt;/li&gt;
&lt;li&gt;Provide monitoring with alerts for the system&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;2️⃣ &lt;a href="https://www.geeksforgeeks.org/system-design/capacity-estimation-in-systems-design/" rel="noopener noreferrer"&gt;&lt;strong&gt;Capacity Estimation&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Metrics for Capacity Estimation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;100M - Monthly Active Users (&lt;strong&gt;MAU&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;10M - Daily Active Users (&lt;strong&gt;DAU&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;about 10M - registered users (&lt;strong&gt;REG_USERS&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;about 3MB(megabyte) - user data (&lt;strong&gt;USER_DATA&lt;/strong&gt;): messages, photos/small videos, profile data, etc.&lt;/li&gt;
&lt;li&gt;let's assume that the ratio of writing to reading data is 1 to 10 (&lt;strong&gt;RATIO_WRITE_READ&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;on average one user performs about 50 operations (&lt;strong&gt;OPERS&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;86400 - number of seconds in a day (&lt;strong&gt;NUM_SEC_DAY&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;365 - number of days in the year (&lt;strong&gt;DAYS_OF_YAER&lt;/strong&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Estimated load indicators&lt;/strong&gt;&lt;br&gt;
Requests Per Second (RPS) or Queries Per Second (QPS):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;RPS_READ&lt;/strong&gt; = OPERS*REG_USERS/NUM_SEC_DAY = 50*10M/86400 = 5800&lt;/em&gt; - RPS for reading&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;RPS_WRITE&lt;/strong&gt; = RPS_READ/RATIO_WRITE_READ = 5800/10 = 580&lt;/em&gt; - RPS for writing data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Network Bandwidth (NB)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;NB&lt;/strong&gt; = USER_DATA*RPS_WRITE = 3MB*580  ~ 2000 MB/sec (2GB/sec)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;NB_PER_YEAR&lt;/strong&gt; = NB*NUM_SEC_DAY*DAYS_OF_YAER = 2GB/sec * 86400sec * 365days ~ 65PB + 20% (with Overhead) ~ 80PB(petabyte)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Storage load (SL)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;SL&lt;/strong&gt; = DAU*USER_DATA = 10M*3MB = 30TB(terabyte) ~ 30TB + 20% (with Overhead) ~ 40TB&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Calculation of cloud infrastructure capacity&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;let's assume that one instance can handle with about 500 RPS: &lt;em&gt;&lt;strong&gt;NUMBER_INST&lt;/strong&gt; = RPS_READ(Peak RPS)/500 = 5800/500 + 20%(with Overhead) ~ 15 instances&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;Instances for Network Bandwidth: Convert to Gbps (125 MB/sec = 1 Gbps)  &lt;em&gt;&lt;strong&gt;NB&lt;/strong&gt; = 2000/125 ~ 16 Gbps&lt;/em&gt;; if each instance can handle 1 Gbps, then &lt;em&gt;&lt;strong&gt;NUMBER_INST_NB&lt;/strong&gt; = 16/1 ~ 20 instances (with Overhead)&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;Storage, if each storage instance can handle 5TB of data, then &lt;em&gt;&lt;strong&gt;NUMBER_INST_STOR&lt;/strong&gt; = SL/5 = 40/5 = 8 instances&lt;/em&gt;. If you implement 2x replication for fault tolerance, you need twice the storage: &lt;em&gt;8*2 = 16 ~ 20 instances (with Overhead)&lt;/em&gt;;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How much does it cost?&lt;/strong&gt;💵&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Network Bandwidth (~0.1$ for 1GB): &lt;em&gt;80PB = 80,000,000GB*0.1$ = 8M$&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;SSD storage (~300$ for 1TB): &lt;em&gt;40TB * 300$ = 12,000$&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;3️⃣ &lt;a href="https://www.geeksforgeeks.org/system-design/what-is-high-level-design-learn-system-design/" rel="noopener noreferrer"&gt;&lt;strong&gt;High-Level Design&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;By high-level design we will mean a design that minimizes the basic scenarios of interaction with the system, but does not reflect all the complexity of interaction between the large number of real components and does not take into account the load, under which the system will be in a productive environment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this step, let's draw the scheme of components for our system using &lt;a href="https://excalidraw.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Excalidraw&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To utilize &lt;strong&gt;the following components of SD&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%2Fs5ek1gfgxlkc9f5sk8hi.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%2Fs5ek1gfgxlkc9f5sk8hi.png" alt="Components of SD" width="800" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://excalidraw-libraries-med12qlry-excalidraw.vercel.app/?theme=light&amp;amp;sort=new" rel="noopener noreferrer"&gt;&lt;strong&gt;From this library&lt;/strong&gt;&lt;/a&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%2Fcyjbenq59vcgetaj1kns.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%2Fcyjbenq59vcgetaj1kns.png" alt="Library of Components for SD" width="800" height="664"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Through those components, let's build the next scheme.&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%2Fmyfciv3qyyhfz04jr4qi.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%2Fmyfciv3qyyhfz04jr4qi.png" alt="High-Level Design" width="800" height="805"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4️⃣ &lt;strong&gt;Component design&lt;/strong&gt;&lt;br&gt;
Previously, we looked at the high-level components that most systems will consist of.&lt;br&gt;
At the same time, we often hid all the logic inside the application behind one logical "square". Let's try to delve into the details of what can actually happen under the hood.&lt;br&gt;
And we can separate our scheme into two parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The first part is intended for users&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%2F985ro89dsofhiyfa127y.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%2F985ro89dsofhiyfa127y.png" alt="Component design part 1" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The second part is intended for app administrators&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%2Fsmxa4ttfjcxjn98ly7kk.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%2Fsmxa4ttfjcxjn98ly7kk.png" alt="Component design part 2" width="800" height="328"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;5️⃣ &lt;a href="https://www.geeksforgeeks.org/system-design/what-is-scalability/" rel="noopener noreferrer"&gt;Scalability and reliability&lt;/a&gt;&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%2Fl3j4tlav5fu7sjv3qxyg.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%2Fl3j4tlav5fu7sjv3qxyg.png" alt="Scalability part 1" width="800" height="516"&gt;&lt;/a&gt;&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%2Finjyv58e4c1dq1no9hea.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%2Finjyv58e4c1dq1no9hea.png" alt="Scalability part 2" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6️⃣ Finally, let's consider &lt;a href="https://www.geeksforgeeks.org/system-design/types-of-monitoring-in-system-design/" rel="noopener noreferrer"&gt;Monitoring&lt;/a&gt; and &lt;a href="https://www.geeksforgeeks.org/system-design/essential-security-measures-in-system-design/" rel="noopener noreferrer"&gt;Security&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/YuesIt17/yuit-docs-system-design/blob/main/backend/sd_backend.png" rel="noopener noreferrer"&gt;Detail you can see in this&lt;/a&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%2F5p19jii7cxtwri4svzrf.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%2F5p19jii7cxtwri4svzrf.png" alt="Monitoring" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>beginners</category>
      <category>architecture</category>
      <category>career</category>
    </item>
    <item>
      <title>[YuIT Docs📜] Create a new SSH key🔑</title>
      <dc:creator>Yues IT</dc:creator>
      <pubDate>Thu, 08 May 2025 15:49:20 +0000</pubDate>
      <link>https://dev.to/yues_it/create-a-new-ssh-key-and-first-commit-to-github-4en5</link>
      <guid>https://dev.to/yues_it/create-a-new-ssh-key-and-first-commit-to-github-4en5</guid>
      <description>&lt;h2&gt;
  
  
  Create a new SSH connection between your local machine and GitHub
&lt;/h2&gt;

&lt;p&gt;1️⃣ Open &lt;strong&gt;the Terminal of VScode&lt;/strong&gt; and generate &lt;strong&gt;a New SSH Key&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-keygen -t ed25519 -C "my-key"
- Enter file in which to save the key (C:\Users\someuser\.ssh\id_ed25519): 
- C:\Users\someuser\.ssh\id_ed25519 already exists.
- Overwrite (y/n)? y
- Enter passphrase for "C:\Users\someuser\.ssh\id_ed25519" (empty for no passphrase):
- Enter same passphrase again:
- Your identification has been saved in C:\Users\someuser\.ssh\id_ed25519
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;/blockquote&gt;

&lt;p&gt;2️⃣ Go to our directory with private and public keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ~/.ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3️⃣ Copy the SSH Public Key&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For windows&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat id_ed25519.pub | clip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;For macos&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat id_ed25519.pub | pbcopy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4️⃣ Add the SSH Key to Your GitHub Account&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log in to GitHub&lt;/li&gt;
&lt;li&gt;Go to Settings &amp;gt; SSH and GPG keys&lt;/li&gt;
&lt;li&gt;Click New SSH key&lt;/li&gt;
&lt;li&gt;Paste your key into the "Key" field&lt;/li&gt;
&lt;li&gt;Add a descriptive title&lt;/li&gt;
&lt;li&gt;Click Add SSH key&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or add the SSH Key to Your GitLab Account&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sign in to GitLab&lt;/li&gt;
&lt;li&gt;On the left sidebar, select your avatar&lt;/li&gt;
&lt;li&gt;Select Edit profile&lt;/li&gt;
&lt;li&gt;On the left sidebar, select SSH Keys&lt;/li&gt;
&lt;li&gt;Select Add new key&lt;/li&gt;
&lt;li&gt;Select Key, and you should see the 1Password helper appear&lt;/li&gt;
&lt;li&gt;Select the 1Password icon and unlock 1Password.&lt;/li&gt;
&lt;li&gt;You can then select Create SSH Key or select an existing SSH key to fill in the public key&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;5️⃣ Test the SSH Connection&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -T git@github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -T git@gitlab.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Summary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Generate SSH key (ssh-keygen)
- Add key to SSH agent (ssh-add)
- Copy public key (cat ~/.ssh/id_ed25519.pub) and add to GitHub or Gitlab
- Test connection (ssh -T git@github.com or ssh -T git@gitlab.com) 
- Use SSH URL for repositories
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Guide to add a file, commit your changes, and prepare for pushing to GitHub:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1.&lt;/strong&gt; Clone your Repositories&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd C:/MyPath/GitHub/
git clone git@github.com:username/repository.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2.&lt;/strong&gt; Add your new or modified files&lt;/p&gt;

&lt;p&gt;To stage a specific file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add filename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To stage all changed files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3.&lt;/strong&gt; Commit your changes with a descriptive message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git commit -m "Your commit message"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4.&lt;/strong&gt; Push your changes to GitHub&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ssh</category>
      <category>github</category>
      <category>gitlab</category>
    </item>
    <item>
      <title>ssh</title>
      <dc:creator>Yues IT</dc:creator>
      <pubDate>Thu, 08 May 2025 14:56:59 +0000</pubDate>
      <link>https://dev.to/yues_it/ssh-54c1</link>
      <guid>https://dev.to/yues_it/ssh-54c1</guid>
      <description></description>
      <category>cli</category>
      <category>security</category>
      <category>backend</category>
      <category>devops</category>
    </item>
    <item>
      <title>[YuIT Docs📜] GitLab🦊 Runner</title>
      <dc:creator>Yues IT</dc:creator>
      <pubDate>Mon, 10 Mar 2025 20:00:42 +0000</pubDate>
      <link>https://dev.to/yues_it/lets-run-a-gitlab-runner-in-a-docker-container-240i</link>
      <guid>https://dev.to/yues_it/lets-run-a-gitlab-runner-in-a-docker-container-240i</guid>
      <description>&lt;p&gt;Hello!👋 In this article, we can try to register a new gitlab runner in a docker container📦 via:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your project on &lt;a href="https://gitlab.com/" rel="noopener noreferrer"&gt;gitlab.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.docker.com/products/docker-desktop/" rel="noopener noreferrer"&gt;Docker desktop&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before your getting started, you can read &lt;a href="https://docs.gitlab.com/runner/install/docker/" rel="noopener noreferrer"&gt;the official documentation&lt;/a&gt; and don't read this article 😉&lt;/p&gt;

&lt;p&gt;So, if you're still here, let's do it together!💪&lt;/p&gt;

&lt;h2&gt;
  
  
  1️⃣ In you local or virtual machine, you should do those steps:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Pull the GitLab Runner Docker Image: Open your terminal and run the following command to pull the GitLab Runner Docker image: &lt;code&gt;docker pull gitlab/gitlab-runner:latest&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create new volume, it's a good practice to use &lt;a href="https://docs.docker.com/engine/storage/volumes/" rel="noopener noreferrer"&gt;a Docker volume&lt;/a&gt; to persist the config.toml file and ensure it remains available between container restarts. You can create a volume using: &lt;code&gt;docker volume create gitlab-runner-config&lt;/code&gt;, where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Names the volume: &lt;code&gt;gitlab-runner-config&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the GitLab Runner Container:&lt;br&gt;
Next, run the GitLab Runner container. You can use the following command to start it in detached mode: &lt;code&gt;docker run -d --name yuit-gitlab-runner --restart always -v gitlab-runner-config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
This command does the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runs the container in detached mode: &lt;code&gt;-d&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Names the container &lt;code&gt;yuit-gitlab-runner&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Restarts the runner automatically if it stops: &lt;code&gt;--restart always&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Maps the configuration directory via: &lt;code&gt;-v gitlab-runner-config:/etc/gitlab-runner&lt;/code&gt;: This command mounts a Docker volume named &lt;code&gt;gitlab-runner-config&lt;/code&gt; into the filesystem of the container at the specified path (/etc/gitlab-runner).&lt;/li&gt;
&lt;li&gt;Add docker socket: &lt;code&gt;-v /var/run/docker.sock:/var/run/docker.sock&lt;/code&gt;: This command mounts the host's Docker socket file (/var/run/docker.sock) at the 
same location inside the container.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Explanation of &lt;a href="https://docs.docker.com/engine/security/protect-access/" rel="noopener noreferrer"&gt;Docker Socket&lt;/a&gt;: By mounting the Docker socket, the GitLab Runner can use Docker to run builds as containers. This is necessary for scenarios where your CI/CD pipelines leverage Docker as an executor for running jobs, allowing the GitLab Runner to create and manage Docker containers during the job execution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2️⃣ Next step is &lt;a href="https://docs.gitlab.com/ci/runners/runners_scope/#create-an-instance-runner-with-a-runner-authentication-token" rel="noopener noreferrer"&gt;Register runner in gitlab&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;You have to go to your project in &lt;a href="https://gitlab.com/" rel="noopener noreferrer"&gt;gitlab.com&lt;/a&gt; and do those steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select Settings ⟶ CI/CD ⟶ Runners&lt;/li&gt;
&lt;/ul&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%2Ftbjnv9srasun7u8n26s8.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%2Ftbjnv9srasun7u8n26s8.png" alt="Settings for runners" width="800" height="539"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select New instance runner.
&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%2Fr67jgsgqlblwffa0hk4p.JPG" alt="new runner in gitlab" width="800" height="339"&gt;
&lt;/li&gt;
&lt;li&gt;In the Tags section, in the Tags field, enter the job tags to specify jobs the runner can run, for example, my tag name's is : &lt;code&gt;yuit-runner-tag&lt;/code&gt;. If there are no job tags for this runner, select &lt;strong&gt;Run untagged jobs&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&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%2Fhje3g0mxun2rsh10ltsi.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%2Fhje3g0mxun2rsh10ltsi.png" alt="Tags section" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runner description: &lt;code&gt;Runner of docker container&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select the operating system where GitLab Runner is installed: &lt;code&gt;linux&lt;/code&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%2F8ihgyowbphvjk4q6i2f3.JPG" alt="new runner in gitlab token" width="800" height="735"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3️⃣ Move on and you should &lt;a href="https://docs.gitlab.com/runner/register/?tab=Docker" rel="noopener noreferrer"&gt;register runner&lt;/a&gt; in local docker container
&lt;/h2&gt;

&lt;p&gt;On your local machine to open terminal and run following command: &lt;br&gt;
&lt;code&gt;docker exec -it yuit-gitlab-runner gitlab-runner register&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;In terminal, you need to enter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the GitLab instance URL: &lt;code&gt;https://gitlab.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;the registration token: &lt;code&gt;****&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;the name for the runner: &lt;code&gt;yuit-runner&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;the executor: &lt;code&gt;docker&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;the default Docker image: &lt;code&gt;node:20.16-alpine&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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%2F3w0wl5icpy3re96nb9ek.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%2F3w0wl5icpy3re96nb9ek.png" alt="docker container" width="800" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4️⃣ Go to &lt;a href="https://gitlab.com/" rel="noopener noreferrer"&gt;gitlab.com&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In there we can see that our runner is registered&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%2Febrou0wqm1v2d61usqmh.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%2Febrou0wqm1v2d61usqmh.png" alt="registered a new runner" width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After clicking &lt;strong&gt;View runners&lt;/strong&gt;, we can see that our runner is available&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%2Fdw03zshp3zdegj3qi2bk.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%2Fdw03zshp3zdegj3qi2bk.png" alt="See the new runner" width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gitlab</category>
      <category>runner</category>
      <category>docker</category>
      <category>documentation</category>
    </item>
    <item>
      <title>[YuIT Docs📜] 🐳Docker compose for a Full Stack App</title>
      <dc:creator>Yues IT</dc:creator>
      <pubDate>Sun, 19 Jan 2025 16:13:12 +0000</pubDate>
      <link>https://dev.to/yues_it/docker-compose-is-very-simple-1oe3</link>
      <guid>https://dev.to/yues_it/docker-compose-is-very-simple-1oe3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction to Docker Compose
&lt;/h2&gt;

&lt;p&gt;🐳Docker Compose is a powerful tool for defining and running multi-container Docker applications. &lt;br&gt;
📑In this article, we will delve into the world of Docker Compose using a real-world example of a web application that consists of a PostgreSQL database, a backend service, and a frontend service.&lt;br&gt;
👉In the previous article I have seen &lt;a href="https://dev.to/yuit_solutions/dockerization-or-how-to-deploy-app-nextjs-nestjs-postgresql-using-docker-and-nginx-42jm"&gt;&lt;strong&gt;how use only docker for this&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What is Docker Compose?
&lt;/h2&gt;

&lt;p&gt;You just can read &lt;a href="https://docs.docker.com/compose/" rel="noopener noreferrer"&gt;the official documentation&lt;/a&gt;😁&lt;br&gt;
Or read a short description: &lt;strong&gt;Docker Compose&lt;/strong&gt; is a command-line tool that allows you to define and run multi-container Docker applications. It uses a YAML file, known as &lt;strong&gt;the docker-compose.yml&lt;/strong&gt; file, to define the services that make up your application. Docker Compose handles the creation and management of the containers, networks, and volumes required by your application.&lt;/p&gt;

&lt;p&gt;Our example application consists of three services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;Database - PostgreSQL&lt;/a&gt;&lt;/strong&gt;: This service is responsible for storing data for our application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://nestjs.com/" rel="noopener noreferrer"&gt;Backend - Nest.js&lt;/a&gt;&lt;/strong&gt;: This service handles the business logic of our application and interacts with the database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Frontend - Next.js&lt;/a&gt;&lt;/strong&gt;: This service provides a user interface for our application and interacts with the backend service.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Docker Compose Configuration
&lt;/h3&gt;

&lt;p&gt;❗Before we start, we need:&lt;/p&gt;

&lt;p&gt;1️⃣ To clone examples repositories for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BE: &lt;code&gt;git clone https://github.com/YuesIt17/yuit-docs-nestjs-docker.git&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;FE: &lt;code&gt;git clone https://github.com/YuesIt17/yuit-docs-nextjs-docker.git&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Docker Compose: &lt;code&gt;git clone https://github.com/YuesIt17/yuit-docs-docker-config.git&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2️⃣ To start the docker db container and create docker images for FE and BE. I describe this in my README:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/YuesIt17/yuit-docs-nestjs-docker/blob/main/README.md#settings-of-docker-for-db" rel="noopener noreferrer"&gt;Database&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/YuesIt17/yuit-docs-nestjs-docker/blob/main/README.md#settings-of-docker-image-for-backend" rel="noopener noreferrer"&gt;Backend&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/YuesIt17/yuit-docs-nextjs-docker/blob/main/README.md#settings-of-docker-image-for-frontend" rel="noopener noreferrer"&gt;Frontend&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3️⃣ To run the containers via: &lt;code&gt;docker-compose up -d&lt;/code&gt;. If you wanna stop and remove the containers via:&lt;code&gt;docker-compose down&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;4️⃣ You can then access the application by visiting &lt;code&gt;http://localhost:3000&lt;/code&gt; in your web browser&lt;/p&gt;

&lt;p&gt;👀Here is the &lt;strong&gt;docker-compose.yml&lt;/strong&gt; file that defines our example application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: "3.8"

services:
  db:
    image: postgres
    container_name: yuit-chart-db-host
    environment:
      POSTGRES_DB: yuit-chart-db
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: adminyuitpassword
    networks:
      - yuit-net
    ports:
      - "5432:5432"
    restart: unless-stopped

  backend:
    image: yuit-chart-backend-image:latest
    container_name: yuit-chart-backend
    networks:
      - yuit-net
    ports:
      - "127.0.0.1:8080:8080"
    depends_on:
      - db
    restart: unless-stopped

  frontend:
    image: yuit-chart-frontend-image:latest
    container_name: yuit-chart-frontend
    networks:
      - yuit-net
    ports:
      - "127.0.0.1:3000:8080"
    restart: unless-stopped

networks:
  yuit-net:
    driver: bridge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💪Let's break down this configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;version&lt;/strong&gt; directive specifies the version of the Docker Compose format.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;services&lt;/strong&gt; directive defines the services that make up our application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;db&lt;/strong&gt; service uses the official PostgreSQL image and sets environment variables for the database name, user, and password.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;backend&lt;/strong&gt; service uses a custom image (yuit-chart-backend-image:latest) and depends on the db service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;frontend&lt;/strong&gt; service uses a custom image (yuit-chart-frontend-image:latest) and does not depend on any other services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;networks&lt;/strong&gt; directive defines a network named yuit-net with a bridge driver.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Concepts
&lt;/h2&gt;

&lt;p&gt;Here are some key concepts to understand when working with Docker Compose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Services: A service is a container that runs a specific image. In our example, we have three services: db, backend, and frontend.&lt;/li&gt;
&lt;li&gt;Images: An image is a template for creating containers. In our example, we use the official PostgreSQL image and two custom images.&lt;/li&gt;
&lt;li&gt;Networks: A network is a way for services to communicate with each other. In our example, we define a network named yuit-net with a bridge driver.&lt;/li&gt;
&lt;li&gt;Environment Variables: Environment variables are used to configure services. In our example, we set environment variables for the database name, user, and password.&lt;/li&gt;
&lt;li&gt;Depends On: The depends_on directive specifies that a service depends on another service. In our example, the backend service depends on the db service.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In this article, we introduced Docker Compose. We defined a &lt;code&gt;docker-compose.yml&lt;/code&gt; file that specified three services: a PostgreSQL database, a backend service, and a frontend service. We then ran the application using the docker-compose up command. Docker Compose provides a powerful way to define and run multi-container Docker applications, making it an essential tool for developers and DevOps teams.&lt;/p&gt;

&lt;p&gt;Thanks for reading and feedback! &lt;br&gt;
See you soon!🤝&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>webdev</category>
      <category>documentation</category>
    </item>
    <item>
      <title>[YuIT Docs📜] Docker container for a Full Stack App📦</title>
      <dc:creator>Yues IT</dc:creator>
      <pubDate>Wed, 01 Jan 2025 12:36:48 +0000</pubDate>
      <link>https://dev.to/yues_it/dockerization-or-how-to-deploy-app-nextjs-nestjs-postgresql-using-docker-and-nginx-42jm</link>
      <guid>https://dev.to/yues_it/dockerization-or-how-to-deploy-app-nextjs-nestjs-postgresql-using-docker-and-nginx-42jm</guid>
      <description>&lt;p&gt;A Docker container📦 image is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries and settings.&lt;/p&gt;

&lt;p&gt;📃In this article we will figure it out, how to deploy your own app using &lt;strong&gt;🐳Docker and 🌐Nginx&lt;/strong&gt;, for our app we will use the following technologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;⚛️ For frontend (&lt;a href="https://github.com/YuesIt17/yuit-docs-nextjs-docker" rel="noopener noreferrer"&gt;my repository&lt;/a&gt;): &lt;strong&gt;&lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;&lt;/strong&gt; is a popular open-source React framework that enables developers to build server-rendered and static web applications with ease. It offers features like automatic code splitting, server-side rendering (SSR), static site generation (SSG), and API routes, which enhance performance and SEO. Next.js simplifies the development process by providing a file-based routing system and built-in support for CSS and TypeScript, making it a powerful choice for creating modern web applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🔚 For backend (&lt;a href="https://github.com/YuesIt17/yuit-docs-nestjs-docker" rel="noopener noreferrer"&gt;my repository&lt;/a&gt;): &lt;strong&gt;&lt;a href="https://nestjs.com/" rel="noopener noreferrer"&gt;Nest.js&lt;/a&gt;&lt;/strong&gt; is a progressive Node.js framework for building efficient, scalable server-side applications. It leverages TypeScript and incorporates modern design patterns, such as modular architecture and dependency injection, to promote maintainability and testability. With built-in support for GraphQL, WebSockets, and microservices, Nest.js is ideal for developing robust APIs and enterprise-level applications. Its extensible architecture allows integration with various libraries and tools, making it a versatile choice for backend development.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🗄️ For database: PostgreSQL is a powerful, open-source relational database management system (RDBMS) known for its robustness, extensibility, and compliance with SQL standards. It supports advanced data types, complex queries, and transactions, making it suitable for a wide range of applications. With features like ACID compliance, full-text search, and support for JSON and GIS data, PostgreSQL is favored for its performance, reliability, and ability to handle large volumes of data. Its active community and rich ecosystem of extensions further enhance its capabilities, making it a popular choice for developers and organizations.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes developers confuse Nest and Next😀 &lt;br&gt;
Ok, let's move on and do it!💪&lt;/p&gt;
&lt;h2&gt;
  
  
  📑Create docker network
&lt;/h2&gt;

&lt;p&gt;The fist of all to create a common network for feauture containers&lt;br&gt;
First of all, it is necessary to create and check a common network for future docker containers via command:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;docker network create -d bridge yuit-net&lt;/code&gt;, where are the following parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;yuit-net&lt;/strong&gt; - the name of our network&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;bridge&lt;/strong&gt; - the default network driver&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-d or --driver&lt;/strong&gt; - this flag allows you to specify which network driver docker should use to create the network

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;docker network ls&lt;/strong&gt; - for check network&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;And in our terminal we can see all networks (including ours)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PS ...\yuit-docs-nestjs-docker&amp;gt; docker network create -d bridge yuit-net
6019f719ee8bcd39cf0406a795f5a61a531756ce29c9a53974868d7797ed19e7
PS ...\yuit-docs-nestjs-docker&amp;gt; docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
33c0431165ec   bridge     bridge    local
295269f446db   host       host      local
801fdcaabbb4   none       null      local
6019f719ee8b  yuit-net   bridge    local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📑Create docker container for database
&lt;/h2&gt;

&lt;p&gt;Next step we need to create container for our database PostgreSQL via:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;docker run --network=yuit-net --name yuit-chart-db-host --rm -d -p 5432:5432 -i -t -e POSTGRES_DB=yuit-chart-db -e POSTGRES_USER=admin -e POSTGRES_PASSWORD=adminyuitpassword postgres&lt;/code&gt;, where are the following parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;--network=yuit-net&lt;/strong&gt; - it's our docker network&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--name yuit-chart-db-host&lt;/strong&gt; - it's a custom name to the container for data source option in our backend project (we will consider this below)
&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%2Fqjb4t81189pbfwi4v0bj.png" alt="Data source option" width="800" height="495"&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%2Fxuba8loy180ewx90a67y.png" alt="Dockerfile of backend" width="800" height="243"&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--rm&lt;/strong&gt; - this option tells docker to automatically remove the container when it stops&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-d&lt;/strong&gt; - this flag runs the container in detached mode&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-p 5432:5432&lt;/strong&gt; - this option maps port 5432(first) of the host machine to port 5432(second) of the container&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-i&lt;/strong&gt; - this flag stands for "interactive" mode. It keeps the standard input (stdin) open even if not attached, allowing you to interact with the container if needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-t&lt;/strong&gt; - this flag allocates a pseudo-TTY (terminal) for the container, which is useful for running interactive applications. It is often used in conjunction with -i.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-e POSTGRES_DB=yuit-chart-db&lt;/strong&gt; - this option sets an environment variable inside the container. Here, it creates a PostgreSQL database named yuit-chart-db&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-e POSTGRES_USER=admin&lt;/strong&gt; - this environment variable sets the username for the PostgreSQL database&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-e POSTGRES_PASSWORD=adminyuitpassword&lt;/strong&gt; - this environment variable sets the password for the PostgreSQL user specified in the previous parameter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;postgres&lt;/strong&gt; - it's the &lt;a href="https://hub.docker.com/_/postgres" rel="noopener noreferrer"&gt;official PostgreSQL image&lt;/a&gt; from Docker Hub&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;And via command &lt;strong&gt;docker ps -a&lt;/strong&gt; to check the DB container&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PS ...\yuit-docs-nestjs-docker&amp;gt; docker run --network=yuit-net --name yuit-chart-db-host --rm -d -p 5432:5432 -i -t -e POSTGRES_DB=yuit-chart-db -e POSTGRES_USER=admin -e POSTGRES_PASSWORD=adminyuitpassword postgres
PS ...\yuit-docs-yues-nestjs-docker&amp;gt;  docker ps -a
CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS         PORTS                    NAMES
2ef9f2d7daa6   postgres   "docker-entrypoint.s…"   5 seconds ago   Up 5 seconds   0.0.0.0:5432-&amp;gt;5432/tcp   yuit-chart-db-host
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;❔ We may also connect to our DB, for example, via Database Tool: &lt;a href="https://dbeaver.io/" rel="noopener noreferrer"&gt;DBeaver&lt;/a&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%2F6pvtzupn9dh6qijb9iuh.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%2F6pvtzupn9dh6qijb9iuh.png" alt="Connect to DB" width="800" height="406"&gt;&lt;/a&gt;&lt;br&gt;
And we see our DB with the name &lt;strong&gt;yuit-chart-db&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%2F20er596cmsulhqrj6txe.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%2F20er596cmsulhqrj6txe.png" alt="Check DB" width="622" height="265"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  📑Create docker image and container for backend
&lt;/h2&gt;

&lt;p&gt;After we have created our DB, we can create a docker image of backend.&lt;br&gt;
For that:&lt;/p&gt;
&lt;h3&gt;
  
  
  1️⃣We need to create our &lt;a href="https://docs.docker.com/reference/dockerfile/" rel="noopener noreferrer"&gt;Dockerfile&lt;/a&gt;, it's needed for describe our image, &lt;a href="https://github.com/YuesIt17/yuit-docs-nestjs-docker/blob/main/infra/docker/Dockerfile" rel="noopener noreferrer"&gt;for example&lt;/a&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; # build app
 FROM node:20.16-alpine AS build
 WORKDIR /app
 COPY . /app

 ENV DATABASE_HOST=yuit-chart-db-host

 RUN yarn install
 RUN echo "Build is ok! Go to next layer!"
 RUN yarn build

 EXPOSE 8080

 # start migration and api
 CMD npm run migration:prod &amp;amp;&amp;amp; npm run start:prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  2️⃣After that we can build image of backend, via command:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;docker build . -t yuit-chart-backend-image -f infra/docker/Dockerfile&lt;/code&gt;, where are the following parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;the dot (.)&lt;/strong&gt; - indicates that the current directory should be used as the context for the build&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-t yuit-chart-backend-image&lt;/strong&gt; - it's name of your image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-f infra/docker/Dockerfile&lt;/strong&gt; - it's directory of our Dockerhfile&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  3️⃣The next step is run container:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;docker run --network=yuit-net --name yuit-chart-backend -d -p 127.0.0.1:8080:8080/tcp yuit-chart-backend-image&lt;/code&gt;, where are the following parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;--network=yuit-net&lt;/strong&gt; - it's our docker network&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--name yuit-chart-backend&lt;/strong&gt; - this flag assigns a name to the container, i.e. &lt;code&gt;yuit-chart-backend&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-d&lt;/strong&gt; - this stands for detached mode&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-p 127.0.0.1:8080:8080/tcp&lt;/strong&gt; - this option is used to publish a container's port to the host, where:

&lt;ul&gt;
&lt;li&gt;8080:8080 indicates that port 8080 on the host will be mapped to port 8080 on the container.&lt;/li&gt;
&lt;li&gt;/tcp specifies the protocol to use (in this case, TCP). This part is optional, as TCP is the default protocol&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;yuit-chart-backend-image&lt;/strong&gt; - it's the name of the Docker image&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;❔ We can check our contaner via command &lt;code&gt;docker ps -a&lt;/code&gt; or to see containers in &lt;a href="https://www.docker.com/products/docker-desktop/" rel="noopener noreferrer"&gt;the docker desktop&lt;/a&gt;&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%2Fty3kbgdhoapz71z0iep3.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%2Fty3kbgdhoapz71z0iep3.png" alt="the docker desktop" width="800" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We may also select our data from the DB, because we have run migrations in the Dockerfile. To do this, just run the select command in the DBeaver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT id, data
FROM public.chart;

SELECT *
FROM public.__migrations;
&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%2F2j39pn9d0ufw8pcxt6zq.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%2F2j39pn9d0ufw8pcxt6zq.png" alt="Select data" width="800" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4️⃣After running the backend container, we can test the api through url: &lt;strong&gt;&lt;a href="http://localhost:8080/data_chart" rel="noopener noreferrer"&gt;http://localhost:8080/data_chart&lt;/a&gt;&lt;/strong&gt;
&lt;/h3&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%2Faeppzvxun1r6inm0ftpd.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%2Faeppzvxun1r6inm0ftpd.png" alt="api" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📑 Create docker image and container for frontend
&lt;/h2&gt;

&lt;p&gt;Finally, we need to create an image and run a container for the frontend.&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Let's add settings for the web server - &lt;a href="https://nginx.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;nginx&lt;/strong&gt;&lt;/a&gt;, &lt;a href="https://github.com/YuesIt17/yuit-docs-nextjs-docker/blob/main/infra/docker/conf.d" rel="noopener noreferrer"&gt;for example&lt;/a&gt;:
&lt;/h3&gt;

&lt;p&gt;Add these settings to the file &lt;strong&gt;conf.d&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http {
  server {
    listen  8080;
    server_name localhost;

    location / {
        root /usr/share/nginx/html;
        index index.html;
        try_files $uri /index.html;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
  }
}

events {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2️⃣We need to create our Dockerfile, &lt;a href="https://github.com/YuesIt17/yuit-docs-nextjs-docker/blob/main/infra/docker/Dockerfile" rel="noopener noreferrer"&gt;for example&lt;/a&gt;:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# build app
FROM node:20.16-alpine as build
WORKDIR /app
COPY . /app
RUN yarn
RUN echo "Build is ok! Go to next layer!"
RUN yarn deploy

# build server
FROM nginx:alpine as normal
# copy the build folder from react to the root of nginx
COPY --from=build /app/build /usr/share/nginx/html
COPY infra/docker/conf.d /etc/nginx/nginx.conf
RUN echo "Nginx is ok!"
# expose port 3000 to the outer world
EXPOSE 3000
# start nginx
CMD ["nginx", "-g", "daemon off;"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3️⃣After that we can build image, via command:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;docker build -t yuit-chart-frontend-image --target normal -f infra/docker/Dockerfile .&lt;/code&gt;, where are the following parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;-t yuit-chart-backend-image&lt;/strong&gt; - it's image name&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-f infra/docker/Dockerfile&lt;/strong&gt; - it's directory of our Dockerhfile&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--target normal&lt;/strong&gt; - it's needed for build only a part of the Dockerfile, which can be useful for optimizing the build process and reducing image size&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;the dot (.)&lt;/strong&gt; - indicates that the current directory should be used as the context for the build&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  4️⃣The next step is run container:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;docker run --network=yuit-net --name yuit-chart-frontend --rm -itd -p 127.0.0.1:3000:8080/tcp yuit-chart-frontend-image&lt;/code&gt;, where are the following parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;--network=yuit-net&lt;/strong&gt; - it's our docker network&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--name yuit-chart-frontend&lt;/strong&gt; - this flag assigns a name to the container&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--rm&lt;/strong&gt; - this option tells Docker to automatically remove the container when it exits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-itd&lt;/strong&gt; - this stands for &lt;code&gt;i&lt;/code&gt; - interactive mode, &lt;code&gt;t&lt;/code&gt; - allocates a pseudo-TTY and &lt;code&gt;d&lt;/code&gt; - detached mode&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-p 127.0.0.1:3000:8080/tcp&lt;/strong&gt; - this option is used to publish a container's port to the host, where:

&lt;ul&gt;
&lt;li&gt;3000:8080 indicates that port 3000 on the host will be mapped to port 8080 on the container&lt;/li&gt;
&lt;li&gt;/tcp specifies the protocol to use (in this case, TCP). This part is optional, as TCP is the default protocol&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;yuit-chart-frontend-image&lt;/strong&gt; - it's the name of the Docker image&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  5️⃣After running the frontend container, we can test the api through &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000/&lt;/a&gt;
&lt;/h3&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%2Fk0tfhj37ujfi06ez6td1.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%2Fk0tfhj37ujfi06ez6td1.png" alt="web app" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/YuesIt17/yuit-docs-nestjs-docker" rel="noopener noreferrer"&gt;Backend - nest.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/YuesIt17/yuit-docs-nextjs-docker" rel="noopener noreferrer"&gt;Frontend - next.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and feedback!🤝&lt;/p&gt;

</description>
      <category>docker</category>
      <category>nginx</category>
      <category>devops</category>
      <category>documentation</category>
    </item>
    <item>
      <title>[YuIT Docs📜] Create a new UI platform using an NPM package📦</title>
      <dc:creator>Yues IT</dc:creator>
      <pubDate>Wed, 13 Nov 2024 16:35:28 +0000</pubDate>
      <link>https://dev.to/yues_it/how-to-create-an-npm-packages-using-rollupjs-lernajs-jfrog-artifactory-2g80</link>
      <guid>https://dev.to/yues_it/how-to-create-an-npm-packages-using-rollupjs-lernajs-jfrog-artifactory-2g80</guid>
      <description>&lt;p&gt;📃In this article we will figure it out, how to &lt;strong&gt;create your own npm package&lt;/strong&gt; using the following technologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;🏗️&lt;a href="https://rollupjs.org/" rel="noopener noreferrer"&gt;Rollup.js&lt;/a&gt; is a JavaScript module bundler that compiles small pieces of code into larger, more complex applications. It is particularly well-suited for bundling ES6 modules and is known for its efficient tree-shaking capabilities, which eliminate unused code from the final bundle, resulting in smaller file sizes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;📦&lt;a href="https://lerna.js.org/" rel="noopener noreferrer"&gt;Lerna.js&lt;/a&gt; is a popular tool for managing JavaScript projects with multiple packages, often referred to as monorepos. It simplifies the process of versioning, publishing, and managing dependencies across various packages within a single repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🐸&lt;a href="https://jfrog.com/artifactory/" rel="noopener noreferrer"&gt;JFrog Artifactory&lt;/a&gt; is a universal artifact repository manager that enables organizations to store, manage, and distribute software packages and artifacts across the entire development lifecycle. It supports a wide range of package formats, including Docker, Maven, npm, PyPI, and more, making it a versatile solution for DevOps and CI/CD pipelines.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  JFrog Artifactory Settings
&lt;/h2&gt;

&lt;p&gt;If you don't have artifactory, you can use &lt;a href="https://jfrog.com/community/open-source/" rel="noopener noreferrer"&gt;the free trial or the free open source version&lt;/a&gt;. &lt;strong&gt;But the free open source&lt;/strong&gt; is a cut down version that doesn't have any pre-built settings for the npm repository. Let's do it step by step!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Let's create &lt;strong&gt;a new virtual npm repository&lt;/strong&gt;. It's necessary to install our npm package from external access (public repository). &lt;br&gt;
&lt;strong&gt;The JFrog virtual npm repository&lt;/strong&gt; is a consolidated view of multiple npm repositories, allowing users to access and manage npm packages from various sources in a single location. It acts as a proxy for local and remote npm repositories, enabling seamless integration of public and private packages. This setup simplifies dependency management, enhances performance through caching, and provides a unified interface for package retrieval. Additionally, virtual repositories support security and access control, ensuring that only authorized users can access specific packages.&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%2Fnng6vnc8chivk26x09x9.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%2Fnng6vnc8chivk26x09x9.png" alt="Click to create virtual repo" width="800" height="398"&gt;&lt;/a&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%2F7ap6nypwdoadewkrvzox.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%2F7ap6nypwdoadewkrvzox.png" alt="Choose npm" width="800" height="408"&gt;&lt;/a&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%2F7hf8ufekpblz1o5bxx57.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%2F7hf8ufekpblz1o5bxx57.png" alt="Input settings" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add &lt;strong&gt;a new local repository&lt;/strong&gt;. It's necessary to publish our npm package to private repository.&lt;br&gt;
&lt;strong&gt;The JFrog local npm repository&lt;/strong&gt; is a dedicated storage space within JFrog Artifactory for hosting and managing your organization's private npm packages. It allows teams to publish, version, and manage their own npm packages securely and efficiently. By using a local repository, developers can ensure that their packages are readily available, control access permissions, and maintain a consistent versioning system. Local npm repositories also facilitate faster builds and deployments by providing quick access to internal packages, ultimately enhancing the overall development workflow.&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%2Ffonbu9d8wn30wbjuancs.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%2Ffonbu9d8wn30wbjuancs.png" alt="Click to create local repo" width="800" height="451"&gt;&lt;/a&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%2Fd3wh7so87z2x1pj0q5ot.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%2Fd3wh7so87z2x1pj0q5ot.png" alt="Input settings" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add &lt;strong&gt;a new remote repository&lt;/strong&gt;. It's necessary for to save cache  from external registry: &lt;a href="https://registry.npmjs.org" rel="noopener noreferrer"&gt;https://registry.npmjs.org&lt;/a&gt; or &lt;a href="https://registry.yarnpkg.com/" rel="noopener noreferrer"&gt;https://registry.yarnpkg.com/&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;The JFrog remote repository&lt;/strong&gt; is a type of repository in JFrog Artifactory that acts as a proxy for a remote artifact repository, such as npm registry or Docker Hub. It allows users to access and cache artifacts from these external sources without directly interacting with them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Caching: Artifacts are cached locally upon first access, improving performance for subsequent requests.
Access Control: Provides security and access management for remote artifacts.&lt;/li&gt;
&lt;li&gt;Aggregation: Can aggregate multiple remote repositories into a single endpoint, simplifying dependency management.&lt;/li&gt;
&lt;li&gt;Metadata Management: Supports metadata for better organization and search capabilities.
&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%2F8aclmdssn3ilgl6j4o22.png" alt="Click to create remote repo" width="800" height="418"&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%2Fo2s7ryalrxhq6b5lzugy.png" alt="Input name" width="800" height="436"&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%2F29ev7ycj118pij8pftbi.png" alt="Input registry url" width="800" height="433"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Let's move on to editing the virtual repository to combine with local and remote ones.&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%2Fcn5qfpsknjo8gg09vqb7.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%2Fcn5qfpsknjo8gg09vqb7.png" alt="Edit virtual repo" width="800" height="320"&gt;&lt;/a&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%2Fvz900ddds1sg74e0t295.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%2Fvz900ddds1sg74e0t295.png" alt="Select repo" width="800" height="412"&gt;&lt;/a&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%2Fbh7ta7ze7jmutgi5pxae.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%2Fbh7ta7ze7jmutgi5pxae.png" alt="Set default repo" width="800" height="479"&gt;&lt;/a&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%2F082jr1a41t7nb4pvzzhe.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%2F082jr1a41t7nb4pvzzhe.png" alt="Remote repo for cache" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  NPM Packages using Rollup.js + Lerna.js
&lt;/h2&gt;

&lt;p&gt;For &lt;strong&gt;our NPM packages&lt;/strong&gt; example we use &lt;strong&gt;Rollup.js + Lerna.js&lt;/strong&gt; (&lt;a href="https://github.com/YuesIt17/yuit-docs-npm-lerna-rollup" rel="noopener noreferrer"&gt;&lt;strong&gt;link to my example npm library&lt;/strong&gt;&lt;/a&gt;). As for the usage of these libraries, we can look at the official documentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://rollupjs.org/tutorial/#installing-rollup-locally" rel="noopener noreferrer"&gt;Rollup.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lerna.js.org/docs/getting-started" rel="noopener noreferrer"&gt;Lerna.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;❗But I'd like to show you &lt;strong&gt;the details of the settings&lt;/strong&gt; ⚙.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rollup settings
&lt;/h3&gt;

&lt;p&gt;After &lt;a href="https://rollupjs.org/tutorial/#installing-rollup-locally" rel="noopener noreferrer"&gt;install Rollup.js&lt;/a&gt;, i have set up &lt;strong&gt;the basic rollup configuration&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {defineConfig} from 'rollup';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
import {terser} from 'rollup-plugin-terser';
import url from '@rollup/plugin-url';

import * as fs from 'fs';
import path from 'path';

const PACKAGE_NAME = process.cwd();
const packageJson = JSON.parse(fs.readFileSync(path.join(PACKAGE_NAME, 'package.json'), 'utf-8'));

const includePaths = ['**/*.woff', '**/*.woff2', '**/*.svg', '**/*.png'];

export default defineConfig({
  input: 'src/index.ts',
  output: [
    {
      file: packageJson.main,
      format: 'cjs',
      sourcemap: false,
      name: packageJson.name,
    },
    {
      file: packageJson.module,
      format: 'es',
      sourcemap: false,
      name: packageJson.name,
    },
  ],
  plugins: [
    resolve(),
    commonjs(),
    typescript({tsconfig: './tsconfig.json'}),
    terser(),
    url({
      fileName: '[name][extname]',
      include: includePaths,
      limit: 0,
    }),
  ],
  external: [...Object.keys(packageJson.peerDependencies || {})],
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From this configuration we see the following settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;packageJson&lt;/strong&gt; is needed to get settings from the package.json file (for which the build is in progress)&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;includePaths&lt;/strong&gt; is needed to support the paths to our images, fonts and ect. We can also save the file name via props &lt;strong&gt;fileName&lt;/strong&gt;, otherwise the file will be an auto-generated name.&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%2F72i4642f7gu73w1sryli.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%2F72i4642f7gu73w1sryli.png" alt="Auto-generated name" width="800" height="269"&gt;&lt;/a&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%2Fx7kttxp5q38n0w5gp6yu.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%2Fx7kttxp5q38n0w5gp6yu.png" alt="Save file name" width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;external&lt;/strong&gt; option is used to specify which modules should be treated as external dependencies. ❗When you mark a module as &lt;strong&gt;external&lt;/strong&gt;, Rollup will &lt;strong&gt;not include it in the output bundle&lt;/strong&gt;. Instead, it will assume that the module will be available in the environment &lt;strong&gt;where the bundle is executed&lt;/strong&gt; (e.g., in your project where you will install this npm package). In here we includes peerDependencies from our packages.&lt;br&gt;
Define &lt;strong&gt;peerDependencies in package.json&lt;/strong&gt;, you can specify the libraries that are expected to be installed by the &lt;strong&gt;consumer of your package&lt;/strong&gt;. &lt;br&gt;
For example, we added &lt;strong&gt;peer dependencies&lt;/strong&gt; in &lt;a href="https://github.com/YuesIt17/yuit-docs-npm-lerna-rollup/blob/main/packages/ui/package.json" rel="noopener noreferrer"&gt;the package ui&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  "peerDependencies": {
    "react": "^18.x",
    "react-dom": "^18.x"
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These &lt;strong&gt;peer dependencies ensures&lt;/strong&gt; the package ui can be installed with &lt;strong&gt;the 18.x major version of the package react and react-dom only&lt;/strong&gt; and these React libraries &lt;strong&gt;must be installed from your project&lt;/strong&gt; (e.g. i installed them in my client project &lt;a href="https://github.com/YuesIt17/yuit-docs-vite/blob/main/package.json" rel="noopener noreferrer"&gt;yuit-docs-vite&lt;/a&gt;)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⁉In other words when using &lt;strong&gt;peerDependencies with the external option&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;external&lt;/strong&gt; ensures when you run the Rollup build command, it will create a bundle that &lt;strong&gt;does not include react and react-dom&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;peerDependencies&lt;/strong&gt; ensures that these dependencies &lt;strong&gt;will be provided by the consumer of your library (i.e. in my case it's &lt;a href="https://github.com/YuesIt17/yuit-docs-vite" rel="noopener noreferrer"&gt;yuit-docs-vite&lt;/a&gt;&lt;/strong&gt;) and  limits react and react-dom versions to &lt;strong&gt;only major version 18.x&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also you can see other &lt;a href="https://github.com/rollup/plugins/" rel="noopener noreferrer"&gt;&lt;strong&gt;official rollup plugins&lt;/strong&gt; here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lerna settings
&lt;/h3&gt;

&lt;p&gt;After &lt;a href="https://lerna.js.org/docs/getting-started" rel="noopener noreferrer"&gt;init Lerna.js&lt;/a&gt; we can see lerna.json:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "$schema": "node_modules/lerna/schemas/lerna-schema.json",
  "version": "independent",
  "packages": ["packages/*"],
  "npmClient": "yarn"
  "command": {
     "publish": {
       "registry": "https://some-art.com/artifactory/api/npm/portfolio-yues-it-npm/"
    }
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I added &lt;code&gt;npmClient&lt;/code&gt;and &lt;code&gt;command&lt;/code&gt; for testing &lt;strong&gt;lerna publish&lt;/strong&gt; via &lt;strong&gt;yarn&lt;/strong&gt;, but it didn't work for me and i published via &lt;code&gt;yarn workspaces foreach no-private&lt;/code&gt; (&lt;strong&gt;we will it below&lt;/strong&gt; ⬇).&lt;br&gt;
An example of a project structure looks like this (❗&lt;strong&gt;Please note&lt;/strong&gt; that in the settings you need to specify the prefix of the name of our root project):&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%2Fjscqu97vv4n5s3pko2ml.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%2Fjscqu97vv4n5s3pko2ml.png" alt="Project structure" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;❗Before to run &lt;code&gt;npx lerna commands&lt;/code&gt; you need to set up &lt;a href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account" rel="noopener noreferrer"&gt;ssh access&lt;/a&gt; to git via terminal (this is necessary for local publishing from a git repository) and test the connection for github: ssh -T &lt;a href="mailto:git@github.com"&gt;git@github.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To publish to git, you need to add settings to &lt;code&gt;.yarnrc.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enableStrictSsl: false

httpTimeout: 12000000

nodeLinker: node-modules

npmAlwaysAuth: false

npmPublishRegistry: 'https://some-art.com/artifactory/api/npm/portfolio-yues-it-npm/'

npmRegistryServer: 'https://some-art.com/artifactory/api/npm/portfolio-yues-it-npm/'

npmAuthToken: 'some token from a virtual repository jfrog (Repositories -&amp;gt; Virtual -&amp;gt; Set me up -&amp;gt; Configure -&amp;gt; Generate token)'

yarnPath: .yarn/releases/yarn-berry.cjs

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;❗&lt;strong&gt;Please note&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;this url of virtual repository - '&lt;a href="https://some-art.com/artifactory/api/npm/portfolio-yues-it-npm/" rel="noopener noreferrer"&gt;https://some-art.com/artifactory/api/npm/portfolio-yues-it-npm/&lt;/a&gt;' we take from artifactory
&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%2F81y5kiyi5rqacx83d9oj.png" alt="Set up repo-click button" width="800" height="374"&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%2F7g194uraaw7snbwuyuqv.png" alt="Configure and generate token" width="800" height="447"&gt;
&lt;/li&gt;
&lt;li&gt;in addition, if you have &lt;strong&gt;a problem with public to JFROG Artifactory&lt;/strong&gt; (when the yarn uses &lt;strong&gt;the Glogal settings&lt;/strong&gt;), because the yarn doesn't use the local project settings from file &lt;code&gt;.yarnrc.yml&lt;/code&gt; -&amp;gt; 
❗you can see &lt;a href="https://nodejs.org/api/corepack.html#corepack" rel="noopener noreferrer"&gt;&lt;strong&gt;corepack&lt;/strong&gt;&lt;/a&gt; for isolation yarn configs for different projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Once lerna and git are configured we can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;install a npm package for a specific lerna package via: &lt;code&gt;yarn workspace @portfolio-yues-it-npm/utils add date-fns&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;version in git and publish to artifactory via:

&lt;ul&gt;
&lt;li&gt;run build via: &lt;code&gt;npx lerna run build&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;then: &lt;code&gt;yarn install&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;make &lt;strong&gt;commit changes&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;run versioning via: &lt;code&gt;npx lerna version --no-private&lt;/code&gt; (📝--no-private is needed to publish packages other than privates
ones)&lt;/li&gt;
&lt;li&gt;select the necessary version: &lt;strong&gt;Patch / Minor / Major&lt;/strong&gt; (after that will be push to your git repository)&lt;/li&gt;
&lt;li&gt;make publish to artifactory via yarn: &lt;code&gt;yarn workspaces foreach --all --no-private npm publish&lt;/code&gt; (⁉&lt;strong&gt;when publishing via&lt;/strong&gt;: &lt;code&gt;npx lerna publish --no-private&lt;/code&gt;, sometimes there is a problem after publishing with installing
packages, i.e. with slash decoding (instead of '/' to '%2f'), because of which it doesn't find the path to the package
and there is the error)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can see more of my commands in &lt;a href="https://github.com/YuesIt17/yuit-docs-npm-lerna-rollup/blob/main/README.md" rel="noopener noreferrer"&gt;&lt;strong&gt;README&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How to use npm packages
&lt;/h2&gt;

&lt;p&gt;After setting jfrog and npm project (lerna + rollup) we can install this package. &lt;br&gt;
But before we must:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;write &lt;strong&gt;virtual url registry of our artifactory&lt;/strong&gt; in .yarnrc.yml
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enableStrictSsl: false

httpTimeout: 600000

nodeLinker: node-modules

npmRegistryServer: 'https://some-art.com/artifactory/api/npm/portfolio-yues-it-npm/'

yarnPath: .yarn/releases/yarn-4.5.1.cjs

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;than install package via: 

&lt;ul&gt;
&lt;li&gt;yarn add @portfolio-yues-it-npm/ui&lt;/li&gt;
&lt;li&gt;yarn add @portfolio-yues-it-npm/utils&lt;/li&gt;
&lt;li&gt;yarn add @portfolio-yues-it-npm/icons&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;❗&lt;strong&gt;If you want to test your npm package without publishing&lt;/strong&gt;, just provide that path (&lt;strong&gt;file:../portfolio-yues-it-npm/packages/ui&lt;/strong&gt;) in dependencies and run &lt;code&gt;yarn install&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  "dependencies": {
    "@portfolio-yues-it-npm/ui": "file:../portfolio-yues-it-npm/packages/ui",
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/YuesIt17/yuit-docs-npm-lerna-rollup" rel="noopener noreferrer"&gt;lerna + rollup npm packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/YuesIt17/yuit-docs-vite" rel="noopener noreferrer"&gt;vite client for testing npm packages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and feedback!🤝&lt;/p&gt;

</description>
      <category>npm</category>
      <category>frontend</category>
      <category>documentation</category>
      <category>ui</category>
    </item>
  </channel>
</rss>
