Blog
Next

Setup Staging Environment with Nginx

Share your work with clients privately using a password-protected staging site—no code access, no public exposure.

What You'll Have at the End

  • A private URL like staging.yoursite.com where your client can preview the project
  • Password protection so random people can't access it
  • A proper SSL certificate (the padlock icon) so it looks professional
  • Your code stays completely private, they only see the running website

What You'll Need

  • A cheap VPS (DigitalOcean, Hetzner, Hostinger or even your old laptop with public ip)
  • A domain name you own
  • Your project running on the server
  • About 15 minutes

Step 1: Point Your Domain to the Server

First, you need to tell the internet that staging.yoursite.com should go to your VPS. Log into wherever you manage your domain (Cloudflare, Namecheap, GoDaddy, etc.) and add an A record:

TypeNameValue
AstagingYOUR_VPS_IP

Replace YOUR_VPS_IP with your server's IP address (something like 165.232.123.45).

DNS changes can take a few minutes to propagate. You can check if it's working by running ping staging.yoursite.com in your terminal.


Step 2: Install Nginx on Your Server

SSH into your VPS and install Nginx. It's the software that will handle incoming requests and add the password protection:

sudo apt update
sudo apt install nginx -y

Start it up and make sure it runs automatically if your server ever restarts:

sudo systemctl start nginx
sudo systemctl enable nginx

Quick sanity check—make sure it's running:

sudo systemctl status nginx

You should see "active (running)" in green. If you visit your server's IP address in a browser, you'll see the default Nginx welcome page.


Step 3: Create the Login Credentials

This is the magic part—we're creating a username and password that your client will need to enter before seeing the site. Install the tool that creates password files:

sudo apt install apache2-utils -y

Now create the password file. Replace client_name with something memorable (like your client's name or project name):

sudo htpasswd -c /etc/nginx/.htpasswd client_name

You'll be asked to type a password twice. Pick something simple, you'll be sharing this with your client.


Step 4: Configure Nginx to Protect Your Site

Now we tell Nginx: "When someone visits staging.yoursite.com, ask for a password, then show them my app running on port 3000."

Create a new config file:

sudo nano /etc/nginx/sites-available/staging.yoursite.com

Paste this configuration (update the domain and port if needed):

server {
    listen 80;
    server_name staging.yoursite.com;
 
    location / {
        # This is what triggers the password prompt
        auth_basic "Client Preview - Enter credentials to continue";
        auth_basic_user_file /etc/nginx/.htpasswd;
 
        # Forward requests to your app
        proxy_pass http://localhost:3000;
 
        # Keep the original request info intact
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
 
        # Support for WebSockets (needed for hot reload, real-time features)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Save and exit.

What's happening here? When someone visits your staging URL, Nginx intercepts the request. It shows a password prompt first. Only after they enter the correct credentials does it forward them to your actual application.


Step 5: Activate the Configuration

Enable your new site by linking it to the sites-enabled folder:

sudo ln -s /etc/nginx/sites-available/staging.yoursite.com /etc/nginx/sites-enabled/

Before reloading, always test your config for typos:

sudo nginx -t

If it says "syntax is ok", you're good. Apply the changes:

sudo systemctl reload nginx

Test it! Open http://staging.yoursite.com in your browser. You should see a password prompt. Enter the credentials you created, and boom—your app appears.

If you see the default Nginx page instead of your app, make sure your application is actually running on port 3000 (or whatever port you configured).


Step 6: Add SSL (The Padlock Icon)

Right now it works, but your client will see a "Not Secure" warning in their browser. Not a great look. Let's fix that with a free SSL certificate from Let's Encrypt.

Install Certbot:

sudo apt install certbot python3-certbot-nginx -y

Get your certificate (this is almost magical one command does everything):

sudo certbot --nginx -d staging.yoursite.com

Follow the prompts. Certbot will automatically:

  1. Verify you own the domain
  2. Get a certificate
  3. Update your Nginx config to use HTTPS
  4. Redirect HTTP to HTTPS

That's it. Visit https://staging.yoursite.com and you'll see the padlock. Your client will never know the difference between this and a "real" production site.

Let's Encrypt certificates expire after 90 days, but Certbot automatically renews them. You don't have to think about it.


Send It to Your Client

You're done! Here's what you can send your client:

Hey! I've set up a preview site for your project. You can check out the progress anytime at:

URL: https://staging.yoursite.com
Username: client_name
Password: preview2024

Feel free to click around and let me know if you have any feedback!

This is so much more professional than "hop on a call and I'll share my screen" or "check out this weird Vercel URL."