Deploy Next js 14 app on Ubuntu or Linux VPS using Nginx Server. Follow the best detailed guide for top performance, security, and easy setup.byHasanul Haque Banna

Host Next.js 14 Application on Ubuntu VPS

When it comes to deploying modern web applications, Next.js has established itself as one of the top frameworks for developers. With its server-side rendering, static site generation, and hybrid capabilities, it offers a robust solution for building scalable web applications. This guide will walk you through the process of hosting a Next.js 14 application on an Ubuntu 22 VPS, ensuring your app runs smoothly and efficiently.

Whether you're a seasoned developer or just starting with Next.js, this tutorial will provide you with a step-by-step approach to deploying your application on a VPS. We'll cover everything from setting up your server environment to configuring Nginx for reverse proxying, ensuring that your application is both secure and performant.

Overview: What We Will Cover

In this guide, we will cover the following 9 steps:

  • Connecting to Your Ubuntu VPS
  • Updating and Installing Essential Dependencies
  • Installing Node.js Using NVM
  • Setting Up PM2 for Process Management
  • Deploying Your Next.js Application
  • Running Your Application with PM2
  • Configuring Nginx as a Reverse Proxy
  • Securing Your Site with SSL (Optional)
  • Final Configuration and UFW Setup

Now, let's dive into each step in detail.

Step 1: Connect to Your Ubuntu VPS

The first step in deploying your Next.js application is to connect to your Ubuntu VPS. If you haven't already, you should have access to your VPS through SSH. Open your terminal and enter the following command:

ssh username@vps_ip

Replace username with your VPS username and vps_ip with your VPS's IP address. Once connected, you'll be working directly on your VPS, where we'll set up the environment needed to host your Next.js application.

Step 2: Update and Install Essential Dependencies

Before we dive into setting up Node.js and other tools, it's essential to update your system's package list and upgrade any outdated packages. This ensures your environment is up-to-date and reduces the risk of conflicts during the installation process.

Run the following commands:

sudo apt update && sudo apt upgrade -y
sudo apt install nginx curl

These commands will update your package list, upgrade existing packages, and install Nginx and Curl, two critical components for our setup.

Note: Although Ubuntu 22 typically comes with Curl pre-installed, we are installing it manually to avoid potential issues. If you’re using a different version of Ubuntu, this step ensures you have the latest version of Curl.

Step 3: Installing Node.js Using NVM

Node.js is the runtime environment required for running Next.js applications. While you can install Node.js directly using apt-get, I recommend using NVM (Node Version Manager). NVM allows you to manage multiple versions of Node.js, making it easier to switch between versions or upgrade in the future.

To install NVM, run the following command:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash

After installation, load NVM into your shell session:

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" 
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"

To verify the installation, check the NVM version

nvm -v

You should see the installed NVM version as below:

Blog Post Image by Hasanul Haque Banna

Now, you can install Node.js using NVM:

nvm install --lts

This command installs the latest Long-Term Support (LTS) version of Node.js, ensuring that you have a stable and supported version for your application. After installation, verify Node.js and NPM (Node Package Manager) versions:

node -v
npm -v

You should see the installed Node and NPM version as below:

Blog Post Image by Hasanul Haque Banna

Step 4: Setting Up PM2 for Process Management

Next.js applications are typically run using the npm start command, but this isn't ideal for production. Instead, we'll use PM2, a process manager that keeps your application running even after you close your SSH session. PM2 also offers additional features like load balancing and monitoring, making it a powerful tool for managing Node.js applications.

Install PM2 globally using NPM:

npm install -g pm2

With PM2 installed, you're now ready to run your Next.js application in a more production-friendly manner.

Step 5: Deploying Your Next.js Application

Now that our environment is set up, it's time to deploy your Next.js application. First, create a directory where your application will reside:

sudo mkdir -p /var/www/myapp

Navigate to this directory and install your Next.js app dependencies:

cd /var/www/myapp
npm install
npm run build

This will install all the necessary packages and build your Next.js application for production. The build command compiles your application into an optimized bundle that can be served to users.

In my case, I directly install nextjs here. Let's go

Blog Post Image by Hasanul Haque BannaBlog Post Image by Hasanul Haque Banna

Step 6: Running Your Application with PM2

Instead of using the traditional npm start command, we'll leverage PM2 to manage our Next.js process. This ensures that your application remains running, even after server restarts or SSH disconnections.

Start your Next.js application using PM2:

pm2 start npm --name "nextjs-app" -- start

if you need to launch Next.js with pm2 on a different port then run the command below:

pm2 start npm --name "nextjs-app" -- start -- --port=3001

Now you can verify that your application is running by checking the PM2 process list:

pm2 list

You should see a list of pm2 that containing your nextjs-app to be running:

Blog Post Image by Hasanul Haque Banna

To ensure that PM2 restarts your application after a server reboot, run the following commands:

pm2 startup systemd
pm2 save

These commands configure PM2 to start your application automatically on system boot.

Step 7: Configuring Nginx as a Reverse Proxy

Nginx is a powerful web server that can act as a reverse proxy for your Next.js application. This means that Nginx will handle incoming HTTP requests and forward them to your Next.js server, which is running on port 3000 by default.

First, create a new Nginx configuration file:

sudo nano /etc/nginx/sites-available/your-domain

Replace your-domain.com with your actual domain name. If you don't have a domain name, you can use your server's IP address.

Paste the following configuration into the file:

server {
    listen 80;
    server_name domainname.com www.domainname.com; # Replace with your domain or IP

    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/myapp/.next/static/;
        expires 365d;
        access_log off;
    }

    location / {
        proxy_pass http://localhost:3000; # Ensure this matches your Next.js port
        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;
    }
}

This configuration tells Nginx to listen on port 80 (HTTP) and forward all requests to your Next.js application running on port 3000. The gzip settings optimize the compression of static assets, improving load times for your users.

Save and close the file. Then, enable this configuration and restart Nginx:

sudo ln -s /etc/nginx/sites-available/your-domain.com /etc/nginx/sites-enabled/your-domain.com
sudo nginx -t
sudo systemctl restart nginx

The nginx -t command tests your configuration for syntax errors, and if everything looks good, Nginx will restart with your new settings.

Step 8: Securing Your Site with SSL (Optional but Recommended)

Securing your site with SSL is crucial for protecting user data and improving SEO. Let's Encrypt provides free SSL certificates, and we can use Certbot to automate the installation process.

First, install Certbot and the Nginx plugin:

sudo apt install certbot python3-certbot-nginx

Next, obtain and install your SSL certificate:

sudo certbot --nginx -d your-domain.com

Replace your-domain.com with your actual domain name. Certbot will automatically configure Nginx to use SSL, and your site will now be accessible via HTTPS.

Step 9: Final Configuration and UFW Setup

To further secure your server, it's essential to configure UFW (Uncomplicated Firewall). We'll allow traffic on ports 80 (HTTP) and 443 (HTTPS), as well as SSH for remote access:

sudo ufw allow ssh
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable

Finally, restart Nginx to apply all changes:

sudo systemctl restart nginx
sudo systemctl status nginx

This will ensure that your Nginx server is running with the latest configuration and that your Next.js application is accessible via your domain or IP address.

Ensuring Proper Nginx Access (Optional but Helpful)

In some cases, even after correctly configuring Nginx, you might encounter issues where your domain doesn't seem to work as expected. This can be due to permission problems with your application's static files. While this step isn't mandatory, it can resolve certain issues that arise after Nginx configuration.

To give Nginx the proper access to your Next.js static files, you can adjust the permissions of the directories containing these files. Run the following commands:

sudo chmod -R 755 /var/www/myapp/.next/static/
sudo chmod -R 755 /var/www/myapp/public/static/

These commands ensure that Nginx has the necessary read and execute permissions to serve your static files properly. While this step is often overlooked in many tutorials, it can be crucial in troubleshooting issues related to file access and permissions.

Finally

In my case I don't have any domain yet so I go with my VPS ip_address and after all the setup, I am finally able to see Nextjs default landing page:

Blog Post Image by Hasanul Haque Banna

Conclusion

Congratulations! You have successfully deployed a Next.js 14 application on an Ubuntu 22 VPS. By following this guide, you've set up a robust environment that includes Nginx for reverse proxying, PM2 for process management, and SSL for security. This setup is scalable, secure, and production-ready, allowing you to focus on developing your application while ensuring it runs smoothly for your users.

Remember, maintaining your server is just as important as setting it up. Regularly update your packages, monitor your server's performance, and renew your SSL certificates to keep your application running securely and efficiently. With this foundation, you're well on your way to delivering a high-performance Next.js application to the world.