How to create Staging and Production Server in Nginx

Finding resources for setting up Nginx’ staging and production server is either none to nothing or a solution that somehow bloated your server. Looking for resources that allows you to serve both staged and production in the same web server (live domain) is indeed hard to find. In this guide, we will teach you how to achieve it as this is very useful for people who are testing codes or upgrading their webserver with a new version of PHP or MySQL that are not sure if it will not cause an error during live production, as well as for WordPress website which requires you to tweak a domain name before the staging file to work with the production.

Table of Content

  1. Staging directory
  2. Setting up NGINX conf
  3. Testing your Staging and Production Server
  4. Pushing Changes from Staging to Production Server
  5. MySQL and PHP-fpm

This guide will basically use a single server with two different root files, it will only serve the staging server to a specific set of IP addresses and other traffic will be served to the production server.

This sounds a bad idea, but this is very useful for small or solo developer that like to do changes in their server without affecting live traffic in case of an error.

Staging directory

To achieve this, we need to use the map directives and uses two different root directories. Let’s say you already have /var/www as your production directory. We can then use /var/beta as your staging directory.

sudo mkdir /var/beta
sudo chown -R www-data:www-data /var/beta

Then, you can simply copy files of your production to your staging directory. You may also use git tool to push the changes, but in this tutorial we will be using basic.

rsync -r /var/www/ /var/beta

Setting up Nginx Conf

Now that we already have directories for our staging, we can then use the map directive and uses $remote_addr to specify IP address that will be allowed to access the staging server. Make sure to change YOUR_IP_ADDRESS with your public IP address.

map $remote_addr $root_yourserver{
    default /var/www/yourserver;
    YOUR_IP_ADDRESS /var/beta/yourserver;

Then at your server block, simply change the root value to $root_youserver;. Example simple configuration file below.

    listen 80;
    root $root_yourserver;

    index index.php index.html index;

    location /{
        try_files $uri $uri/ /index.php?q=$uri$args;

Then don’t forget to restart your Nginx server.

sudo service nginx restart

Testing your Staging and Production Server

Now that we already setup our staging server and the configuration, let’s test out our server.

But first of all, to check that you’re indeed using the staging server, we can create a simple file to check it.

vim /var/beta/test.html

Then just write some text on it, example “hello from staging server”.

Do the same on production server with content saying “hello from production server”.

vim /var/www/test.html

After that, you can now try opening your server from your browser, example You should see the message you added on the html file when accessing the IP address you specify at the configuration. You can also add as many addresses you want in the map directives.

For live production, you need to access in different IP address, try a VPN or from your neighbor.

Pushing changes from Staging to Production Server

There are other tool to push and pull changes from one to other directory available in the internet. For simplicity, you can still use the rsync function to copy the changes, just make sure to be extra careful on copying files especially for user’s directories.

Example code below will copy all files from beta directory to www directory.

rsync -r /var/beta/ /var/www

MySQL and PHP-fpm Version

If you want to try different latest version of PHP and has no idea if it will create problem on your production server, you can also specify FPM version that will serve to specific addresses.

Using the map directives, you can add a new one for php-fpm.

map $remote_addr $fpm_sock{
    default unix:/var/run/php/php7.4-fpm.sock;
    YOUR_IP_ADDRESS unix:/var/run/php/8.0-fpm.sock;

Then at your server block, simply change the fastcgi_pass value to $fpm_sock;

location ~\.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass $fpm_sock;

For your database, you need create duplicate the database of your production server and simply change the configuration access inside the /var/beta directory. The only thing you need watch out here is that the configuration of your staging directory is not copied over to production. rsync -r /var/beta/ /var/www is a bad idea here, you need to manually copy files or folders.

That’s it guys! Hope this will help you developing your staging and production server for your use.

Leave a Comment

trabzon escort yalova escort Samsun escort izmit escort nazilli escort