<?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: Markus Persson</title>
    <description>The latest articles on DEV Community by Markus Persson (@markusmp).</description>
    <link>https://dev.to/markusmp</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%2F1111164%2F7b9f6925-cbbc-4377-8f20-611e9bd9bb14.png</url>
      <title>DEV Community: Markus Persson</title>
      <link>https://dev.to/markusmp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/markusmp"/>
    <language>en</language>
    <item>
      <title>How to use the useMemo &amp; useCallback React hook</title>
      <dc:creator>Markus Persson</dc:creator>
      <pubDate>Sun, 02 Jul 2023 19:54:02 +0000</pubDate>
      <link>https://dev.to/markusmp/how-to-use-the-usememo-usecallback-hook-5a9h</link>
      <guid>https://dev.to/markusmp/how-to-use-the-usememo-usecallback-hook-5a9h</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As your React skills grow, you'll start to care more and more about how well your app performs. When it comes to optimizing React applications, caching is as important as any other tool or programming technique. In React, caching is commonly referred to as memoization, and it is used to reduce the number of times a component is rendered due to state or prop changes. This article will explain how to use the useMemo and useCallback hooks in React for caching purposes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The default caching in React
&lt;/h2&gt;

&lt;p&gt;By default, React uses a technique called "shallow comparison" to decide whether a component should be re-rendered. It compares the previous props and state of the component with the new ones, and if there are no changes, React assumes that the component hasn't changed, and it won't re-render.&lt;/p&gt;

&lt;p&gt;However, when dealing with more complex components that have advanced state management, this default mechanism may not be sufficient. In such cases, additional caching techniques are needed to optimize performance. That's where the useMemo and useCallback hooks come in.&lt;/p&gt;

&lt;h2&gt;
  
  
  useMemo hook
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; useMemo hook can only return a value.&lt;/p&gt;

&lt;p&gt;When a component renders, all the code within it is executed, including any functions defined within the component. If a function performs a complex calculation, it can be inefficient to execute it on every render, especially if the function's arguments hasn't changed.&lt;br&gt;
&lt;code&gt;React re-renders a component if a prop or state has changed.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is where the useMemo hook comes into play. By wrapping the function in an useMemo hook, React will remember the calculated value from the function between renders. It will only call the function if any of useMemo's dependencies specified in the dependency array (the second argument of useMemo) has changed. If the dependencies remain the same from the previous render, the previously calculated value is returned, and bypassing the need for a Recalculation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example without useMemo:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here you can see that &lt;code&gt;{expensiveCalculation(count)}&lt;/code&gt; will re-render no matter if your click &lt;code&gt;incrementCount&lt;/code&gt; or &lt;code&gt;incrementCountRender&lt;/code&gt; becuase React re-renders a component if a prop or state has changed. Which results in everything inside of the &lt;code&gt;JSX return()&lt;/code&gt; will get rendered again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from "react";

const App = () =&amp;gt; {
  const [count, setCount] = useState(0);
  const [countRender, setCountRender] = useState(1)

  const incrementCount = () =&amp;gt; {
    console.log('Increment count')
    setCount((c) =&amp;gt; c + 1);
  };


  const incrementCountRender = () =&amp;gt; {
    console.log('Increment count render')
    setCountRender((c) =&amp;gt; c + 1)
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;
        Count: {count}
        &amp;lt;button onClick={incrementCount}&amp;gt;+&amp;lt;/button&amp;gt;
        &amp;lt;br /&amp;gt;
        Count render: {countRender}
        &amp;lt;button onClick={incrementCountRender}&amp;gt;+&amp;lt;/button&amp;gt;
        &amp;lt;h2&amp;gt;Expensive Calculation&amp;lt;/h2&amp;gt;
        {expensiveCalculation(count)}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

const expensiveCalculation = (num: number) =&amp;gt; {
  console.log("Expensive calculation");
  for (let i = 0; i &amp;lt; 1000000000; i++) {
    num += 1;
  }
  return num;
};

export default App
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example with useMemo:&lt;/strong&gt;&lt;br&gt;
I removed &lt;code&gt;{expensiveCalculation(count)}&lt;/code&gt; from the &lt;code&gt;JSX return()&lt;/code&gt; and added &lt;code&gt;calculatedResult&lt;/code&gt; function which is wrapped with useMemo and returns &lt;code&gt;expensiveCalculation(count)&lt;/code&gt; with a dependency array that has &lt;code&gt;count&lt;/code&gt; inside of it. This useMemo function will only run in the initial render and if &lt;code&gt;count&lt;/code&gt; has changed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useMemo, useState } from "react";

const App = () =&amp;gt; {
  const [count, setCount] = useState(0);
  const [countRender, setCountRender] = useState(1)

  const incrementCount = () =&amp;gt; {
    console.log('Increment count')
    setCount((c) =&amp;gt; c + 1);
  };


  const incrementCountRender = () =&amp;gt; {
    console.log('Increment count render')
    setCountRender((c) =&amp;gt; c + 1)
  }

  const calculatedResult = useMemo(() =&amp;gt; {
    console.log('useMemo')
    return expensiveCalculation(count)
  }, [count])

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;
        Count: {count}
        &amp;lt;button onClick={incrementCount}&amp;gt;+&amp;lt;/button&amp;gt;
        &amp;lt;br /&amp;gt;
        Count render: {countRender}
        &amp;lt;button onClick={incrementCountRender}&amp;gt;+&amp;lt;/button&amp;gt;
        &amp;lt;h2&amp;gt;Expensive Calculation&amp;lt;/h2&amp;gt;
        {calculatedResult}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

const expensiveCalculation = (num: number) =&amp;gt; {
  console.log("Expensive calculation");
  for (let i = 0; i &amp;lt; 1000000000; i++) {
    num += 1;
  }
  return num;
};

export default App
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  useCallback hook
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; useCallback hook returns a function.&lt;/p&gt;

&lt;p&gt;The useCallback hook in React allows you to memoize a function, ensuring that the function reference remains the same between renders unless any dependencies specified in the dependency array (the second argument of useCallback) have changed.&lt;/p&gt;

&lt;p&gt;When a component renders, all the code within it is executed, including the creation of any functions inside the component. If a function is passed down as a prop to child components, it can lead to unnecessary re-renders of those child components if the function reference changes, even if the logic inside the function hasn't changed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example without useCallback&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The getTodos function retrieves a single todo from the todos array based on the count state. This function is then passed as a prop to the TodosList component, where it is used in an useEffect hook to update the state by spreading the retrieved todo with the existing todos.&lt;/p&gt;

&lt;p&gt;This functionality works correctly when there is no countTwo state or setCountTwo button, as they trigger a re-render of the component. If the button is clicked, it will cause the TodosList component to re-render, resulting in the addition of an old todo to the todos state, which can lead to an error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useEffect, useState } from "react";

const todos = [
  {id: 1, title: 'Todo 1'},
  {id: 2, title: 'Todo 2'},
  {id: 3, title: 'Todo 3'},
  {id: 4, title: 'Todo 4'},
  {id: 5, title: 'Todo 5'},
]

const App = () =&amp;gt; {
  const [count, setCount] = useState(0);
  const [countTwo, setCountTwo] = useState(100)

  const getTodos = () =&amp;gt; {
    return todos[count]
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;
        Count: {count}
        &amp;lt;button onClick={() =&amp;gt; setCount(count + 1)}&amp;gt;+&amp;lt;/button&amp;gt;
        &amp;lt;br /&amp;gt;
        Count Two: {countTwo}
        &amp;lt;button onClick={() =&amp;gt; setCountTwo(countTwo - 1)}&amp;gt;+&amp;lt;/button&amp;gt;
        &amp;lt;br /&amp;gt;
        &amp;lt;TodosList getTodos={getTodos}/&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

const TodosList = ({getTodos}) =&amp;gt; {
  const [todos, setTodos] = useState([])

  useEffect(() =&amp;gt; {
    console.log('getTodos function is called.')
    setTodos([...todos, getTodos()])
  }, [getTodos])

  return (
    &amp;lt;&amp;gt;
    {todos.map(todo =&amp;gt; &amp;lt;span key={todo.id}&amp;gt;{todo.title} &amp;lt;/span&amp;gt;)}
    &amp;lt;/&amp;gt;
  )
}

export default App
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example with useCallback:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here, we have wrapped the getTodos function in a useCallback hook. This ensures that the function will only be executed during the initial render of the component or when the count state has changed. Otherwise, it won't be invoked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useCallback, useEffect, useState } from "react";

const todos = [
  {id: 1, title: 'Todo 1'},
  {id: 2, title: 'Todo 2'},
  {id: 3, title: 'Todo 3'},
  {id: 4, title: 'Todo 4'},
  {id: 5, title: 'Todo 5'},
]

const App = () =&amp;gt; {
  const [count, setCount] = useState(0);
  const [countTwo, setCountTwo] = useState(100)

  const getTodos = useCallback(() =&amp;gt; {
    return todos[count]
  }, [count])

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;
        Count: {count}
        &amp;lt;button onClick={() =&amp;gt; setCount(count + 1)}&amp;gt;+&amp;lt;/button&amp;gt;
        &amp;lt;br /&amp;gt;
        Count Two: {countTwo}
        &amp;lt;button onClick={() =&amp;gt; setCountTwo(countTwo - 1)}&amp;gt;+&amp;lt;/button&amp;gt;
        &amp;lt;br /&amp;gt;
        &amp;lt;TodosList getTodos={getTodos}/&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

const TodosList = ({getTodos}) =&amp;gt; {
  const [todos, setTodos] = useState([])

  useEffect(() =&amp;gt; {
    console.log('getTodos function is called.')
    setTodos([...todos, getTodos()])
  }, [getTodos])

  return (
    &amp;lt;&amp;gt;
    {todos.map(todo =&amp;gt; &amp;lt;span key={todo.id}&amp;gt;{todo.title} &amp;lt;/span&amp;gt;)}
    &amp;lt;/&amp;gt;
  )
}

export default App
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclution
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;useMemo:&lt;/strong&gt; allows you to calculate and store a value only when its dependencies have changed. By memoizing the value, Then React can avoid unnecessary recalculations and re-renders of the component, improving overall performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;useCallback:&lt;/strong&gt; is used to memoize a function. It returns a memoized version of the function that will only be called if its dependencies has been changed. This is particularly useful when passing callbacks as props to child components.&lt;/p&gt;

&lt;p&gt;By using useMemo and useCallback wisely, you can optimize your React application by reducing unnecessary calculations and rendering, leading to improved performance and a smoother user experience.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Step-by-Step Guide: Deploying a NextJS App on a VPS</title>
      <dc:creator>Markus Persson</dc:creator>
      <pubDate>Sat, 01 Jul 2023 19:47:32 +0000</pubDate>
      <link>https://dev.to/markusmp/step-by-step-guide-deploying-a-nextjs-app-on-a-vps-4iaj</link>
      <guid>https://dev.to/markusmp/step-by-step-guide-deploying-a-nextjs-app-on-a-vps-4iaj</guid>
      <description>&lt;p&gt;Hello, today we will explore how we can deploy a Next.js website on a Ubuntu Virtual Private Server (VPS). A VPS provides the user with the flexibility and control of a dedicated server, allowing them to install and configure their preferred software and applications while sharing the underlying hardware infrastructure with other VPS instances. It offers a cost-effective solution for hosting websites, running applications, and managing online services with improved scalability, security, and customization options.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To begin to deploy your Next.js app on a VPS, you’ll need to fulfill the following prerequisites:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A Next.js project: If you don't already have a Next.js project, you can create one in your terminal using the command &lt;code&gt;npx create next-app@latest&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Git &amp;amp; GitHub: You'll need to create a &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; repository and push your code to that repository using &lt;a href="https://git-scm.com/" rel="noopener noreferrer"&gt;git&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VPS: Research and select a VPS provider that suits your needs in terms of pricing, features, server location, performance, and customer support. I personally like DigitalOcean's Droplet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create an SSH key: Create an SSH key on your local machine and add it to your VPS provider.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Now, let’s dive into the process of deploying your Next.js application to a VPS:&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Point your domain to the server
&lt;/h2&gt;

&lt;p&gt;Once you have created a VPS, you will be provided with an IP address. Copy this IP address and go to the dashboard of your domain website. In the DNS settings, or if you have changed the nameservers to Cloudflare and are using &lt;a href="https://www.cloudflare.com/" rel="noopener noreferrer"&gt;Cloudflare DNS&lt;/a&gt; (which is recommended &amp;amp; free), find the @ record and modify it to point to the IP address of your VPS server. This ensures that your domain is correctly pointed to your VPS, allowing it to be accessible through your domain name.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Connect to your server
&lt;/h2&gt;

&lt;p&gt;To access the server via SSH, you can use the command &lt;code&gt;ssh root@your_vps_ip.&lt;/code&gt; However, it is important to note that without an SSH key, you won't be able to connect to the server using your terminal. To enable SSH access, you need to create an SSH key on your local machine and add the corresponding public key to your VPS provider's SSH settings. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. Update the server
&lt;/h2&gt;

&lt;p&gt;Now we can update the Ubuntu server using the command &lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade&lt;/code&gt; in your terminal, it will usually take some time. If you see &lt;code&gt;Configuring openssh-server&lt;/code&gt; just click ok.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Install NGINX &amp;amp; Certbot
&lt;/h2&gt;

&lt;p&gt;We can install NGINX and Certbot using the command &lt;code&gt;sudo apt install nginx certbot python3-certbot-nginx&lt;/code&gt;. Certbot will allow you to use let's encrypt which will give your domain an SSL certificate for free.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Allow firewall access
&lt;/h2&gt;

&lt;p&gt;Run these commands in order&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;sudo ufw allow "Nginx Full"&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ufw allow OpenSSH&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ufw enable&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  6. Install NPM
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;apt install npm&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Install pm2 &amp;amp; check if it's working
&lt;/h2&gt;

&lt;p&gt;pm2 is a process manager for Node.js which basically tells Next.js to start or stop running. Install it using the command &lt;code&gt;npm install -g pm2&lt;/code&gt; and check if it's working by using the following command &lt;code&gt;pm2 status&lt;/code&gt;. You should see a table with nothing running.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Install NVM &amp;amp; Node.js
&lt;/h2&gt;

&lt;p&gt;Now you need to run the following command &lt;code&gt;cd /var/www&lt;/code&gt; and then run these commands in order.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;exec $SHELL&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;nvm install --lts&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  9. Create an SSH key in your VPS server and place in GitHub
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;cd ~/.ssh&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run this command to create an SSH key &lt;code&gt;ssh-keygen -t rsa -b 4096 -C your@github_email.com&lt;/code&gt;, replace the email address &lt;code&gt;your@github_email.com&lt;/code&gt; with the email address that is associated with your GitHub account.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the command &lt;code&gt;ls&lt;/code&gt; to see what files exists.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;cat id_rsa.pub&lt;/code&gt; And copy the text, it will look something like this &lt;code&gt;ssh-rsa long_random_text your@github_email.com&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to GitHub and click on your avatar upper right corner then click settings, then on the left sidebar click &lt;code&gt;SSH and GPG keys&lt;/code&gt;, then upper right click &lt;code&gt;New SSH key&lt;/code&gt;, and paste the key and name it something like &lt;code&gt;vps_key&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now run this command &lt;code&gt;cd /var/www&lt;/code&gt; in your terminal to got back to the root folder.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  10. Clone Next.js project inside a new folder &amp;amp; install dependencies
&lt;/h2&gt;

&lt;p&gt;Go to your GitHub's project repository and click the green button &lt;code&gt;Code&lt;/code&gt; and select SSH. It should look something like this.&lt;/p&gt;

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

&lt;p&gt;Copy it and edit to look like this &lt;code&gt;git clone git@github.com:your_github_name/your_repository_name.git your_app_name&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now we can clone it into our VPS. Make sure you have run the command &lt;code&gt;cd /var/www&lt;/code&gt; and then run the command &lt;code&gt;git clone git@github.com:your_github_name/your_repository_name.git your_app_name&lt;/code&gt; Ensure that you provide a name at the end; otherwise, it will clone into the &lt;code&gt;var/www&lt;/code&gt; folder, which is not what we want.&lt;/p&gt;

&lt;p&gt;Now we can check if it has created a folder using &lt;code&gt;ls&lt;/code&gt; and then cd into the folder using &lt;code&gt;cd your_app_name&lt;/code&gt;, and then run the command &lt;code&gt;npm install&lt;/code&gt; to install all the required dependencies. Then we can run &lt;code&gt;npm run build&lt;/code&gt; to build the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Create NGINX file and configure it
&lt;/h2&gt;

&lt;p&gt;Run this command &lt;code&gt;cd /etc/nginx/sites-available&lt;/code&gt; then run &lt;code&gt;touch your_app_name&lt;/code&gt; the name of the folder u cloned your repository to. Then we can run the command &lt;code&gt;nano your_app_name&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Change &lt;code&gt;domainname.com&lt;/code&gt; in &lt;code&gt;server_name domainname.com;&lt;/code&gt; to your domain name you pointed to the server and keep &lt;code&gt;;&lt;/code&gt; and change the &lt;code&gt;your_app_name&lt;/code&gt; in &lt;code&gt;alias /var/www/your_app_name/.next/static/;&lt;/code&gt; to folder name you created with git clone. You can use arrow keys to go up and down and to save you can press &lt;code&gt;CTRL + s&lt;/code&gt; and to exit press &lt;code&gt;CTRL + X&lt;/code&gt;.&lt;/p&gt;

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

server {
        listen 80;
        server_name domainname.com;

        gzip on;
        gzip_proxied any;
        gzip_types application/javascript application/x-javascript text/css text/javascript;
        gzip_comp_level 5;
        gzip_buffers 16 8k;
        gzip_min_length 256;

        location /_next/static/ {
                alias /var/www/your_app_name/.next/static/;
                expires 365d;
                access_log off;
        }

        location / {
                proxy_pass http://127.0.0.1:3000; #change to 3001 for second app, but make sure second nextjs app starts on new port in packages.json "start": "next start -p 3001",
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;
        }
}




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

&lt;/div&gt;

&lt;p&gt;Now we need to run &lt;code&gt;nano /etc/nginx/nginx.conf&lt;/code&gt; in the terminal and change &lt;code&gt;include /etc/nginx/sites-enabled/*;&lt;/code&gt; to &lt;code&gt;include /etc/nginx/sites-available/*;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then we need to make sure everything is ok, we can run the command &lt;code&gt;nginx -t&lt;/code&gt;. Next we need to remove default config files, run these commands.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;cd /etc/nginx/sites-available&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;rm default&lt;/code&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;cd /etc/nginx/sites-enabled&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;rm default&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now we can restart NGINX using the command &lt;code&gt;systemctl restart nginx&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Launch app and create an SSL with let's encrypt
&lt;/h2&gt;

&lt;p&gt;Now we need to go back to the directory of our project using &lt;code&gt;cd /var/www/name_of_app&lt;/code&gt; and then run the command &lt;code&gt;pm2 start npm --name name_of_app -- start&lt;/code&gt; but change &lt;code&gt;name_of_app&lt;/code&gt; to the name of the directory of your project. Last we need to create an SSL using Certbot &lt;code&gt;sudo certbot --nginx -d domainname.com&lt;/code&gt;. Congratulations you have now successfully deployed an Next.js application on a VPS server 🎉.&lt;/p&gt;

&lt;h3&gt;
  
  
  Helpful commands
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Starts the app: &lt;code&gt;pm2 start npm --name name_of_app -- start&lt;/code&gt; You need to be inside of the application directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restarts NGINX: &lt;code&gt;systemctl restart nginx&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adds a SSL using Let's encrypt for a specified domain: &lt;code&gt;sudo certbot --nginx -d domainname.com&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nextjs</category>
      <category>github</category>
      <category>vps</category>
      <category>nginx</category>
    </item>
    <item>
      <title>How to Dockerize a Next.js Application Using Docker for Beginners</title>
      <dc:creator>Markus Persson</dc:creator>
      <pubDate>Fri, 30 Jun 2023 19:59:52 +0000</pubDate>
      <link>https://dev.to/markusmp/how-to-dockerize-a-nextjs-application-using-docker-for-beginners-5hi8</link>
      <guid>https://dev.to/markusmp/how-to-dockerize-a-nextjs-application-using-docker-for-beginners-5hi8</guid>
      <description>&lt;p&gt;Hello, today we will explore how Docker can be used to Dockerize your Next.js application. Docker is an open-source platform that allows you to containerize your applications to develop, ship, and run applications efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To begin containerizing your Next.js app using Docker, you’ll need to fulfill the following prerequisites:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Docker: Install Docker on your Windows, Mac, or Linux system. You can find the installation on Docker’s website.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Node.js: Download &amp;amp; Install it on your PC.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Now, let’s dive into the process of Dockerizing your Next.js application:&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Setting up a New Next.js Project
&lt;/h2&gt;

&lt;p&gt;If you already have a Next.js project, you can skip this step. Otherwise, follow the instructions below:&lt;/p&gt;

&lt;p&gt;In your terminal, run the command &lt;code&gt;npx create-next-app@latest&lt;/code&gt; to create a new Next.js project and follow the instruction provided in the terminal by Next.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Creating the Dockerfile
&lt;/h2&gt;

&lt;p&gt;In the root directory of your project, create a file called “Dockerfile” (without any file extension). This file serves as a step-by-step script for Docker to build the container image.&lt;/p&gt;

&lt;p&gt;Copy and paste the following code into your Dockerfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:18-alpine

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 3000

CMD npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s a breakdown of the Dockerfile:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;FROM node:18-alpine&lt;/code&gt; instructs Docker to use a lightweight Linux distribution with Node.js version 18 installed. You can choose a different OS image from Docker Hub if you prefer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;WORKDIR /app&lt;/code&gt; sets the working directory inside the container to /app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;COPY package*.json ./&lt;/code&gt; copies the package.json file into the working directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;RUN npm install&lt;/code&gt; installs all the dependencies for your project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;COPY . .&lt;/code&gt; copies all the files from the current directory into the working directory of the container. You can utilize a .dockerignore file to exclude specific files from being copied.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;EXPOSE 3000&lt;/code&gt; exposes port 3000 from the container to the local network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;CMD npm run dev&lt;/code&gt; starts the development server inside the container.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Building Your Docker Container
&lt;/h2&gt;

&lt;p&gt;In your terminal, navigate to the root directory of your project and run the command &lt;code&gt;docker build -t nextjs_docker:dev .&lt;/code&gt; This command builds the Docker container with the specified name (&lt;code&gt;nextjs_docker&lt;/code&gt;) and tag (&lt;code&gt;dev&lt;/code&gt;). Feel free to customize the name and tag as per your preference. The &lt;code&gt;.&lt;/code&gt; indicates that the Dockerfile is located in the current directory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Each time you run this command, a new image of your container will be created. You can view the images on your system by running &lt;code&gt;docker images&lt;/code&gt; or &lt;code&gt;docker image ls&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Running the Docker Container
&lt;/h2&gt;

&lt;p&gt;There are two ways to run your Docker container image: through the command line or using the Docker Desktop GUI.&lt;/p&gt;

&lt;p&gt;To run the container through the command line, open your terminal &lt;br&gt;
and execute the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --publish 3000:3000 nextjs_docker:dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you prefer using the Docker Desktop GUI, open Docker Desktop and navigate to the “Images” tab. Select the desired image and click the “Run” button.&lt;/p&gt;

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

&lt;p&gt;Once the container is running, access your Next.js application by visiting &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000/&lt;/a&gt;. You should be able to see the homepage of your Next.js application.&lt;/p&gt;

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

&lt;p&gt;Please note that this article only covers the process of containerizing your development environment for portability purposes. It is not intended for production use.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>javascript</category>
      <category>docker</category>
      <category>react</category>
    </item>
  </channel>
</rss>
