Skip to content

How to Deploy a Next.js App on a VPS

While there are many hosting options available, deploying your Next.js app on a Virtual Private Server (VPS) gives you complete control over your environment and can be more cost-effective for larger projects. This guide will walk you through the process of deploying a Next.js app on a VPS, from setting up your server to configuring your application for production use.

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Setting Up Your VPS
  4. Installing Node.js and npm
  5. Setting Up a Web Server
  6. Configuring Your Domain
  7. Preparing Your Next.js App for Deployment
  8. Deploying Your Next.js App
  9. Setting Up Process Management
  10. Configuring SSL/TLS
  11. Automating Deployments
  12. Monitoring and Maintenance
  13. Troubleshooting Common Issues
  14. Conclusion

1. Introduction

Deploying a Next.js app on a VPS offers several advantages:

  • Complete control over your server environment
  • Ability to customize server configurations
  • Potentially lower costs for larger applications
  • Flexibility to scale resources as needed

This guide assumes you have a basic understanding of Next.js, Node.js, and Linux command-line operations. We'll be using Ubuntu as our server operating system, but most steps should be similar for other Linux distributions.

2. Prerequisites

Before we begin, make sure you have:

  • A Next.js application ready for deployment
  • A VPS with Ubuntu installed (we'll use Ubuntu 22.04 LTS in this guide)
  • SSH access to your VPS
  • A domain name pointing to your VPS's IP address

3. Setting Up Your VPS

First, let's secure our VPS and update its software:

  1. SSH into your VPS: ssh username@your_server_ip

  2. Update the package list and upgrade installed packages: sudo apt update && sudo apt upgrade -y

  3. Set up a firewall (we'll use UFW): sudo apt install ufw sudo ufw allow OpenSSH sudo ufw enable

  4. Create a new user with sudo privileges (replace your_username with your desired username): sudo adduser your_username sudo usermod -aG sudo your_username

  5. Set up SSH key authentication for the new user (optional but recommended).

4. Installing Node.js and npm

Next.js requires Node.js to run. Let's install Node.js and npm:

  1. Install Node.js and npm using nvm (Node Version Manager): curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash source ~/.bashrc nvm install --lts

  2. Verify the installation: node --version npm --version

5. Setting Up a Web Server

We'll use Nginx as our web server to handle incoming requests and proxy them to our Next.js application:

  1. Install Nginx: sudo apt install nginx

  2. Allow Nginx through the firewall: sudo ufw allow 'Nginx Full'

  3. Start Nginx and enable it to start on boot: sudo systemctl start nginx sudo systemctl enable nginx

6. Configuring Your Domain

Assuming you have a domain name pointing to your VPS's IP address, let's configure Nginx to serve your Next.js app:

  1. Create a new Nginx server block: sudo nano /etc/nginx/sites-available/your_domain

  2. Add the following configuration (replace your_domain with your actual domain): ```nginx server { listen 80; server_name your_domain www.your_domain;

    location / { proxy_pass http://localhost:3000; 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; } } ```

  3. Create a symbolic link to enable the site: sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

  4. Test the Nginx configuration: sudo nginx -t

  5. If the test is successful, reload Nginx: sudo systemctl reload nginx

7. Preparing Your Next.js App for Deployment

Before deploying your Next.js app, make sure it's optimized for production:

  1. Update your package.json file to include the following scripts: json "scripts": { "dev": "next dev", "build": "next build", "start": "next start" }

  2. If you're using environment variables, create a .env.local file in your project root and add your production environment variables.

  3. Make sure your .gitignore file includes: node_modules .next .env.local

  4. Commit your changes and push them to your version control system (e.g., GitHub).

8. Deploying Your Next.js App

Now, let's deploy your Next.js app to your VPS:

  1. Create a directory for your app: sudo mkdir -p /var/www/your_domain sudo chown -R $USER:$USER /var/www/your_domain

  2. Clone your repository (replace with your actual repository URL): git clone https://github.com/yourusername/your-nextjs-app.git /var/www/your_domain

  3. Navigate to your app directory: cd /var/www/your_domain

  4. Install dependencies: npm install

  5. Build your Next.js app: npm run build

  6. Start your Next.js app: npm run start

At this point, your Next.js app should be running and accessible through your domain.

9. Setting Up Process Management

To keep your app running even after you close your SSH session, we'll use PM2:

  1. Install PM2 globally: npm install -g pm2

  2. Start your Next.js app with PM2: pm2 start npm --name "next-app" -- start

  3. Set up PM2 to start on system boot: pm2 startup systemd

  4. Save the current PM2 process list: pm2 save

10. Configuring SSL/TLS

To secure your site with HTTPS, let's set up SSL/TLS using Let's Encrypt:

  1. Install Certbot: sudo apt install certbot python3-certbot-nginx

  2. Obtain and install a certificate: sudo certbot --nginx -d your_domain -d www.your_domain

  3. Follow the prompts to configure HTTPS.

  4. Certbot will automatically update your Nginx configuration to use HTTPS.

11. Automating Deployments

To streamline future updates, consider setting up a CI/CD pipeline. Here's a basic example using GitHub Actions:

  1. Create a .github/workflows/deploy.yml file in your repository:
name: Deploy to VPS

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Deploy to VPS
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.SSH_PRIVATE_KEY }}
        script: |
          cd /var/www/your_domain
          git pull
          npm install
          npm run build
          pm2 restart next-app
  1. Set up the necessary secrets in your GitHub repository settings.

12. Monitoring and Maintenance

To keep your Next.js app running smoothly:

  1. Set up monitoring with PM2: pm2 monitor

  2. Regularly update your Node.js version and npm packages.

  3. Monitor your server resources and scale as needed.

  4. Set up log rotation for your app and Nginx logs.

13. Troubleshooting Common Issues

Here are some common issues you might encounter and how to resolve them:

  1. App not starting: Check your Node.js version, ensure all dependencies are installed, and review your error logs.

  2. "502 Bad Gateway" error: This usually means your Node.js app isn't running. Check your PM2 processes and Nginx configuration.

  3. Slow performance: Consider optimizing your Next.js app, adjusting your VPS resources, or implementing caching strategies.

  4. SSL certificate issues: Ensure your domain is correctly pointed to your VPS and that Certbot can access your server on port 80.

14. Conclusion

Deploying a Next.js app on a VPS gives you great flexibility and control over your hosting environment. While it requires more setup than some platform-as-a-service options, it allows for customization and potentially lower costs for larger applications.

By following this guide, you've learned how to: - Set up and secure a VPS - Install and configure the necessary software - Deploy your Next.js app - Set up process management and SSL/TLS - Implement basic automation and monitoring

Remember to keep your server and applications updated, monitor performance, and scale resources as your traffic grows. With these steps, you're well on your way to successfully hosting your Next.js application on your own VPS.