Install CiviCRM on WordPress with Nginx

Install CiviCRM on WordPress with Nginx

Over the weekend I installed a copy of CiviCRM on WordPress to demo for a small nonprofit that recently asked me to help with some of their data needs. CiviCRM is a constituent relationship management (CRM) system designed for nonprofit organizations. While I installed it as a WordPress plugin, it’s also available for Joomla and Drupal.

Install CiviCRM on WordPress with Nginx

This guide was written using:

  • WordPress 4.0.1,
  • CiviCRM 4.5.4
  • Nginx 1.6.2
  • MariaDB 10.0.15 (as a replacement for MySQL)
  • PHP 5.5.9
  • Ubuntu 14.04 LTS

Nginx, MariaDB or MySQL, and PHP/PHP-FPM should already be installed. Instructions for installing Nginx and MariaDB are can be found in my earlier LEMP stack tutorial. If you’re just interested in using PHP and not other languages like Python, you can substitute PHP-FPM for uWSGI.

Create CiviCRM and WordPress databases

While CiviCRM and WordPress can use the same database, it’s cleaner to keep them separate.

From the command line, log into MySQL/MariaDB as as root or your administrative user.

james@localhost:~$ mysql -u root -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 635
Server version: 10.0.15-MariaDB-1~trusty-log binary distribution

Copyright (c) 2000, 2014, Oracle, SkySQL Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> 

Create one database for WordPress and another for CiviCRM.

MariaDB [(none)]> CREATE DATABASE demo_wp;
Query OK, 1 row affected (0.00 sec)CREATE DATABASE demo_wp;
MariaDB [(none)]> CREATE DATABASE demo_civi;
Query OK, 1 row affected (0.00 sec)

Create the user crm_user@localhost and assign a password while simultaneously granting that user access to the WordPress database. Then grant the user access to CiviCRM database.

Two separate users could also be created rather than giving one access to multiple databases.

MariaDB [(none)]> GRANT ALL PRIVILEGES ON demo_wp.* TO "crm_user"@"localhost" IDENTIFIED BY "mypassword";
MariaDB [(none)]> GRANT ALL PRIVILEGES ON demo_civi.* TO "crm_user"@"localhost";

Reload privileges from the grant tables and exit MariaDB.

Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> EXIT

Create site directory and configure Nginx

For now, just create the root directory where you’ll be placing the WordPress files.

james@localhost:~$ mkdir -p /srv/www/democivi/public

Create the Nginx site configuration file.

james@localhost:~$ nano /etc/nginx/sites-available/democivi

This server block is probably familiar if you serve any other PHP sites with Nginx. It starts with standard directives telling Nginx where and how to listen for requests as well as where to look for files.

server {
    listen 80;
    root /srv/www/democivi/public;
    index index.php;
    charset utf-8;

Basic access and error logging.

    access_log /var/log/nginx/democivi.access.log;
    error_log /var/log/nginx/democivi.error.log;

Location and try_files directives to check for the existence of static files that can be served directly prior to passing requests to PHP.

    location / {
            try_files $uri $uri/ /index.php?$args;

    location ~* \.(htm|html|xml)$ {
            try_files $uri $uri/ /index.php?$args;

Send remaining requests to PHP-FPM using FastCGI.

    location ~ \.php$ {
            try_files $uri /index.php;
            include fastcgi_params;
            fastcgi_buffers 16 16k;
            fastcgi_buffer_size 32k;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass php;

CiviCRM checkUploadsAreNotAccessible error

This last location directive tells Nginx to block HTTP access to files in the CiviCRM uploads directory. Without blocking access to these files, CiviCRM will display warning messages such as checkUploadsAreNotAccessible.

    location ~ ^/wp-content/plugins/files/civicrm/(ConfigAndLog|custom|upload|templates_c)/ {
            deny all;

I pass PHP requests to an upstream referencing PHP-FPM’s UNIX-domain socket. Depending on your configuration and structure, you may need to use something similar.

  upstream php {
          server unix:/var/run/php5-fpm.sock;

Create a symbolic link from the site configuration file in sites-available to sites-enabled.

ln -s /etc/nginx/sites-available/democivi /etc/nginx/sites-enabled/democivi

Test the new Nginx configuration. If the test is successful, reload Nginx.

james@localhost:~$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
james@localhost:~$ sudo service nginx reload

Download and Install WordPress

Switch to the site’s base directory, below public.

james@localhost:~$ cd /srv/www/democivi

Download and extract the latest version of WordPress into the public directory.

james@localhost:~$ curl -O
james@localhost:~$ tar -zxf latest.tar.gz --strip-components=1 -C public/

WordPress Permissions

There’s a lot written about WordPress file permissions. Unfortunately, every case is different so what works for someone might not work for your situation.

Try proceeding with your WordPress installation without touching the permissions. You’ll be told during the installation if there are problems and can come back here.

These lines attempt to reset WordPress files to the recommended default. However, /wp-content/ gets special treatment and has its owner set to that of the Nginx and PHP-FPM users.

james@localhost:~$ sudo chown -R youruser:www-data /srv/www/democivi/public
james@localhost:~$ sudo chown -R www-data:www-data /srv/www/democivi/public/wp-content
james@localhost:~$ sudo find /srv/www/democivi/public/ -type d -exec chmod 755 {} \;
james@localhost:~$ sudo find /srv/www/democivi/public/ -type f -exec chmod 644 {} \;

If reapplying permissions and changing the owner of /wp-content/ isn’t sufficient, you may need to change the ownership of all files to match the the Nginx and PHP-FPM users. If you use shared hosting and the Nginx/PHP-FPM user is something like www-data, www, nobody, or nginx then this isn’t a good idea.

james@localhost:~$ sudo chown -R www-data:www-data /srv/www/democivi/public
james@localhost:~$ sudo chmod -R g+w /srv/www/democivi/public

Complete WordPress Installation

Run the WordPress installation by accessing your site with a web browser. The process is quick and easy, you just have to enter your MySQL/MariaDB credentials along with a few other settings and submit.

If the process was successful, you’ll be prompted to create an admin user and provide some basic information about your new site.

Download and Install CiviCRM on WordPress with Nginx

Switch to the directory below your site’s root if you’re not already there.

james@localhost:~$ cd /srv/www/democivi

Download the appropriate source file from The URL will look something like

Download the zip file, dropping the /download at the end of the URL.

james@localhost:~$ curl -LO

Unzip the file to the WordPress plugins directory.

james@localhost:~$ unzip -d public/wp-content/plugins

Create a CiviCRM’s files directory under plugins. Change the directory’s owner as well as the owner of plugins/civicrm/.

james@localhost:~$ mkdir -p /srv/www/democivi/public/wp-content/plugins/files
james@localhost:~$ sudo chown www-data /srv/www/democivi/public/wp-content/plugins/files
james@localhost:~$ sudo chown -R www-data /srv/www/democivi/public/wp-content/plugins/civicrm

Log into WordPress using your administrator account and go to the Plugins page, http://yoururl/wp-admin/plugins.php. Click Activate under the CiviCRM listing.

CiviCRM installer

With the CiviCRM plugin activated, go to CiviCRM Installer under Settings, http://yoururl/wp-admin/options-general.php?page=civicrm-install.

On the CiviCRM Installer screen the red requirements have not been met. Many are red just because it doesn’t have your database settings yet. Go ahead and enter them and click Re-Check Requirements to refresh the screen. If everything is in order the bars will turn green and a Check Requirements and Install CiviCRM button will appear.

Click the button to finish installing CiviCRM on WordPress. Upon refreshing your dashboard, a CiviCRM icon will appear on the left menu. Congrats on your install of CiviCRM on WordPress with Nginx!

Could not create a trigger

If CiviCRM can connect to the database but complains about not being able to create triggers (and you’re using MySQL version 5.1.6 or higher), you may have binary logging enabled. If that’s the case, adding a line to to your MariaDB/MySQL configuration will resolve the problem.

james@localhost:~$ sudo nano /etc/mysql/my.cnf

Add the following line to the configuration.

log_bin_trust_function_creators = 1

Restart MariaDB/MySQL to apply the changes.

james@localhost:~$ sudo service mysql restart

Leave a Reply

Your email address will not be published. Required fields are marked *