← Back to Blogs
HN Story

Self-Hosting a Node.js Website on a Raspberry Pi

May 9, 2026

Self-Hosting a Node.js Website on a Raspberry Pi

For many developers, the allure of self-hosting is not just about cost, but about control. While platforms like Vercel or Netlify offer seamless deployment, there are times when specific technical requirements—such as the need for a legacy dynamic library or a preference for total environment ownership—make a home server the better choice.

Using a Raspberry Pi as a web server is an excellent way to learn the intricacies of networking, server management, and deployment pipelines. This guide outlines a streamlined process for hosting a Node.js-based website (such as one built with Astro or Svelte) on a Raspberry Pi.

The Architecture: From Router to Browser

To make a website accessible to the world from a home network, you must bridge the gap between your local private IP and your public-facing IP address.

1. Port Forwarding and Reverse Proxying

The first step is configuring your router to forward incoming traffic to the specific internal IP address of your Raspberry Pi. Because router interfaces vary widely, this step requires checking your specific hardware's documentation.

Once the traffic reaches the Pi, you need a way to handle requests and manage SSL certificates. Caddy is a highly recommended tool for this because it handles HTTPS automatically. A typical Caddyfile configuration for an Astro site looks like this:

m4rt.nl {
    root * /home/mart/Documents/m4rt.nl
    file_server
    reverse_proxy localhost:4321
}

In this setup, Caddy serves static files directly and proxies requests to the Node.js process running on port 4321.

2. DNS Configuration

After setting up the server, you must point your domain to your home network. This is done by adding an A Record in your DNS provider's settings, mapping your domain (e.g., yoursite.com) to the public IP address provided by your ISP.

Managing the Application Lifecycle

Running a build script manually every time you make a change is inefficient. To create a production-ready environment, you need a process manager and a deployment pipeline.

Using PM2 for Process Management

When deploying a Node.js app, you cannot simply run the start command in a terminal session, as the process will terminate when the session closes. PM2 is a production process manager that keeps applications alive in the background and restarts them if they crash.

After running npm run build, you can launch your entry point using: pm2 run entry.mjs

Automating Deployment with GitHub Actions

To mimic the "push-to-deploy" experience of modern cloud platforms, you can implement a CI/CD pipeline using GitHub Actions. By creating a workflow file (e.g., .github/workflows/update_server.yml), you can trigger a remote update via SSH every time you push code to your repository.

Using the appleboy/ssh-action, the workflow can securely connect to the Pi using secrets for the host IP and password, then execute a local shell script to handle the updates.

The Update Script

A robust update script should handle multiple projects and ensure the latest code is pulled and built. A sample logic for such a script includes:

  1. Iterating through directories in a base folder.
  2. Checking for the presence of a .git folder to perform a git pull.
  3. Identifying Node.js projects via package.json and running the build command with a specific port.
  4. Restarting all PM2 processes to apply the changes.

Security Considerations and Alternatives

While port forwarding is the quickest way to get a site live, it exposes a port on your home network to the public internet, which can introduce security risks.

As noted by community members in the discussion surrounding this setup, poking holes in a home firewall can be risky. A more secure alternative is using a Cloudflare Tunnel. Tunnels create a secure, outbound-only connection between your server and the Cloudflare network, removing the need to open ports on your router and hiding your home's public IP address from the public.

By combining a Raspberry Pi with tools like Caddy, PM2, and GitHub Actions, developers can build a fully automated, professional-grade hosting environment right from their living room.

References

HN Stories