This article is a walkthrough on the steps to setup a fairly secure* WordPress site leveraging git to make updates easier. It is the result of a set of best practices that I follow when setting up a new WordPress site.
This is not a guarantee of a “hackproof” WordPress site. It is merely a tutorial based on best practices that I have evolved over time. Following these instructions will provide a more secure, better protected WordPress site but it does not confer any kind of magical or technical immunity.
This is a medium-level tutorial and assumes some basic knowledge about using git and working with both the command line and SQL directly. I will provide links to resources where I can and am happy to answer questions in the comments if you have them. If you have previous experience installing WordPress it will be easier to use but it should be accessible to new users who already have some technical expertise.
We will be covering the following topics in detail as we walk through this series. In addition, I have committed everything to GitHub at https://github.com/bookwyrm/secure-wordpress-setup so you can review the history or see setup details there if you want.
- WordPress Setup with Git
- Cleaning up Themes and Plugins
- Pre-Install Security and Config
- WordPress Installation
- Post-Install Plugins and Configuration
- Keeping on Top of Updates
WordPress Setup with Git
I like using Git to manage WordPress because it is much easier to manage updates to WordPress.
Setup Git Repository
First we need a local git repo to work with. This will essentially be the document root of a website assuming that you aren’t running your WordPress site in a subdirectory.
[gist id=”2b8b123f1a7079c250cc” file=”setup-git-repo.sh”]
Add WordPress as Submodule
This is where the major benefit of using git comes in. WordPress is added as a git submodule so that it is much easier to upgrade when newer versions are released.
[gist id=”2b8b123f1a7079c250cc” file=”setup-wordpress-submodule.sh”]
Initial WordPress Config
Now we need copy some bits from the submodule into our document root so that WordPress can work as expected.
[gist id=”2b8b123f1a7079c250cc” file=”initial-wordpress-config.sh”]
In this setup, I like to version my
wp-config.php because I usually run a local dev version of my WordPress instance in addition to the production version. There is more on this topic below in Pre-Install Security and Config.
You will also need to edit
index.php to load the WordPress resources correctly. The best way to see this is via the commit diff for
Manage Themes and Plugins in Git
In order to be able to version themes and plugins in our Git repository, we need to copy the
wp-content/ directory from the submodule:
[gist id=”2b8b123f1a7079c250cc” file=”manage-themes-and-plugins-in-git.sh”]
Cleaning up Themes and Plugins
It’s always a good idea to delete themes and plugins that you won’t use. To support this, I usually delete the default plugins and all but the most recent theme.
[gist id=”2b8b123f1a7079c250cc” file=”cleaning-up-themes-and-plugins.sh”]
Pre-Install Security and Config
There is some data in
wp-config.php that is common to both installations and having it versioned makes keeping everything in sync much easier. However, I do not want my keys, salts, or database credentials in version control. To support this setup I create a separate
environment.php file which contains the bits I don’t want in version control and import that into my
You can see see the updated
wp-config.php file and a sample environment.php file both in the GitHub repo.
As you can see in the
wp-config.php we also need to setup appropriate URLs and Directories to support referencing resources in the submodule.
The final step I like to take before the WordPress setup is to change the default database prefix. I like to follow the pattern of
wp_XXXXXXXX_ where I still start with
wp_ but then add in a random 8 character string generated by Random.org.
I keep this in the
wp-config.php file rather than
environment.php so that it is easier to keep my local dev and production in sync and refresh my local database from production when necessary.
In my next post, I’ll go over post-installation security and plugins that we can use for keeping everything more secure.