1. Home
  2. cPanel
  3. 4 steps to create and use Dev and Test environments in cPanel for Drupal
  1. Home
  2. Drupal
  3. 4 steps to create and use Dev and Test environments in cPanel for Drupal

4 steps to create and use Dev and Test environments in cPanel for Drupal

This article helps our cPanel customers running single-site Drupal 7 or Drupal 8 setting up additional test environments, for example Dev and UAT. Dev environment cPanel Drupal. This article assumes basic knowledge of bash and using SSH to login to our cPanel server

Using cPanel as an agency or a corporate client has many challenges. One of such challenges is difficulty to use cPanel for testing and UAT purposes. In this article we cover steps required to setup dev and UAT environments in cPanel, and steps to use those environments with Drupal 7 and Drupal 8.

Setup overview & prerequisites

  • Requires one fully setup cPanel account with RedyHost. Some of configuration options listed are unique to RedyHost, please submit a comment if you find any issues executing the steps listed with another hosting provider.
  • Using multiple environments in sub-folder, siblings to the public_html web root folder
  • Dedicated settings.php file per environment. Adding settings.php files into .gitignore if you use git is required to avoid overriding the files
  • Creating and using drush aliases to synchronise environments.
  • This setup does not support Redis as cache environment. Consider using memcache_storage or memcache Drupal modules.

Dev environment cPanel Drupal

To configure UAT and any other websites we will be using cPanel’s subdomain functionality. This assumes that you have an active cPanel account and working Drupal website, which will be referred as Prod environment from this point.

1. Create cPanel Subdomains

1.1 Login to cPanel and create subdomains.

For example ‘dev.yoursite.com’ and ‘uat.yoursite.com’. Point these domains to folders in home directory (these folders will be created for you and should not exist before doing this step). The intended folder layout that we will use in the rest of our example is:

~/public_html/ # Main website web root
~/dev/ # Dev environment folder. This will be created when you add the `dev.` subdomain via cPanel
~/uat/ # UAT environment folder. Will be created when you add the `uat.` subdomain via cPanel
~/backups/ # Folder to store database backups

1.2 At this point SSH into your cPanel account.

Ensure permissions of the ~/dev/ and ~/uat/ folders are set to 755

chmod 0755 ~/dev
chmod 0755 ~/uat

1.3 Create remaining required folders

mkdir ~/backups

1.4 Created databases

Using cPanel’s MySQL database functionality, create one empty database for each environment. You may name the databases as dev and uat for easy recognition. The full database name will be in the following format: [cpanel_username]_dev and [cpanel_username]_uat

It is important to ensure that your production Drupal website is fully configured and running with no issues. If you have any issues in your production environment, resolve them before moving any further.

2. Create Drupal drush aliases in cPanel

Drush aliases allow to easily use drush with no path dependency. Any drush command could be executed from any path or any environment.

To setup drush aliases, create file ~/.drush/yoursite.aliases.drushrc.php and add the following content. Modify a) site URL and b) path to the web root. Look for the fixme text and replace accordingly.

 * @file fixme.aliases.drushrc.php
 * Usage:
 *   To copy the development database to your local site:
 *   $ drush sql-sync @yoursite.dev @yoursite.local

 * Development alias
 * Set up each entry to suit your site configuration
$aliases['dev'] = array (
  'uri' => 'dev.fixme.com.au',
  'root' => '/home/fixme/dev',
  'path-aliases' => array(
    '%drush' => '/usr/bin',
    '%site' => 'sites/default/',
    '%dump-dir' => '/home/fixme/backups',
  'source-command-specific' => array (
    'sql-sync' => array (
      'no-cache' => TRUE,
      'structure-tables-key' => 'common',
  'command-specific' => array (
    'sql-sync' => array (
      'sanitize' => TRUE,
      'no-ordered-dump' => TRUE,
      'structure-tables' => array(
       // You can add more tables which contain data to be 
       // ​ignored by the database dump.
        'common' => array('cache', 'cache_filter', 'cache_menu', 'cache_page', 'history', 'sessions', 'watchdog'),

 * UAT alias
 * Set each option to match your configuration
$aliases['uat'] = array (
  'uri' => 'uat.fixme.com.au',
  'root' => '/home/fixme/uat',
  'parent' => '@dev',

 * Production alias
 * Set each option to match your configuration
$aliases['prod'] = array (
  'uri' => 'fixme.com.au',
  'root' => '/home/fixme/public_html',
  'parent' => '@dev',

2.1 Testing drush aliases

To view your new site aliases, use the command any time

drush sa


3. Drupal preparation in cPanel Production

Our configuration setup will require a couple of Drupal modules to be installed in Dev and UAT environment (stage_file_proxy and shield), so let’s download them now into your production website.

drush @yoursite.prod dl stage_file_proxy -y
drush @yoursite.prod dl shield -y

4. Synchronising sites with Drush: Prod to Dev, Prod to UAT

Here and further we will be using Dev environment for commands example. If you require more than a single Dev environment, repeat steps for each environment.

Next, let’s sync files and database from our Prod environment to our Dev environment (configured in ~/dev folder).

4.1 Update settings.php in cPanel Prod

Modify your Production settings.php file to include variables for shield module to avoid username/password to appear for your Prod website. Place this code at the bottom of the settings.php file. We assume your settings.php file is stored in default location sites/default/. If it is stored elsewhere, modify the path to the Drupal root accordingly.

// Disable Shield module authentication for production.
// The environmental include files will override this setting.
$conf['shield_user'] = ''; 
$conf['shield_pass'] = '';

4.2 Synchronise files in cPanel (first time only)

Navigate to the home folder and synchronise files. We explicitly include the --include-conf option so that the settings.php file is also synchronised. However this should only be used once during the initial setup. See usage examples below for ongoing file and database synchronisation.

We will skip copying media assets (file uploads and images) by adding --exclude-files option. Instead of duplicating these files, we recommend to use stage_file_proxy module to load these from your production environment. The Drupal’s public files folder have to exists so that Drupal can store caches, we will create this folder for both environments below.

cd ~
chmod u+w ~/dev/sites/default
chmod u+w ~/uat/sites/default
mkdir ~/dev/sites/default/files
mkdir ~/uat/sites/default/files
chmod a-w ~/dev/sites/default 
chmod a-w ~/uat/sites/default
drush rsync @yoursite.prod @yoursite.dev --include-conf --exclude-files
drush rsync @yoursite.prod @yoursite.uat --include-conf --exclude-files
Please note that using rsync does not provide any means of reverting the state of your files back (in the case when something goes wrong). We strongly recommend to use git based deployments instead of rsync, or use external Git-based deployment systems such as http://springloops.io. By adding your website to git you get an ability to easily view the changed files and revert them back to any previous commit.

4.2 Update settings.php for Dev and UAT environments.

We need to update database configuration and disable production caches in our new Dev and UAT environments. Following our folder structure, the settings.php file was copied via the step above into the following locations:

  • Dev: ~/dev/sites/default/settings.php
  • UAT: ~/uat/sites/default/settings.php
chmod u+w ~/dev/sites/default/settings.php
nano ~/dev/sites/default/settings.php

4.2.1 Locate your $database variable and modify database credentials and database name

The database variable looks like this:

$databases = array (
  'default' =>
  array (
    'default' =>
    array (
      'database' => 'name',
      'username' => 'user',
      'password' => 'password',
      'host' => 'localhost',
      'port' => '',
      'driver' => 'mysql',
      'prefix' => '',

4.2.2 Add cache overrides

Go to the bottom of this settings.php file and add the following code to disable caches and set shield module username and password

$domain = 'yoursite.com';
$env = 'dev';

// For UAT environment, replace 'dev' with 'uat', assuming your // subdomain is 'uat.'
// $env = 'uat';
$protocol = 'http://';
$cookie_domain = $env . '.' . $domain;
$base_url = $protocol . $cookie_domain;

// Unset any cache backends (such as memcache_storage) for dev environment.
// You may want to skip these lines below for your UAT environment.
// In the example below we use memcache_storage module. If you prefer to use
// the memcache module instead, please refer to the related readme file for
// installation and configuration steps. The values are commented out to
// avoid breaking sites with no memcache_storage module installed.
// $conf['memcache_extension'] = 'Memcached';
// $conf['cache_backends'][] = 'sites/all/modules/memcache_storage/memcache_storage.inc';
// $conf['cache_default_class'] = 'MemcacheStorage';
// $conf['cache_class_cache_form'] = 'DrupalDatabaseCache';
// $conf['cache_class_cache_update'] = 'DrupalDatabaseCache';
// $conf['page_cache_without_database'] = TRUE;
// $conf['page_cache_invoke_hooks'] = FALSE;
// $conf['memcache_key_prefix'] = 'Some_Unique_Secure_key_string';
// $conf['memcache_storage_key_prefix'] = 'Some_Unique_Secure_key_string';
// # Move storage for lock system into memcached.
// $conf['lock_inc'] = 'sites/all/modules/memcache_storage/includes/lock.inc';
// # Move storage for sessions into memcached.
// $conf['session_inc'] = 'sites/all/modules/memcache_storage/includes/session.inc';

// Files path.
$conf['file_private_path'] = 'sites/default/files';
$conf['file_temporary_path'] = '/tmp';

// Tell stage_file_proxy module to load file uploads from Production site.
$conf['stage_file_proxy_origin'] = $protocol . $domain . '/';

ini_set('display_errors', 1);

// Protect your dev/uat environment with username/password
// to prevent anyone looking at them and to keep search engines away.
// Shield module (must be installed) username/password:
$conf['shield_user'] = 'simpleuser';
$conf['shield_pass'] = 'simplepassword'; 

Repeat the steps 4.2, 4.2.1 and 4.2.2 for the UAT environment. You may want to skip unsetting the cache configuration variables for UAT environment.

4.2.3 Remove write permission from settings.php file

chmod -f a-w ~/dev/sites/default/settings.php
chmod -f a-w ~/uat/sites/default/settings.php

4.3 Test database configuration

Note! Before executing any drush commands, ensure the drush aliases use the right database. To test it, run
drush @yoursite.prod status

and confirm the Database name is the expected for your environment.

Repeat this step for Dev and UAT.

drush @yoursite.dev status
drush @yoursite.uat status

4.5 Synchronise database in cPanel with drush

Database could be synchronised in 2 ways:

  1. drush sql-sync
  2. manual store source database and import into the destination environment.

4.5.1 Using drush to synchronise databases (from Prod to Dev)

drush sql-sync @yoursite.prod @yoursite.dev
drush sql-sync @yoursite.prod @yoursite.uat

If this step worked, skip to the step 4.6

4.5.2 Using manual steps when the above fails

Create DB backup in Production environment. In our scenario, the database dump will be stored in ~/backups/ folder.

The below example creates full database dump. For any future database dumps (re-sync purpose) you may skip the cache tables by listing them with parameter --skip-tables-list=cache,cache_views etc.

For Drupal 7, you may pass the following table names to skip: --skip-tables-list=cache,cache_filter,cache_menu,cache_page,history,sessions,watchdog

For Drupal 8, you may pass the following table names to skip: --skip-tables-list=cache,cachebootstrap,cacheconfig,cachecontainer,cachedata,cachedefault,cachediscovery,cachefilter,cachemenu,cachepage,history,searchindex,sessions,watchdog

For full database dump (first time synchronisation)
drush @yoursite.prod sql-dump --result-file=~/backups/database-prod.sql
For partial database dump (skipping cache tables, Drupal 7):
rm -f ~/backups/database-prod.sql

drush @yoursite.prod sql-dump --skip-tables-list=cache,cache_filter,cache_menu,cache_page,history,sessions,watchdog --result-file=~/backups/database-prod.sql
For partial database dump (skipping cache tables, Drupal 8):
rm -f ~/backups/database-prod.sql

drush @yoursite.prod sql-dump --skip-tables-list=cache,cachebootstrap,cacheconfig,cachecontainer,cachedata,cachedefault,cachediscovery,cachefilter,cachemenu,cachepage,history,searchindex,sessions,watchdog --result-file=~/backups/database-prod.sql
Import the database in cPanel with drush

Importing the database dump into our Dev environment.

drush @yoursite.dev sql-drop

drush @yoursite.dev sql-cli < ~/backups/database-prod.sql

4.6 Enable development modules in cPanel

drush @yoursite.dev en stage_file_proxy
drush @yoursite.dev en shield

drush @yoursite.uat en stage_file_proxy
drush @yoursite.uat en shield

Drupal 7: Disable any cache modules that you have in production

drush @yoursite.dev dis memcache memcache_storage

Drupal 8: Disable any cache modules that you have in production

drush @yoursite.dev pmu memcache memcache_storage

5 Using drush aliases in Dev and UAT environments

Synchronising files with drush in cPanel

To sync files from Prod to Dev

drush rsync @yoursite.prod @yoursite.dev --exclude-files

To sync files from Prod to UAT

drush rsync @yoursite.prod @yoursite.uat --exclude-files

To sync files from UAT to Prod

We recommend to use git based deployment to production environment instead of doing rsync. If you proceed with this steps, make sure you have full backup of your production website files and the database.
drush rsync @yoursite.prod @yoursite.uat --exclude-files

Synchronising databases with drush in cPanel

To sync Drupal database from Prod to Dev environments

Drupal 7

drush sql-sync @yoursite.prod @yoursite.dev --skip-tables-list=cache,cache_filter,cache_menu,cache_page,history,sessions,watchdog

Drupal 8

drush sql-sync @yoursite.prod @yoursite.dev --skip-tables-list=cache,cachebootstrap,cacheconfig,cachecontainer,cachedata,cachedefault,cachediscovery,cachefilter,cachemenu,cachepage,history,searchindex,sessions,watchdog

To sync Drupal database from Prod to UAT environments

Drupal 7

drush sql-sync @yoursite.prod @yoursite.uat --skip-tables-list=cache,cache_filter,cache_menu,cache_page,history,sessions,watchdog

Drupal 8

drush sql-sync @yoursite.prod @yoursite.uat --skip-tables-list=cache,cachebootstrap,cacheconfig,cachecontainer,cachedata,cachedefault,cachediscovery,cachefilter,cachemenu,cachepage,history,searchindex,sessions,watchdog

To sync Drupal database from UAT to Prod environments


RedyHost recommends to export any structural changes into features (Drupal 7) or configuration (Drupal 8) instead of database synchronisation. Before running this command make sure you have backup of your database.

Drupal 7
drush sql-sync @yoursite.uat @yoursite.prod --skip-tables-list=cache,cache_filter,cache_menu,cache_page,history,sessions,watchdog
Drupal 8
drush sql-sync @yoursite.uat @yoursite.prod --skip-tables-list=cache,cachebootstrap,cacheconfig,cachecontainer,cachedata,cachedefault,cachediscovery,cachefilter,cachemenu,cachepage,history,searchindex,sessions,watchdog

Send us your feedback for Dev environment cPanel Drupal if you find any issues with these steps.


Updated on 7 June, 2017

Was this article helpful?

Related Articles