Best deals in your Town!

Self Hosting

Self Hosting Next.js App From Your Local Home Lab

So, you’ve built a killer Next.js app and you’re ready to unleash it on the world. But instead of relying on big cloud providers, you want to take the DIY route and self-host it from your very own home lab. You’re not alone. Self-hosting gives you more control, saves money, and it could be a great learning experience.

In this guide, we’ll walk you through how to self-host a Next.js application from your local machine, and make it accessible over the internet. We’ll cover the essential steps, from setting up your server to securing your application, including tips and tricks for regular backups and updates.

Here’s what all we’re going to cover in this article.

  • Setting Up Your Server: Configuring your local machine to act as a server.
  • Installing Node.js and npm: Installing the necessary runtime environment for Next.js.
  • Setting up Your Next.js Application: Uploading your Next.js Application to the server.
  • Configuring a Production Build: Building your Next.js application for production.
  • Using a Process Manager: Keeping your Next.js app running smoothly with PM2.
  • Setting up a Reverse Proxy with Nginx: Configuring Nginx to forward requests to your Next.js app.
  • Domain Name and DNS Configuration: Linking your domain name to your home server.
  • Securing Your Application with SSL: Setting up HTTPS with Certbot.
  • Firewall Configuration: Protecting your server with a firewall.
  • Regular Backups: Automating backups to safeguard your data.
  • Regular Updates: keeping your application up to date with security & bug patches.

Setting Up Your Server

First, you’ll need a machine to act as your server. It could be an old laptop, a Raspberry Pi, or a dedicated machine setup with Ubuntu server. Here are few things to consider when setting up your server.

  • Hardware Resources: A baseline of 0.25 vCPU and 0.5 GB of memory might lead to slow performance. Consider bumping it up to at least 1 vCPU and 1GB RAM for a smoother experience [1].
  • Operating System: For this guide, we’ll assume you’re using Ubuntu Server, a popular and lightweight choice.

To get started, install Ubuntu Server on your chosen machine. Once installed, you’ll want to configure some basic things like setting up SSH , setting up a static IP and much more. Here are the steps.

  1. Install SSH: Access your server remotely.

    sudo apt update
    sudo apt install openssh-server
    
  2. Configure Static IP: In order to make sure the IP address of your server is persistent, you need to make sure the IP address is static. This ensures that the IP address does not change after rebooting your server.

    sudo nano /etc/netplan/01-network-manager-all.yaml
    

    Add the following lines of code. Remember to change the values as per your network configurations.

    network:
    version: 2
    renderer: networkd
    ethernets:
        eth0:
            dhcp4: no
            addresses: [192.168.1.100/24]
            gateway4: 192.168.1.1
            nameservers:
                addresses: [8.8.8.8,8.8.4.4]
    

    To apply the changes, run:

    sudo netplan apply
    

Installing Node.js and npm

Next.js is a JavaScript framework, so you’ll need Node.js and npm (Node Package Manager) installed on your server. NVM(Node Version Manager) will allow us to easily switch between different Node.js versions. Here’s how to install them:

  1. Install NVM: Install NVM using the following command:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
  1. Activate NVM: After installation, activate NVM by sourcing the NVM script.
source ~/.nvm/nvm.sh
  1. Install Node.js: Once NVM is installed, you can install Node.js.
    bash
    nvm install --lts
  2. Verify the Installation: Ensure Node.js and npm are installed correctly by checking their versions:
    bash
    node -v
    npm -v

Setting up Your Next.js Application

Now that your server is ready, you need to transfer your Next.js application files to the server. There are a couple of ways to do this such as using Git or SCP(Secure Copy).

Using Git

  1. Initialize Git Repository: If you haven’t already, initialize a Git repository in your Next.js project:
git init
or
git clone <repo url>
  1. Commit Your Code: Commit your application code to the repository:
git add .
git commit -m "Initial commit"
  1. Clone Repository on the Server: On your server, clone the repository to a directory, such as /var/www/your-app:
cd /var/www/
sudo git clone <your-repository-url> your-app

Using SCP

  1. Install SCP: SCP should already be installed on most systems.
  2. Copy Files: Use SCP to copy your Next.js application files to the server:
scp -r /path/to/your/nextjs/app user@your-server-ip:/var/www/your-app

Configuring a Production Build

To run your Next.js application in a production environment, you need to build it using the following steps:

  1. Install Dependencies: Navigate to your application directory on the server and install the dependencies:
cd /var/www/your-app
npm install
  1. Create .env.local File: If your project uses environment variables, create a .env.local file in your application directory:
touch .env.local
nano .env.local
  1. Add Environment Variables: Add your environment variables to the .env.local file. For example:

    DATABASE_URL="your_database_url"
    NEXTAUTH_SECRET="your_nextauth_secret"
    
  2. Build the Application: Run the build command to create an optimized production build:

npm run build

Using a Process Manager

To ensure your Next.js application stays running smoothly, even after crashes or server reboots, you can use a process manager like PM2.

  1. Install PM2: Install PM2 globally:
npm install -g pm2
  1. Start Your Application: Start your Next.js application with PM2:
pm2 start npm --name "your-app" -- start

This command tells PM2 to start your app using the `npm start` command.

  1. Set up Auto-Start: Configure PM2 to start your application automatically on server reboot:
pm2 startup
sudo env PATH=$PATH:/usr/bin /home/ubuntu/.pm2/pm2-init.sh start-process-manager ubuntu

PM2 will provide a command to run, copy and paste it to set up the auto-start.

  1. Save Current Process: Save the current process list so that PM2 can restore it on reboot:
pm2 save

Setting up a Reverse Proxy with Nginx

Now, set up Nginx as a reverse proxy to manage incoming traffic and forward it to your Next.js application.

  1. Install Nginx: Install Nginx:
sudo apt update
sudo apt install nginx
  1. Create Nginx Configuration File: Create a new configuration file for your Next.js application in /etc/nginx/sites-available/:
sudo nano /etc/nginx/sites-available/your-app

and Add your Next.js application details to the file. Replace the values with your own configurations.

server {
    listen 80;
    server_name yourdomain.com;

    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;
    }
}
  1. Create a Symbolic Link: To enable your configuration, create a symbolic link from the sites-available directory to the sites-enabled directory:
sudo ln -s /etc/nginx/sites-available/your-app /etc/nginx/sites-enabled/
  1. Remove Default Configuration: Remove the default Nginx configuration file:
sudo rm /etc/nginx/sites-available/default
sudo rm /etc/nginx/sites-enabled/default
  1. Test Configuration: Test the Nginx configuration for any syntax errors:
sudo nginx -t
  1. Restart Nginx: Restart Nginx to apply the changes:
sudo systemctl restart nginx

Domain Name and DNS Configuration

To make your Next.js application accessible through a domain name, you need to configure your DNS settings.

  1. Get Your Server’s Public IP: Find the public IP address of your server:
curl ifconfig.me
  1. Configure DNS Records: Go to your domain registrar’s website (e.g., Namecheap, Cloudflare) and add an A record that points your domain (or subdomain) to your server’s public IP address.
    • Type: A
    • Name/Host: @ (or subdomain, e.g., app)
    • Value/Address: Your server’s public IP

Securing Your Application with SSL

To secure your Next.js application with HTTPS, you can use Certbot, a free and open-source tool that automates the process of obtaining and installing SSL certificates from Let’s Encrypt.

  1. Install Certbot:
    bash
    sudo apt update
    sudo apt install certbot python3-certbot-nginx
  2. Obtain SSL Certificate: Run Certbot to obtain and install the SSL certificate for your domain:
sudo certbot --nginx -d yourdomain.com

Certbot will automatically configure Nginx to use the SSL certificate.

  1. Automatic Renewal: To ensure your SSL certificate is automatically renewed, set up a cron job:
sudo crontab -e

Add the following line to renew the certificate automatically.

0 0 * * * /usr/bin/certbot renew --quiet

Firewall Configuration

A firewall is essential to protect your server from unauthorized access. You can use UFW (Uncomplicated Firewall) to configure a firewall.

  1. Install UFW:
sudo apt update
sudo apt install ufw
  1. Configure UFW: Allow SSH, HTTP, and HTTPS traffic:
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx HTTP'
sudo ufw allow 'Nginx HTTPS'
  1. Enable UFW:
sudo ufw enable
  1. Check Status:
sudo ufw status

Regular Backups

Regular backups are crucial to prevent data loss in case of hardware failure, corruption, or other unforeseen events. You can automate backups using tools like rsync or scp.

sudo apt install rsync

Create a script to perform the backup:

sudo nano /usr/local/bin/backup-script.sh

Add the following content to the script, make sure to change the directories wherever necessary.

#!/bin/bash
DATE=$(date +%Y%m%d)
BACKUP_DIR="/var/backup"
BACKUP_SOURCE="/var/www/your-app"
BACKUP_DEST="$BACKUP_DIR/backup-$DATE.tar.gz"

# Create backup directory if it doesn't exist
mkdir -p "$BACKUP_DIR"

# Create a tar.gz archive of the source directory
tar -czvf "$BACKUP_DEST" "$BACKUP_SOURCE"

echo "Backup created: $BACKUP_DEST"

Make the script executable.

sudo chmod +x /usr/local/bin/backup-script.sh

Now, set up a cron job to run the backup script daily:

sudo crontab -e

Add the following line to run the script every day at 3:00 AM:

0 3 * * * /usr/local/bin/backup-script.sh

Regular Updates

To keep your server secure and stable, it’s crucial to keep it updated with the latest security patches and bug fixes.

  1. Update Packages: Regularly update your system packages:
sudo apt update
sudo apt upgrade
  1. Automated Updates: To automate updates, you can configure unattended upgrades:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure unattended-upgrades
Follow the prompts to configure automatic security updates.

Addressing Security Vulnerabilities

It’s also crucial to address vulnerabilities promptly. Recently, a critical authorization bypass vulnerability, CVE-2025-29927, was identified in Next.js. To mitigate such risks:

  1. Upgrade Next.js: Update to the latest patched version.

    npm install next@latest
    
  2. Filter Headers: Prevent external user requests containing the x-middleware-subrequest header from reaching your Next.js application [10].

  3. Use a Web Application Firewall (WAF): Block requests that contain the x-middleware-subrequest HTTP Header.

Conclusion

Self-hosting your Next.js application from a home lab gives you more control and insight into your deployment process. This detailed guide covered everything from setting up your server and configuring Nginx to securing your application with SSL and automating backups.

By following these steps, you can build a robust, cost-effective, accessible over the internet Next.js hosting solution right in your home.

Leave a Reply