Drupal migration from production to local testing server

Drupal Gears

You might have to export a Drupal based website to a local development computer in order to test new modules, make important changes or just because under no circumstances you can stop your production server.

Drupal documentation should be the path to follow, but it is too generic and does not take in consideration some particular cases. For that reason in this post, I am going to describe the process of exporting a Drupal 8 Website under a real domain name with HTTPS support, to a local testing server with no HTTPS in a localhost folder. In this link you will find the official Drupal documentation: https://www.drupal.org/docs/7/backing-up-and-migrating-a-site/migrating-a-site

Remote Server Tasks

Activate maintenance mode

In this step we will prevent anyone from using our web, apart from avoiding any unintentional database or cache modification. To do so we will go to Configuration->Development->Maintenance Mode and will disable the site.

Delete Drupal Cache

This step is compulsory if we want our database installed in a different domain to work, as It will be full with the current domain information. You will find the cache cleaning form in Configuration->Development->Performance.

In case the cleaning process does not work properly I will describe how to remove the cache content manually once exported the database to the new server.

Create a Database Backup

If the web is located in a hosting service, you should have access to create a database dump from you hosting control panel like Cpanel, Plesk, phpMyAdmin .. The export process is not this post reason so that I will leave it with you.

Once the database dump is done, download it to your computer.

Copy web content

As you did with the Database, the quickest way to create a copy of de web content would be from your domain control panel (CPanel, Plesk), go to the File Manager, select the root folder (maybe htdocs), compress and download it. 

Getting you local server ready

In this case, our local server has Apache installed in it with no virtualhosts, so that the base access URL would be something like: http://localhost/test.

The default Ubuntu 18.04 Linux installation (Other distros should be similar) the Apache server root folder is located in /var/www/html. As we would like to install our website in the root folder we will create a folder like /var/www/html/test and will put the backup of our files there.

Restoring the Database backup locally

The easiest way to import a MySql database dump is by using a Database Management System like phpMyAdmin even if to be honest phpMyAdmin is too heavy to me and usually I use a lighter client that allows me to perform all basic operations quickly. This management system is called Adminer and comprises one single php file that you can drop in your web server document root and that is it (you need php at least). In addition it also supports some other database systems like SQLite. You can download it from: https://www.adminer.org

Adminer Login

1 - Create an empty database.

We log into Adminer and create a database called "drupal_db". Keep in mind that the database name does no need to match the original name, as we will change it from the Drupal file "settings.php" later, to set up the local database connection string and other important values. We do have to respect the collation from the original database otherwise we could see some extrange characters in our texts.

Adminer Create BD

2- Import the Database Dump

Adminer tool offers 3 options to perform the import.

  1. Using a raw text format dump *.sql (file < 2MB)
  2. Using a compressed dump *.tar.gz (file < 2MB)
  3. Rename our dump to "adminer.sql" (uncompressed) and move it to the same folder where "adminer.php" is located in the document root.

The only valid option in this case is the third one as a basic Drupal database dump file would be over 5MB.

Adminer Import

It will take the import process some seconds to finish after pressing the button "Run File". Once it is done we can move on to the next step.

Copy web files in the Web Server Directory.

Uncompress the copy of your web files and copy the content (with no htdocs or html folder) in the folder we created previously. "/var/www/html/test"

Adjusting localhost configuration.

This step depends on the remote server and local server configuration. In this case we will need to change  some settings in two of the files in our Drupal installation "/sites/default/settings.php" and "/.htaccess", due to the fact that we want to revert the next parameters:

1 - Move a real domain name like www.mydomain.com to a local domain (no domain) -> /localhost/test

The standard way of changing the URL in Drupal 8 is through the main config file "mysite/sites/default/settings.php" that contains Drupal basic configuration parameters. For security reasons the old parameter $base_url was removed in favour of "$settings['trusted_host_patterns']" that filters the allowed URL by a list of regular expressions to prevent http header attacks.

The next configuration is recommended in a real domain.


$settings['trusted_host_patterns'] = [
   '^mydomain\.com$',
   '^www\.mydomain\.com$',
];

In localhost environment  (no application folder needed):

$settings['trusted_host_patterns'] = [ '^localhost$', ];

2 - Change the configuration of the database. 

Connection string is also located in "settings.php". Change values in case they are different.


$databases['default']['default'] = array (
  'database' => 'drupal_db',
  'username' => 'user',
  'password' => 'password',
  'prefix' => '',
  'host' => 'localhost',
  'port' => '3306',
  'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
  'driver' => 'mysql',
);

3 - Remove the real domain HTTPS configuration to work in HTTP mode.

In case we have SSL enabled in our production server, we will have to remove the lines that allow us to redirect HTTP to HTTPS in .htaccess file.


# RewriteCond %{HTTPS} off
# RewriteCond %{HTTP:X-Forwarded-Proto} !https
# RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Troubleshooting

If everything was right, you should be able to open "/localhost/test" and see your webpage running in maintenance mode, but the process is not always so easy, and you might have to tweak some other stuff:

1 - Erase database Drupal 8 cache. If your page does not work yet and you cannot log into your backoffice, the first option you have is to remove the database cache manually, by executing the SQL commands in you Database Management System.


TRUNCATE cache_config;
TRUNCATE cache_container;
TRUNCATE cache_data;
TRUNCATE cache_default;
TRUNCATE cache_discovery;
TRUNCATE cache_dynamic_page_cache;
TRUNCATE cache_entity;
TRUNCATE cache_menu;
TRUNCATE cache_render;
TRUNCATE cache_toolbar;

2 - "/var/www/html/test" permission.

Under Linux "/var/www/html" will have user = "root" and group = "root" so that, if we copied the files using "sudo", they inherited the user and group.

Drupal can optimise and compress *.css and *.js files that need to be rewritten using Apache default group "www-data", but  according the root::root permission, javascript and stylesheet will fail to load. This is why I recommend that you change your app folder default group to "www-data".


cd /var/www/html
sudo chgrp -R www-data test

Conclusion

If you keep on facing some issues and you can at least log into the backoffice, I recommend that you increase the verbosity of error messages from Configuration->Development->Logging and errors. This way I assure that you will find the problem.

Remind that if you want to upload a local installation to a production server you will have to do the opposite operations.


I hope you find this post useful.

Tags