Bash Script: Easily Backup your Magento2 Code Files + Database

October 2, 2017  |  No Comments  |  by Raj (MagePsycho)  |  Linux, Mac OS-X, Magento 2

We had created a similar Backup Script for Magento1 in the past. Now we are back with the much-improvised version for Magento2.
You must be wondering why we needed a bash script for Magento2 backup even it comes up with inbuilt console command:

php /path/to/magento2/bin/magento setup:backup -v --code --media --db

Some of the reasons are:

  • Linux native command is always faster than PHP.
  • There is no enabling and disabling of maintenance mode while running the backup script. So there is no any downtime.
  • To have more Freedom. Magento2 console script is limited. What if you want to backup in Amazon S3, Google Drive etc.? If you have independent script you can play as you like without worrying about breaking the Magento2 system.

You can find the full script below:

Please visit our GitHub project page for more info: MagePsycho/magento2-db-code-backup-bash-script

Installation

You can simply download the script file and give the executable permission.
In Linux system this can be simply done as:

cd /path/to/your/preferred/download/folder
curl -O mage2-backup.sh https://raw.githubusercontent.com/MagePsycho/magento2-db-code-backup-bash-script/master/src/mage2-db-code-backup.sh
chmod +x mage2-backup.sh

If you want to make this command system-wide then

sudo mv mage2-backup.sh /usr/local/bin/mage2-backup.sh

Usage

To display help

./mage2-backup.sh --help

mage2-backup-script-help

To backup database only

./mage2-backup.sh --type=db --src-dir=/path/to/magento2/root --dest-dir=/path/to/destination

To backup code only

./mage2-backup.sh --type=code --skip-media=1 --src-dir=/path/to/magento2/root --dest-dir=/path/to/destination

To backup code + database

./mage2-backup.sh --type=all --skip-media=1 --src-dir=/path/to/magento2/root --dest-dir=/path/to/destination

To schedule backup via Cron
You can run this command manually (on demand) or via cron.
If you want to schedule via Cron, just add the following line in your Crontab entry (crontab -e)

0 0 * * * /path/to/mage2-backup.sh --type=all --skip-media=1 --src-dir=/path/to/magento2/root --dest-dir=/path/to/destination > /dev/null 2>&1

0 0 * * * expression means the command will run run at every midnight. You can refer to https://crontab.guru/ to know more about the cron-expression.

Hope you will find this script useful in your day-to-day operation. Any issues found can be raised at our GitHub project – Bash Script: Backup Magento2 Code + Database

Let us know your experience/feedback on this script.

Bash Script: Create MySQL Database & User with Optional Password

January 3, 2017  |  No Comments  |  by Raj (MagePsycho)  |  Linux, Mysql

I have been using DigitalOcean for my personal projects. And one repeated things that I had to do is the creation of MySQL database & user. I know I could have used some CPanel like GUIs and even some of them came to my mind like VestaCP, Ajenti, ServerPilot etc. But all comes with sort of things and not so developer friendly.

So I decided to create a simple bash script that can simply the database & user.

Bash Script Code

You can find the script at Gist:

How to use?

1# Download
Download the script from Gist – Bash Script: Create MySQL Database & User

2# Set Permission
You need to set the executable permission in order to execute the shell script:

chmod +x mysql-create-db-user.sh

3# Usage
Use the script as:

./mysql-create-db-user.sh [--host="<host-name>"] --database="<db-name>" [--user="<db-user>"] [--pass="<user-password>"]

So the only required parameter is database name. In the case of empty values for other parameters:

  • ‘host’ becomes localhost
  • ‘user’ takes value from database name
  • ‘password’ is randomly generated

For the following command:

./mysql-create-db-user.sh --database=bash_db2

The output looks like:

Bash Script: Create MySQL Database & User with Optional Password

Bash Script Console: Create MySQL Database & User with Optional Password

Hope you find this script useful.
Please do let us know any feedback in the comments below.

Sandbox script for quick testing in Magento2

September 14, 2016  |  No Comments  |  by Raj (MagePsycho)  |  Linux, Mac OS-X, Magento 2

What’s your approach for quick & dirty testing in Magento2?

  • Creating a test module with a controller and executing it from browser to see the output?
  • Creating a Console module and executing via CLI?

Obviously, above two approaches takes time.

Rather I would create a simple script (a single file) and put it somewhere in /[path-to-magento2]/pub/sandbox.php

<?php
/**
 * @author Raj KB<magepsycho@gmail.com>
 * @website http://www.magepsycho.com
 */
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require __DIR__ . '/../app/bootstrap.php';
$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);
$obj = $bootstrap->getObjectManager();
$state = $obj->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');

// Your quick and dirty code goes here...
$quote = $obj->get('Magento\Checkout\Model\Session')->getQuote()->load(1);
Zend_Debug::dump($quote->getOrigData());

Now you can easily test by pointing to URL
http://[magento2-url]/sandbox.php

But wait, this won’t work in the case when you are using Nginx + PHP-FPM server.
The reason you can explore from the Nginx conf file: [path/to/magento2]/nginx.conf.sample

...
# PHP entry point for main application
location ~ (index|get|static|report|404|503)\.php$ {
    try_files $uri =404;
    fastcgi_pass   fastcgi_backend;
    fastcgi_buffers 1024 4k;

    fastcgi_param  PHP_FLAG  "session.auto_start=off \n suhosin.session.cryptua=off";
    fastcgi_param  PHP_VALUE "memory_limit=768M \n max_execution_time=600";
    fastcgi_read_timeout 600s;
    fastcgi_connect_timeout 600s;

    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
}
...

As you can see only PHP files: index.php, get.php, static.php, report.php, 404.php & 503.php files are parsed by the PHP-FPM.

In order to include your sandbox.php in the whitelist, just edit the line of Nginx conf file:

location ~ (index|get|static|report|404|503)\.php$ {

to

location ~ (index|get|static|report|404|503|sandbox)\.php$ {

And don’t forget to reload or restart your Nginx server depending upon your Operating System.
Ubuntu

sudo service nginx reload
sudo service nginx restart

MacOSx

sudo nginx -s reload
sudo nginx -s stop && sudo nginx

What’s your approach for quick & dirty testing in Magento2? Please do comment below.

MySQL Issue: Table storage engine for ‘catalog_product_relation’ doesn’t have this option

July 30, 2016  |  1 Comments  |  by Raj (MagePsycho)  |  Linux, Mac OS-X, Magento, Mysql

When you export the Magento database dump from MySQL 5.5.x and try to import in MySQL 5.7.x, You are likely to face an error:

ERROR 1031 (HY000) at line 3002: Table storage engine for ‘catalog_product_relation’ doesn’t have this option

PROBLEM

This is probably due to the table option that you have in your CREATE TABLE DDL: ROW_FORMAT=FIXED

Let’s check if there is any such string in the SQL dump (Ex: magento-db-dump.sql).

cat magento-db-dump.sql | grep '=FIXED'

Which resulted as:

) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Catalog Product Relation Table';
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Catalog Product To Website Linkage Table';

Refer – MySQL Row Format Option

SOLUTION

Removing ROW_FORMAT=FIXED option from CREATE TABLE DDL will fix the issue.
So let’s try possible solutions.

#1

sed -i 's/ROW_FORMAT=FIXED//g' magento-db-dump.sql

This didn’t work for me in MacOSx which resulted in following error:

sed: 1: “magento-db-dump.sql”: invalid command code m

#2

sed -i '' 's/ROW_FORMAT=FIXED//g' magento-db-dump.sql

And even this resulted as:

sed: RE error: illegal byte sequence

#3
But this one worked for me in MacOSx (Refer Mac OS X, Sed, and strange document encoding to know more about the issue)

LC_ALL=C sed -i '' 's/ROW_FORMAT=FIXED//g' magento-db-dump.sql

Re-check if the string has been removed or not:

cat magento-db-dump.sql | grep '=FIXED'

If the string is removed, now try to import as:

mysql -u <user> -p <db-name> < magento-db-dump.sql

Yay! Now it imported successfully.
Please do share and care if you liked this article.

Cheers!

Install Bash Completion for Mac OS-X

May 22, 2016  |  No Comments  |  by Raj (MagePsycho)  |  Linux, Mac OS-X

One of the nicest features of the modern shell is the built in “completion” support. This allows you to complete commands and their arguments easily without memorizing.

Unfortunately, Mac OS-X bash shell doesn’t have completion feature by default unlike Ubuntu(Debian based Linux OS).
But the good thing is you can easily install the auto completion by using Homebrew or Macports.

Homebrew being my favourite packaging tool for OS-X, I will be explaining the installation using this tool.

Bash Completion Installation

1. Install bash-completion package using brew

brew install bash-completion

Brew Bash Completion

2. Edit the ~/.bash_profile

vi ~/.bash_profile

And add the following code:

if [ -f $(brew --prefix)/etc/bash_completion ]; then
    . $(brew --prefix)/etc/bash_completion
fi

3. Reload the bash shell

source ~/.bash_profile

Now try to type few letters of command and press [TAB], you will see the auto-completed command or auto-suggested commands(for more than one matches). For example:
nets[TAB] ->

netstat

net[TAB] ->

net-server               net-server5.18           net-snmp-config
net-server5.16           net-snmp-cert            net-snmp-create-v3-user

Bonus

You can also install additional completions from Homebrew-Completions
All you have to do is:

brew tap homebrew/completions
brew install <formula>

If you know how to create bash completions, you can create your own file and drop in the folder:

/usr/local/etc/bash_completion.d

After sourcing(loading) it, your custom completion is ready to take into account.

Please do share/comment on your favourite bash-completion.