In this guide we are setting up Drupal 7 with php-fpm and Nginx
Prerequisites
-
A DNS record:
cms.example.com. 69 IN A 2.2.2.2
-
A Debian 9.3 (stretch) instance (ami-b9fa4cc1)
-
Make the hostname persistent on the instance, by creating the file /etc/cloud/cloud.cfg.d/99_hostname.cfg:
#cloud-config hostname: cms fqdn: cms.example.com
Installing dependencies
NOTE:The following commands are executed under a privileged admin user, unless otherwise stated.
$ sudo apt -y install php-apcu php-pear php7.0-fpm php7.0-cli php7.0-gd php7.0-mysql php7.0-xml php7.0-mbstring php7.0-curl nginx
Install Drupal 7
Create a user for the website and switch to it:
$ sudo useradd -s /bin/bash -d /srv/webadmin -m webadmin
$ sudo su - webadmin
Download Drupal 7:
$ wget https://ftp.drupal.org/files/projects/drupal-7.56.tar.gz
Extract Drupal 7
$ tar xvzf drupal-7.56.tar.gz
Rename the destination folder to cms:
$ mv drupal-7.56/ cms
Setup Nginx
Exit back to the admin user and prepare the CMS Virtualhost (Create the /etc/nginx/sites-available/cms file):
server {
server_name cms.example.com;
root /srv/webadmin/cms;
access_log /var/log/nginx/cms.example.com.access.log;
error_log /var/log/nginx/cms.example.com.error.log info;
index index.php;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# This matters if you use drush
location = /backup {
deny all;
}
# Very rarely should these ever be accessed outside of your lan
location ~* \.(txt|log)$ {
allow 127.0.0.1;
deny all;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTP_PROXY "";
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
}
location ~ \..*/.*\.php {
return 403;
}
location / {
# This is cool because no php is touched for static content
try_files $uri $uri/ @rewrite;
expires max;
}
location @rewrite {
# Some modules enforce no slash (/) at the end of the URL
# Else this rewrite block wouldn't be needed (GlobalRedirect)
rewrite ^/(.*)$ /index.php?q=$1;
}
location ~ ^/sites/.*/files/imagecache/ {
try_files $uri @rewrite;
}
location ~ ^/sites/.*/files/styles/ {
try_files $uri @rewrite;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
location ~ ~$ {
access_log off;
log_not_found off;
deny all;
}
}
Enable the cms virtualhost and disable the default (switch back to the admin user):
$ cd /etc/nginx/sites-enabled/
$ sudo ln -s ../sites-available/cms
$ sudo rm default
Verify the configuration:
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
The configuration is free from syntax errors. We can go ahead and restart Nginxand PHP-FPM :
$ sudo systemctl restart nginx.service php7.0-fpm.service
Enable HTTPS with Let's Encrypt
Install Certbot:
$ sudo apt -y install python-certbot-nginx
Generate the certificate:
sudo certbot --authenticator standalone --installer nginx -d cms.example.com --pre-hook "systemctl stop nginx" --post-hook "systemctl start nginx"
NOTE: under normal conditions the following command should work (and without restarting Nginx), but the Nginx authenticator has been disabled because of a security bug:
$ certbot run --nginx -d cms.example.com # Currently not working because of a letsencrypt bug
Use these settings in the prompt:
- Enter Email Address: admin@example.com
- ToS: Agree
- HTTPS Access: Secure
Certificate auto-renewal is already included in the python-certbot-nginx package. That is true for Debian but not Ubuntu:
$ cat /etc/cron.d/certbot
# /etc/cron.d/certbot: crontab entries for the certbot package
#
# Upstream recommends attempting renewal twice a day
#
# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc. Renewal will only occur if expiration
# is within 30 days.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew
Setup a MariaDB database
Install MariaDB:
$ sudo apt -y install mariadb-server
Now create the Drupal database:
$ sudo mysql
MariaDB [(none)]> CREATE DATABASE cms CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON cms.* TO 'cmsuser'@'localhost' IDENTIFIED BY 'MyDrupalDBPass';
MariaDB [(none)]> FLUSH PRIVILEGES;
Setup Drupal 7
We need some preparations before we proceed with the setup.
First create the sites/default/files directory (as the admin user):
$ cd /srv/webadmin/cms/
$ sudo mkdir sites/default/files
$ sudo chown www-data:webadmin sites/default/files
Then create the sites/default/default.settings.php file:
$ sudo cp sites/default/default.settings.php sites/default/settings.php
$ sudo chown www-data:webadmin sites/default/settings.php
Now visit this website to setup Drupal:
https://cms.example.com/install.php
Select the following options:
- Select an installation profile: Standard
- Choose language: English
- Verify requirements You will be redirected to the next step if all is OK. Otherwise you will need to fix your setup.
- Database configuration:
- Database name: cms
- Database username: cmsuser
- Database password: MyDrupalDBPass
- Configure site:
- Site name: Example Drupal CMS
- Site e-mail address: cms@example.com
- Username: cmsadmin
- E-mail address: admin@example.com
- Password: MyDrupalAdminPass
- Confirm Password: MyDrupalAdminPass
- Default country: Your country here
- Default Timezone: Your Timezone here
- Check for updates automatically: Enabled
- Receive e-mail notifications: Enabled
If everything is correct you will be greeted with a "Congratulations, you installed Drupal!" after you press the Save and continue button.
You can visit your newly installed Drupal CMS here:
Post-install steps
Setup cron for Drupal
Under the webadmin user run crontab -e
and use this cron job:
*/5 * * * * wget -O - -q -t 1 https://cms01.theo-andreou.org/cron.php?cron_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
### Check the status page
Visit the status page for any errors or warnings that need to be attended:
https://cms.example.com#overlay=admin/reports/status
If all is good we can move to the next step.
References
----------
* https://www.drupal.org/node/1030854
* http://blog.celogeek.com/201209/202/how-to-configure-nginx-php-fpm-drupal-7-0/
* https://www.drupal.org/node/244924
* http://drupal.org/cron