I want to share my development setup and talk about how I do things these days.
This post is has two main sections. Part one covers the tools I use, and part two will cover my workflow ie. how I perform common tasks.
Part 1: The Tools
Local Web Server
I’ve used Vagrant, then Docker, and Vagrant again. Finally, I discovered Local by Flywheel. It’s a free tool which wraps docker up into a really slick app, and it makes life a lot simpler. If you find yourself working on WordPress most of the time, its a no-brainer.
From the interface, it allows you to add a new local website with just a few clicks and integrates nicely with Adminer or Sequel Pro. You can add a local SSL with one click, and includes MailHog to catch your development emails.
Flywheel gives away the app for free, as it deploys seamlessly to their Flywheel hosting, but it’s a standalone tool so you can actually use whatever hosting you like.
Production Hosting
I use Digital Ocean, and not Flywheels managed hosting platform. Using a VPS means that you also have to be your own server admin, but personally, I need the flexibility.
For the cost, Digital Ocean is excellent value, and if there’s one thing that stands out for me, it’s their depth of written tutorials. You can Google almost any server related How-To and find one of their community written tutorials.
Version Control
Git is essential (to me). If my project is public facing, I use Github, if not I use Gitlab as they provide private repositories at no extra cost. Even with a platform where the content is primarily stored in the database, it makes sense to keep all your updates versioned in case you need to roll back any changes.
Production Deployment
These days I am a team of one, so I just keep it simple and clone my master branch onto the server.
Text Editor
Visual Studio Code. It is fast, customisable and allows me to make use of the built-in PHP debugger really easily. Setting it up to work with Local by Flywheel is simple: It’s one config file, and a Chrome extension. I’ll cover the nitty gritty in part 2.
Part 2: Workflow
Setting up a new site
- Click the big + icon and work your way through step 1 of the wizard.
- Once you get to step 2, choose the custom environment. This is important if you want to use the PHP debugger in VSCode. It exposes the config directory for you can edit the necessary ini files.
- Finish the wizard step 3. It’ll provision the site automatically for you, and after a minute or two you’ll be able to load it up in your browser.
Using the same TLD as production:
It’s worth mentioning here that I personally prefer to use the same TLD as production for my local sites, and I use a host editor app such as Gasmask to quickly switch my host file. I can then avoid having to edit the database when I migrate it from local to production.
Using a hosts editor throws a spanner in the works with Local’s host file management, so you’ll need to set your own host entries using the app. Of course, if you want to simplify, just use a .local
TLD instead.
Its a choice between looking after the hosts file yourself, or having to find and replace DB dumps when you want to migrate.
Setting up the PHP debugger in VSCode
In the past, I’ve found setting up XDebug to be a bit of a headache. Luckily, with VSCode & Local by Flywheel, its really straightforward. I’ll link to the exact tutorial I followed, but overall it goes something like this:
- Make sure you chose the ‘Custom’ setup when you created your Local site.
- Edit
/yoursiteroot/conf/php/7.2.0/php.ini
a little. - Click a button in VSCode, and edit the
.vscode/launch.json
that gets created. - Install this Chrome extension: https://github.com/mac-cain13/xdebug-helper-for-chrome
Here is the detailed tutorial created by Ahmad Awais in order to complete the above steps: https://gist.github.com/ahmadawais/d6e809d45b8103b2b3a79fa8845f9995
Updating plugins & deploying to production
When updating plugins, I prefer the following procedure:
- Update the plugin on my local website.
- Add & commit the new files, with a commit message like
Update WP Rocket
- Git push to my remote Git repository.
- SSH into my Digital Ocean server,
cd
into my webroot and then I use a couple of custom alias commands:
I’ve got one called 770
that opens up my file permissions, in order to perform the git pull without any file linking errors.
I’ve got another alias called perms
, which I run once the git commands have completed. This runs a separate shell script, which sets all the common WordPress permissions for me. It accepts one argument, the absolute path of the WordPress directory, for example: /var/www/html/production/chrisjallen/
My aliases:
# User specific aliases and functions
alias 770='sudo chmod -R 770 .'
alias perms='sudo /usr/local/bin/wp-permissions.sh'
And the custom permissions script:
# Author: Chris Allen
#
WP_OWNER=apache # -- wordpress owner
WP_GROUP=apache # -- wordpress group
WP_ROOT=$1 # -- wordpress root directory ( arg #1 )
WS_GROUP=apache # -- webserver group
EXCLUDE=.git
# reset to safe defaults
echo "Setting permissions for files & folders.."
find ${WP_ROOT} -exec chown ${WP_OWNER}:${WP_GROUP} {} \;
find ${WP_ROOT} -type d -not -path ${EXCLUDE} -exec chmod 755 {} \;
find ${WP_ROOT} -type f -not -path ${EXCLUDE} -exec chmod 644 {} \;
# allow wordpress to manage wp-config.php (but prevent world access)
echo "Setting wp-config permissions..."
chgrp ${WS_GROUP} ${WP_ROOT}/wp-config.php
chmod 660 ${WP_ROOT}/wp-config.php
# allow wordpress to manage .htaccess
echo "Setting .htaccess permissions..."
touch ${WP_ROOT}/.htaccess
chgrp ${WS_GROUP} ${WP_ROOT}/.htaccess
chmod 664 ${WP_ROOT}/.htaccess
# allow wordpress to manage wp-content
echo "Setting wp-content permissions..."
find ${WP_ROOT}/wp-content -exec chgrp ${WS_GROUP} {} \;
find ${WP_ROOT}/wp-content -type d -exec chmod 775 {} \;
find ${WP_ROOT}/wp-content -type f -exec chmod 664 {} \;
# reset the .git permissions
find ${WP_ROOT}/.git -type d -exec chmod 770 {} \;
find ${WP_ROOT}/.git -type f -exec chmod 770 {} \;
tput setaf 2; echo "Complete."; tput sgr0
Please note: If you aren’t 100% confident with the command line, just be aware that one false move can cause untold destruction, so be careful what you type.
Migrating a database
Because I share a TLD between my local and love sites, the process is fairly simple. One thing I do try to avoid is migrating the DB from local to live. I tend to make sure I’m only exporting the live database into my local. The live database takes care of itself most of the time. I’ve listed the steps here so you can see how simple it is.
- Open up Sequel Pro, and connect to my live database.
- Select the correct database, and then go to
file > export
- I usually go with the defaults and export the whole database to my desktop.
- Close Sequel Pro, then go to the ‘Database’ tab in Local by Flywheel and click Sequel Pro. This reconnects to the local box, with no connection config required.
- Delete the tables from the database, which will usually be called ‘local’ and then do a file import.
Keeping live changes in sync
Any active live website will undergo daily content changes, people process orders, write posts, upload images. All of this means code changes on the live site.
To check for this, I SSH into the live server regularly and run a git status
on the webroot. Any changes which haven’t been performed by me get added, committed and pushed to the remote git repository. Usually with a super-descriptive commit message like "User updates"
.
It’s not perfect, but it’s real-world, and it ensures my live site is always under version control.