It's a bold title, I know. But I have been working to achieve this for about five years now and am finally very satisfied with my configuration. If you're looking to work on WordPress Themes or Plugins on your local machine, manage your code base with GitHub, and effortlessly deploy updates, you've come to the right place.
I'm cross-posting this from my personal site to dev.to because:
(a) I hope it will be useful to anyone trying to get all this working smoothly and
(b) I genuinely am hoping for some feedback from others who likely can point out things I'm doing horribly inefficiently and / or can tell me if any part of this essay is incorrect.
Let's go!
Local Setup
The first thing you need to do is upgrade to Mac OS X Sierra 10.12.2 or else you're going to have problems left and right. You should already have done that, though, because you're a developer and developers don't like to live with stale operating systems.
After that you need to follow Chris Mallinson's excellent tutorial, The Perfect Web Development Environment for Your New Mac. (I'm not going to rehash his whole article here because he did such a great job.) You can skip the bit at the end about implementing a custom home page if you want. I didn't do that and it's not really important if you already have your own method of navigating your own file system. I use Coda as my IDE and it handles organizing my projects.
The only tricky part of Chris' instructions is getting your httpd.conf files right. You may get lucky and have everything work perfectly just by following his rules. I was not lucky and had to make several changes, but that's probably because I have been screwing with my httpd.conf files for years. If you contact me I'm happy to send you my copies of httpd.conf and httpd-vhosts.conf and they'll probably work on your machine. I keep an archive of them in my iCloud Drive folder and use the exact same configuration on multiple machines -- two Mac Mini desktops and my MacBook Air -- with no issues.
After you've installed MySQL locally you need to make sure you have the ability to actually use it. Terminal.app is your friend:
/usr/local/mysql/bin/mysqladmin -u root -p'temppassword' password 'newpassword'
Now you can create a database to use for WordPress. I always name mine "wordpress" but you can name it anything really.
In that code the temppassword is what the MySQL install gave you for root. It's probably annoyingly complex enough to just use that same one again for the newpassword, but you can change it if you want.
Once you've gotten that working you're ready to start really cooking. Download a copy of WordPress, unzip it, and drop it into ~/Sites/wordpress/ first. You're going to run into some permission issues probably, but you can handle them with:
sudo chown -R _www ~/Sites/wordpress ; sudo chmod -R g+w ~/Sites/wordpress
And you'll need to make sure you can install Plugins locally by adding this line to your wp-config.php script:
define('FS_METHOD', 'direct');
At this point you should be able to hit wordpress.dev and start the WordPress installation process. I know it's tempting to use localhost as your database host, but you should stick with 127.0.0.1. The database name is going to be the database you added to MySQL a few minutes ago.
GitHub Setup
Okay. So now you have WordPress running locally and you can edit Themes and Plugins without worrying about taking down a production website while you hack. Now it's time to get serious. Do you have GitHub Desktop yet? If not, grab it and install it. (If you're some crazy person that does everything via CLI, I have no idea why you're even reading this since you probably know how to do it all already.)
Let's work on Theme development first. Create a new GitHub repository and initialize it with a README. I'll assume you named your repo "Skywalker" because you're an awesome person and that's what awesome people do. (Whether you make it public or private is up to you.) Click the big green Clone or download button and choose "Open in Desktop". You're going to save Skywalker in ~/Sites/wordpress/wp-content/themes/skywalker and it should only take a zillionth of a second because it's an empty repo right now.
Okay. Edit your theme. You don't have to do anything dramatic; just drop a style.css file in there and add a title to get started and save it. Switch to your GitHub Desktop app and it should show that a file has been changed and is ready to commit. But don't commit yet. We're just getting to the cool part.
Before you do anything else, SSH into your web server. If you can't SSH into your web server, you're out of luck and can't really continue. You should be able to SSH into your web server, though. If you can't, tell them you need shell access or else you're going to switch to a different host! (I recommend DreamHost.) Once you've SSHed to your server, make sure it has git installed by running:
which git
If your web server doesn't have git running, guess what? You need a better web host.
Good to go? Okay … Moving right along.
Download Marko Marković’s Simple PHP Git deploy script and update its config script.
- You can get a value for the SECRET_ACCESS_TOKEN from the handy Random Key Generator. I know you want to use one of the Strong or Fort Knox passwords, but this key needs to be used as a querystring variable, so save yourself a headache and just use one of the CodeIgniter Encryption Keys instead. If you're working on a WordPress theme for the government or a bank, jump through the hoops to make it Fort Knox safe. Otherwise I wouldn't be too worried about someone hacking the local pizza place's website by cracking the code here.
- Update the REMOTE_REPOSITORY to your own. It's going to look like https://github.com/YOUR_GITHUB_USERNAME/skywalker.git
- For now leave the BRANCH set to master. If you're rolling your eyes here and know that you want to use a different branch, go nuts. This is supposed to be a tutorial for beginners.
- Your TARGET_DIR is going to depend on your web host, so I can't give you much direction here. If you use DreamHost and have WordPress running in the root of your domain, it will probably look like this: /home/DREAMHOST_USERNAME/yourwebsite.com/wp-content/themes/skywalker
You'll need to FTP – or, better, sFTP – these two files to your web server somewhere. It doesn't matter where, as long as they're accessible to the outside world.
You also need the contents of your public SSH key (usually id_rsa.pub) from your web server. SSH into your server and run this to generate a key if you don't have a way to get one from your web host:
ssh-keygen -t rsa
Doing that will likely drop id_rsa.pub into a /.ssh/ folder. (You can use vi to get to it. You just need to copy its contents.)
While you're still SSHed into your web server, try to SSH from it to GitHub to make sure you can. You need to do this to "authorize" your web server to connect to GitHub, too. Run this command:
ssh git@github.com
You should get a response saying something along the lines of, "That worked but you can't do it," which is confusing but okay. If it doesn't work, you're going to need to talk to someone at your web host and / or at GitHub to figure out why your server can't talk to GitHub. I'll assume it works so you can move to the next step.
Go back to GitHub, click on your repository's Settings tab to get to the Deploy keys panel. You're going to add the contents of the id_rsa.pub file you just created as a deploy key. (You can name it whatever you want, as far as I can tell the name doesn't matter.) One snafu here, though: You can only use a single deploy key on a single repository. So if you want to work on two separate themes on the same server, you need to either generate a new user on your server for each one and then generate a new SSH key for each user or you need to drop your entire wp-content directory into the repo. (That's what I did, but I don't recommend it because then you're going to have to deal with git-ignoring a ton of files, since all your WordPress media uploads and any other Plugins are in that folder, too.)
Switch to the Webhooks panel and add a new webhook.
- Your "Payload URL" is the full path to the deploy.php script you uploaded, along with a querystring containing the SECRET_ACCESS_TOKEN you added to the deploy-config.php script. Just append ?sat=SECRET_ACCESS_TOKEN to the file.
- The "Content type" should be application/json
- I have my webhooks set to "Send me everything", although you can limit it to just the push event if you want to minimize how frequently it gets pinged.
- Yes, you want to make it active.
When you are done and click the green "Add webhook" button, GitHub will send a test ping to your web server's deploy.php script and tell you the results right there.
Wrapping Up
If everything has gone smoothly to this point, you should be able to switch back to your GitHub Desktop app and run a commit. (I have mine set to always commit and sync. Under Edit check the "Automatically sync after committing" option.) When you commit, your files are pushed to GitHub which triggers the webhook which calls the deploy script which pulls your files from your repo and pushes them to your web server and BOOM!, now your new Skywalker theme is in production. How cool is that?!
Bonus Points
You can have different webhooks for different branches of your repository. So let's say you have three branches: dev, beta, and master. On your web server you would then have deploy-dev.php, deploy-beta.php, and deploy.php, each with its own unique SECRET_ACCESS_TOKEN and each hitting its own unique config file with a different TARGET_DIR updating the appropriate folder. Since you can selectively assign permissions to branches -- assuming you have an "Organization" GitHub account -- that means you could have some developer working on the dev branch and only allowed to push to your dev folder. Then you make your dev folder serve up your dev subdomain and now you don't have to worry about a developer accidentally pushing something into production.
If you use Slack you can configure a different webhook to send a message to a Slack #channel any time someone commits, which is handy if you're working on a big project.
Top comments (8)
I am by no means a pro-level wordpress dev, but I do a fair amount of work on the platform.
If you'll allow me, some thoughts on your article here:
I generally work with $jsframework which means I rarely need a proper server setup on my local machine, but I did follow Chris's guide too for the times I do need one, and it works great, right up to the point where I want to access $site from my phone over the wifi network. For some reason that xip.io thing just refuses to work. eh.
At first when I read that you only add your theme to a repo I found it quite strange, but the more I thought about it, it makes a lot of sense. My experience with Wordpress, especially moving it around is not a great one, and now I think of it, most of that negativity comes with moving the entire wordpress platform from local to staging to production, and not just the theme.
And it makes sense. Wordpress itself doesn't change much.
If I can add something to your guide to make it the SUPER ULTIMATE GUIDE TO LOCAL WORDPRESS DEVELOPMENT (with uppercase and all!):
I realise you don't enjoy working in the terminal much, but... and here me out on this one, it will literally change your life: Add WP CLI to your toolbox.
Or:
$ cd ~/Sites/wordpress/
to get you in your working folder$ wp core download
- Downloads the latest wp to that folder$ wp core config --dbname="wp-experiment" --dbuser="whatevs" --dbpass="shhh" --dbhost="127.0.0.1" --skip-check
- creates your wp-config.php file for you.$ wp db create
- creates the db for you using the deets you entered into your wp-config.php file.$ wp core install --url=example.com --title=Example --admin_user=supervisor --admin_password=strongpassword --admin_email=info@example.com
- does the wp install in seconds.You now have a running wordpress site! The cooler thing about the wp cli is that your average maintenance becomes a lot quicker.
$ wp core update
- updates your wordpress installation$ wp plugin update
- updates all your plugins$ wp plugin install bbpress --activate
- install & activate a pluginThere is obvs a whole lot more it can do, especially around migrating content/db between servers etc.
You could for example create a very simple bash script that runs some of these commands for you to move all your uploads to another server, migrate the content/db, change urls etc for you.
Great article. Not a WP dev, or even a PHP dev for that matter. But I've recently been doing some theme development and decided to go with Varying Vagrant Vagrants TL;DR:
1) Install VirtualBox (if not already installed)
2) Install Vagrant (if not already installed)
3) Clone the VVV repo or download the latest stable release
4) In terminal (or cmd, it works cross-platform),
cd
into the directory where you cloned the VVV repo, typevagrant up
.It does some provisioning but once it's up it's a delight to work with. The beauty of it being in Vagrant is that I have the same environment across all of my machines (OS X and Windows 10) with:
To name but a few.
VVV: Intstalled Packages
It's a little overkill but, it's a great environment with everything that I need, and then some.
It's 2017, please stop recommending people run any development environments on their host OS. Vagrant exists, you should use it.
After setting up your environment in Vagrant learn to take snapshots of the images, or better yet use SaltStack, Ansible, Bash, or some other tool for installing all the requirements and configuring the VM automatically, and you're a long way into having a reasonable development environment and deployment strategy.
I think installing natively on Mac seems less troublesome because it's something we know. Docker offers lots of potential, but it's like: do I need to learn yet-another-thing? I think so many Docker-based solutions are coming up because once people figure out, they want to share it like evangelicals. That makes decision making a little tricky.
Anyway!
Here’s a video tutorial on how to set up a Docker-based PHP local development environment for macOS using this handy tool called DDEV. You have all the flexibility you'd have with Docker, but it "just works" out of the box, taking care of lots of things for you.
drud.com/ddev-local/how-to-set-up-...
Bonus: The same tool, DDEV, works on Linux and Windows (with an installer) and you can use it with any PHP application. There are some helper tools for popular CMSs too.
Disclaimer: I work with these people and they are awesome <3
Thanks, Adrian. I'll take you up on exploring WP CLI for sure.
You're right about storing all of WP in a git repo. Since I wrote this I've moved to only keeping my themes and not all of wp-content in repositories. On my machine I just have a standard database with the suite of test data that I use for developing all my themes.
Try Local by Flywheel! It uses docker and it's zippy quick. I work at Flywheel, but I also used to work at an agency and still do freelance work, and Local is such a dream to work with. You can download it here: local.getflywheel.com
Pro top: use docker for local development. And you will never ever mess your http.conf
docs.docker.com/docker-for-mac/ins...
docs.docker.com/compose/wordpress/
Very good article ! :)
I'll give it a try but I'll gonna call the repository
Kenobi
and I hope it will have the Hight Ground again ! :P