Install and manage WordPress with Composer
Well over two years have passed since my previous blog post on managing WordPress with git was written. A lot has changed since then. Composer has taken the PHP world by storm and the majority of developers are seeing the benefits and embracing it.
Using Composer, you can list a set of requirements for your project, and let it figure out where everything needs to be installed to, what dependencies are required, and how to obtain them.
If you’re not familiar with Composer, I would recommend that you go and read the Getting Started guide. This howto assumes you have knowledge of, and have perhaps used Composer before. This howto will cover installing WordPress with Composer. Following blog posts will cover installing themes and plugins.
Installing WordPress
First, you need to make sure you have Composer installed for your project, this is easily done by running the following command:
mkdir my-wordpress-project
cd my-wordpress-project
curl -sS https://getcomposer.org/installer | php
You will now have a composer.phar
file in your project directory.
Create a new composer.json
file with the following contents:
{
"repositories": [
{
"type": "package",
"package": {
"name": "wordpress",
"type": "webroot",
"version": "4.0",
"dist": {
"type": "zip",
"url": "https://github.com/WordPress/WordPress/archive/4.0.zip"
},
"require" : {
"fancyguy/webroot-installer": "1.0.0"
}
}
}
],
"require": {
"wordpress": "4.*",
"fancyguy/webroot-installer": "1.0.0"
},
"extra": {
"webroot-dir": "public/wp",
"webroot-package": "wordpress"
}
}
A quick explanation of what the above is doing for us. WordPress doesn’t support Composer installs out of the box - it doesn’t provide a composer.json
file. So we have to create a virtual Composer package for WordPress. We give it a name, version and location to a zip file archive where it can be downloaded from.
We don’t want the package to be installed to the default vendor directory that Composer would use. We need to specify a different directory. We do this with the aid of the webroot installer package. By giving our virtual package a type of webroot
, the plugin will detect and relocate the install location of WordPress to public/wp
.
We define the preferred install located in the extra section of the composer.json
file.
We need to create the public directory:
mkdir public
Note: It’s good practice to have a separate directory in your projects for your document root. This is so that if you have any other files, that shouldn’t be served via the web server, you can place them outside of the public directory.
You can now run:
php composer.phar install
This will pull down WordPress for you into the correct location.
Now with a normal install you’d go ahead and proceed with the famous 5 minute install. But because we want to be able to use Composer for any future WordPress updates, we don’t want to change any of the contents of the public/wp
directory. We want to be able to ignore this directory with our source code management tool.
In order to be able to use WordPress, we need to copy some files from the public/wp
directory to the public directory.
cp -R public/wp/{wp-content,index.php,wp-config-sample.php} public/
mv public/wp-config-sample.php public/wp-config.php
In public/index.php
, modify the following line:
require( dirname( __FILE__ ) . '/wp-blog-header.php' );
With:
require( dirname( __FILE__ ) . '/wp/wp-blog-header.php' );
We’re just updating the path as we want to reference the core WordPress files in the public/wp
directory.
Go to https://api.wordpress.org/secret-key/1.1/salt/ and update the lines in your public/wp-config.php
file:
define('AUTH_KEY', 'put your unique phrase here');
define('SECURE_AUTH_KEY', 'put your unique phrase here');
define('LOGGED_IN_KEY', 'put your unique phrase here');
define('NONCE_KEY', 'put your unique phrase here');
define('AUTH_SALT', 'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT', 'put your unique phrase here');
define('NONCE_SALT', 'put your unique phrase here');
That’ll secure your WordPress install. Configure your database settings as you normally would.
Now we need to set a few additional constants for the configuration.
define('WP_CONTENT_DIR', __DIR__ . '/wp-content');
define('WP_CONTENT_URL', 'http://' . $_SERVER['SERVER_NAME'] . '/wp-content');
define('WP_SITEURL', 'http://' . $_SERVER['SERVER_NAME'] . '/wp');
define('WP_HOME', 'http://' . $_SERVER['SERVER_NAME']);
Because the wp-content
directory isn’t in the same place as the core WordPress files (remember, it is now one directory level above), we need to tell the config file where it actually is. The same with the core WordPress files.
Some other optional tidy up; remove the default twenty*
themes:
rm -rf public/wp-content/themes/twenty*
Remove the default Hello Dolly plugin too:
rm public/wp-content/plugins/hello.php
You probably have an idea of what theme you’ll be using. Setting this constant will define the default theme, so that you don’t need to manually set this in your admin. This is optional.
define('WP_DEFAULT_THEME', 'mytheme');
Regarding housekeeping with your source code management tool. You’d want to ignore the composer.phar
file and public/wp
directory. Everything else can be committed and pushed.
Updating WordPress
Say you want to update to version 4.0.1
when it is released. In your composer.json
file, update the section under repositories so it looks like:
{
"type": "package",
"package": {
"name": "wordpress",
"type": "webroot",
"version": "4.0.1",
"dist": {
"type": "zip",
"url": "https://github.com/WordPress/WordPress/archive/4.0.1.zip"
},
"require" : {
"fancyguy/webroot-installer": "1.0.0"
}
}
}
We’ve updated the version number and the URL for the zip archive to reference the new versioned file.
You can then run:
php composer.phar update wordpress
Then commit your composer.json
and composer.lock
files.
That’s all there is to it. This is quite a stable workflow, and my next blog posts will cover handling the installation of plugins and themes.