Building an eCommerce Site with Drupal Commerce
I started this journey because the eCommerce site we built with OpenCart 3 was too slow and we needed a better alternative. These are my experiences.
In the world of Agile, we need to level-set and define the problem upfront. I tried the quickstart package and it was too old, I tried the basic install and it was too complicated, finally, I am trying the demo project.
Security Advisory: On a production system, the operating system should be hardened to CIS Level 1 and require at least 2FA (google-authenticator). If you store any privacy or customer data, the system needs to be TLS 1.2 only, secure headers, and have data at rest encryption. I would also recommend automatic security updates for the operating system.
To create our development platform, I chose Oracle’s Virtualbox and Ubuntu 18.04 LTS. The LTS version of the support is Long Term Supported. This is the recommended version for any production application.
Due to the fact that we are creating a virtual machine, we will need to add the guest additions at the end of the standard installation.
Virtual Hardware Config:
CPU = 4
RAM = 4096
HDD = 100G (dynamically sized)
VIDEO = VBoxSVGA
NETWORK = Bridged (so you can ssh/sftp to it)Shared Folders: I share my downloads folder for easy access to software. It is optional. Set to automount
Installation Notes:
Only MySQL 5.7 is supported by Drupal 8. Only the old password style is supported. Drupal uses MySQL PDO driver (because PDO unlike MySQLi supports both PostgreSQL and MySQL).I prefer Percono mySQL for performance.
Guest Additions
After the basic installation, we need to add the guest add-ons and update the patches. I have also found that VirtualBox can fail if you insert the guest’s cd additions. For best results attach the ISO before starting the VM.
sudo apt update
sudo apt upgrade -y
sudo apt install zip unzip curl wget -y
sudo mount -t iso9660 /dev/sr0 /mnt
sudo apt install -y gcc make perl linux-headers-generic
sudo sh /mnt/VBoxLinuxAdditions.run"VirtualBox Guest Additions: Running kernel modules will not be replaced until the system is restarted"reboot
Apache Installation
apt install apache2 -y
We will configure apache after all of the software is installed.
PHP: Installation
At this time, Ubuntu 18.04.03 LTS distribution contains PHP 7.2.
Drupal 8 Requirements can be found here.
apt installphp -y
apt install php7.2-bcmathphp7.2-bz2 php7.2-bz2 php7.2-cgi \
php7.2-cli php7.2-common php7.2-curl php7.2-dev php7.2-enchant \
php7.2-fpm php7.2-gd php7.2-json php7.2-mbstring php7.2-opcache \
php7.2-mysql php7.2-pspell php7.2-readline php7.2-tidy php7.2-xml \
php7.2-zip -y
MySQL (Percona Installation)
I prefer the Percona version. However, any MySQL 5.7 distribution will work the same.
wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.debsudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.debpercona-release setup ps57
apt install percona-server-server
Create a user and a database for the project
mysql -u root -pMySecurePasswordcreate database commerce;CREATE USER 'app_commerce'@'localhost' IDENTIFIED BY 'mysql -';CREATE USER 'app_commerce'@'%' IDENTIFIED BY '4Ht#RQz5jDNt';
flush privileges;
exit
Composer Installation
Note: Do not use the “apt install composer” it is old and does not upgrade well.
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"php -r "if (hash_file('sha384', 'composer-setup.php') === 'a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"php composer-setup.php --install-dir=/usr/local/bin --filename=composerphp -r "unlink('composer-setup.php');"
Results of these commands
root@drupal-demo-project:~# php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
root@drupal-demo-project:~# php -r "if (hash_file('sha384', 'composer-setup.php') === 'a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
Installer verified
root@drupal-demo-project:~# php composer-setup.php --install-dir=/usr/local/bin --filename=composer
All settings correct for using Composer
Downloading...Composer (version 1.9.1) successfully installed to: /usr/local/bin/composer
Use it: php /usr/local/bin/composerroot@drupal-demo-project:~# php -r "unlink('composer-setup.php');"
Project Setup
Create a working folder for the project. I like using a root folder “/data” with a subdirectory “./commerce”. If I tie a specific user to the project, I set the home directory of that user to/data/commerce.
mkdir /data
mkdir /data/commerce
cd /data/
Setup permissions for the directories:
Note my default user is “commerce”
groupadd -g 1500 commerce-site
usermod -a -G commerce-site www-data
usermod -a -G commerce-site commerce
chown -R commerce:commerce-site /data
chmod -R 775 /data
Results:
root@drupal-demo-project:/data# ls -la
total 12
drwxrwxr-x 3 commerce commerce-site 4096 Dec 10 19:46 .
drwxr-xr-x 26 root root 4096 Dec 10 19:46 ..
drwxrwxr-x 2 commerce commerce-site 4096 Dec 10 19:46 commerce
Drupal Commerce
Now add the Drupal demo-project
su - commerce
cd /data
composer create-project drupalcommerce/demo-project commerce --stability dev --no-interaction
Added Note:
After I completed this article and installation, I found that I need some NPM modules. Add the following after the above command.
composer require bower-asset/jquery-simple-color bower-asset/spectrum
Results
> DrupalProject\composer\ScriptHandler::createRequiredFiles
Created a sites/default/settings.php file with chmod 0666
Created a sites/default/files directory with chmod 0777
Additional Useful Modules: Seckit and Feeds.
~/commerce$ composer require drupal/seckit
~/commerce$ composer require drupal/feeds
Apache Configuration:
Because this is a local installation and we want to use a named server, we need to add an entry in the host machine /etc/hosts and the guest machine /etc/hosts
guest machine IP: 192.168.200.136
On the guest (Ubuntu)
echo -e "127.0.0.1\tcommerce.local" >> /etc/hosts
On my Mac (Host Machine)
echo -e "192.168.200.136\tcommerce.local" >> /etc/hosts
Now I can configure the apache server for the project. We need to create a named virtual server for the directory “/data/commerce/web”. Create the following file in “/etc/apache2/sites-available”.
# Filename 001-commerce-local.conf
<VirtualHost *:80>
ServerName commerce.local
ServerAdmin webmaster@localhost
DocumentRoot /data/commerce/webErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined<Directory /data/commerce/web>
Options All -Indexes -ExecCGI +Includes +MultiViews
<IfModule mod_dav.c>
DAV Off
</IfModule>
AllowOverride All
Require all granted</Directory>
</VirtualHost>
#Fix Clean URLS
root@drupal-demo-project:/etc/apache2/sites-enabled# a2enmod rewrite
Enabling module rewrite.
To activate the new configuration, you need to run:
systemctl restart apache2
root@drupal-demo-project:/etc/apache2/sites-enabled# systemctl restart apache2
Database Configuration
I change localhost to the IP address, this fixes odd issues with mysql.sock permission issues.
Don’t be surprised if you get this message the first time:
The first step is to test if the mysql command works.
Now we need to check the socket
commerce@drupal-demo-project:~$ php -ini | grep mysqld.sock
pdo_mysql.default_socket => /var/run/mysqld/mysqld.sock => /var/run/mysqld/mysqld.sock
This tells us where PHP is looking for the socket. Now we need to see where the socket is.
commerce@drupal-demo-project:/etc/mysql$ mysqladmin -p -u app_commerce variables | grep sock
Enter password:
| performance_schema_max_socket_classes | 10 |
| performance_schema_max_socket_instances | 322 |
| socket | /var/run/mysqld/mysqld.sock
After some troubleshooting on mysql, the issue was the grant option wasn’t applied properly. Logging in as root (mysql -u root -p )and running this command. Fixed the issue
GRANT ALL PRIVILEGES ON commerce. * TO 'app_commerce'@'localhost';
A little time passes
Final Configuration
Post Installation Notes:
- If you get an “Access Denied admin” type message, use incognito and reset your webserver.
- There were 2 errors and 3 warnings in the admin panel.
Remove write permissions from the configuration directory and settings
# Fix for configuration files
cd ./commerce/web/sites
chmod -222 default
chmod -222 default/settings.php
Add the following lines for your domain into the settings.php file.
$settings['trusted_host_patterns'] = [
'^www\.example\.com$',
'^example\.com$'
];