Git Push with WPEngine

One of my favorite features of WPEngine is their integrated git push for deployment. Instead of manually SFTP’ing files back and forth, you can easily push code changes while keeping your code version controlled.

WPEngine lets you create unlimited transferrable installs, so you can easily use it for all your site development. When it’s time to go live, you simply type in your client’s email address and they’ll get a direct email walking them through the transfer process.

Create a site on WPEngine

From your WPEngine dashboard, click “Add Install” and give it a name. Once created, you can clone an existing live site here by installing the WPEngine Automated Migration plugin on the live site, typing in your WPE install details, and letting it handle the migration of everything.

Once the install has been created, click “Git Push” in the sidebar, type in your name, and paste your SSH public key. This support article by WPEngine will walk you through it.

Setup Locally

Setup your local development environment. You can use MAMPLocal, or other tools. I also recommend you setup wp cli.

Open Terminal and initialize git in the top level of the website: git init. While you could use it to version control everything (WP core, themes, plugins…), it makes sense to limit it to just the code you’re actively editing using a .gitignore file. I limit it to my custom theme and core functionality plugin. Here’s my gitignore file.

If you’ve created a repo on GitHub, click “Clone or Download” (screenshot), copy the URL they give you, and set it up as a remote. For instance, for my EA Starter theme I would use: git remote add origin [email protected]:billerickson/EA-Starter.git

Go back to the Git Push page in the WPEngine dashboard. In the bottom of the right column you’ll see the two remotes corresponding to your production and staging environment. Add them (make sure you use the correct URL). Example:

git remote add production [email protected]:production/mysite.git
git remote add staging [email protected]/mysite.git

Pushing code updates

As you develop your site, periodically commit your changes: git commit -am 'this is my great commit message'. Push those changes to GitHub: git push origin master. And when you’re ready to push to your production or staging site, simply push to the remote: git push production master.

WPEngine will scan the files, make sure there’s no PHP errors, update the correct files, and clear your cache.

I also recommend using WP Migrate DB Pro to push/pull your database and media. If your site has lots of media, skip the media syncing and use BE Media from Production so that your local install will reference the production site for media rather than having to store a copy of everything locally.

Migrating Environments

You can also migrate entire environments through the WPEngine portal. When you enable the Multi-Environment Site feature, you’ll get three environments: Production, Staging, and Development.

When we are redesigning a website that’s already hosted on WPEngine, we’ll copy the production site to development and build our new theme there. When it’s time to go live, we can push the development environment to production.

We often work with food bloggers and publishers who have dozens of new posts and thousands of comments created during the development process, and we don’t want to lose it. When it’s time to launch the new site, we use the following approach to migration:

  1. Implement a “content freeze” on production. The client should not create or edit any content between now and completion of the redesign launch.
  2. Make a fresh backup of all three envrionments.
  3. Deploy the latest production backup to the staging environment
  4. Use git push staging master to push the code updates to the staging environment.
  5. Rebuild everything on staging: setup new plugins, menus, widgets, forms, and update any pages that need new content (ex: Home)
  6. Do a final review of the staging site with the client.
  7. Once approved, deploy the staging environment to production, overwriting the production files and database.

Minimize downtime with a hidden feature flag

When you deploy the staging environment to production, the production site becomes inaccessible until the migration is complete. This was by design so there isn’t any data lost during the migration, like ecommerce sales that occur after you press “Deploy” but before the new database is in place.

However, for our clients, we would rather have a few lost comments than an hour of downtime when pushing a large site to production.

There is an unpublished feature that can help.  Open up a support chat and request the ‘clone_site_use_deploy_dir’ site config option for the specific install. Since this is a hidden feature, the first person you chat with may be confused so you may need to ask them to escalate.

Once enabled, instead of copying the source site directly to the target site, WPEngine will now copy source to a temporary directory and database, do the data munging (search-replace) on the temporary location, and then move the temporary location to the target. This way the target site doesn’t change while the data munging is happening. The only downtime incurred is the time taken to do the move.

We request this feature flag for all of our clients and have had no noticeable downtime during deployments.

Be careful though. Since the target site is now available during the time of the copy, it introduces potential data loss issues. If any data is written to the target site while the copy is happening, that data will be lost at the end of the copy since it gets overwritten by source. I wouldn’t recommend this approach where important data might be collected during the migration, like ecommerce or membership sites.

Bill Erickson

Bill Erickson is the co-founder and lead developer at CultivateWP, a WordPress agency focusing on high performance sites for web publishers.

About Me
Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk

Reader Interactions

Comments are closed. Continue the conversation with me on Twitter: @billerickson

Comments

  1. Thomas Zickell says

    Hi Bill,
    I am glad that your bringing this type of thing up. Many people do not utilize GitHub on WP engine. I agree the ability to spin up transferable client sites is awesome.

    Have you checked out and I’m just saying this because it’s so relevant to what you’re talking about. Have you tryed Pantheon? They have everything you’re talking about and a much deeper Git integration what you said about SFTP and GitHub are done in a manner in which I don’t think can be topped.

    I am not trying to promote something just letting you know that everything you talked about that you liked is built in the right way to pantheon take a look is my advice.

    I love power of versioning and transferring to clients is especially important. Also not having a limit of any type on how long you can develop a site is amazing.

    • Bill Erickson says

      No, I haven’t had a chance to use Pantheon’s offering yet but it looks great. I’m hoping I can get a client hosted with them soon so I can learn more about it.

  2. carrie dils says

    Yay for Git + WPE! One thing worth noting is that you can push directly to a WPE staging site as well as the production site.

    • Bill Erickson says

      I just updated the post to include that. I also added a link to your great article 🙂

  3. Jon Schroeder says

    Bill (or Carrie), how do you deal with your own plugins that you’re using (and perhaps modifying) on a client site that you’re writing a theme for?

    Do you use the individual repo for the plugin, and ignore that plugin in the main client gitignore (which includes both the theme and some plugins), or is there a different way you approach it?

    (I ask because I have a number of plugins that I use over and over that aren’t on the WP repo, like a plugin that adds a content type for testimonials, then outputs that in a default way. It periodically gets a bit more refined during development of an individual site on which it’s being used.)

    • Bill Erickson says

      I have a single “site” repo that contains the website’s theme and core functionality plugin. My gitignore ignores everything BUT those two folders. So as I add new plugins, I don’t have to edit the gitignore to ignore that too.

      For plugins that I use often, I create a repo for it, like EA Share Count and BE Events Calendar.

      • Jon Schroeder says

        That’s about what I’d thought; wanted to see if you had a better way. Are you still liking this methodology after using it a bit? I’m thinking of moving to a similar workflow on Flywheel (using DeployHQ to push Git commits onto staging or production), but it’ll be a significant change to workflow.

      • Bill Erickson says

        I like the setup. It’s a bit more work to initially setup, but then pushing / pulling changes are very easy.

        It really helps if you have WP Migrate DB Pro. Their CLI and Media addons help you manage everything that’s not code.

        wp migratedb migrate 1 – Pushes the database and any new media from my local environment to WPEngine. (used for initial migration)

        wp migratedb migrate 2 – Pulls the database and new media from WPE to my local environment (used before making changes to site locally once the client has access and is making changes)

  4. Nick Davis says

    Hey Bill,

    Thanks for writing this up. I’ve been using Git Push with WP Engine for a while now but it’s always good to get your take on something!

    Cheers,
    Nick

  5. Richard Buff says

    So just to clarify… Since WPE doesn’t allow pulling, if the client adds 10 plugins to the site (or edits the stylesheet, etc…), the only way to get those physical file changes back into your local install is to manually download and extract the latest restore point and copy those files into the local install? (and then pull the database with WP Migrate DB Pro)

    As a followup to that, when you’re working on change requests after having sent the site for review, do you tell the client to not make any changes to the review site, so that you don’t wind up with anything out of sync?

    • Bill Erickson says

      That’s exactly why I created wp cli plugin install-missing. Before I start any changes I have a script that:

      git pull origin master make sure I have up-to-date theme & CF plugin
      wp migratedb migrate 2 pull latest copy of DB and media, the profile id = 1 is for pushing to WPE, id = 2 is for pulling
      wp plugin install-missing install any plugins that were added

      My clients aren’t usually tech savvy enough to edit theme files, but if it becomes an issue I think turning on Read Only File Configuration would fix it.

      Clients can still edit content, add media, and install/deactivate plugins. The only thing this doesn’t cover is what version plugins are used, but that’s easily fixed by running wp plugin –update-all on both sites.

      And I’ve only been doing this for a few weeks now so I’m sure there’s things I haven’t thought of yet.

      • Richard Buff says

        Wanted to swing back by and say thanks, I got this working on WPE with your’s and Carrie’s article. I bought the $200 version of WP Migrate DB Pro through your affiliate link . 🙂

          • Josh says

            I want to say thanks as well. Great article. I’m new to WP development and the DB syncing was driving me nuts. Your plugin recommendation is perfect. I followed your link and made a purchase.

          • Bill Erickson says

            Glad to help! You might also check out Mergebot which lets you merge changes between two sites. So changes you make to the development database can be recorded and run on the production environment.

  6. Ann Cascarano says

    Hey Bill! Completely agree with the move from Bitbucket to Github now that unlimited private repositories are permitted – not only is it less of a hassle to have everything in one place – but I also much prefer the GitHub interface (sorry, Bitbucket! ).

    I’ve been using the Git Push feature with WPEngine for some time- still refining the process. I have been manually keeping things in sync between environments (sql dumps and moving media via SFTP) – which I am used to by now – but I’ll definitely look into WP Migrate DB Pro. Cheers!

  7. Ben Attenborough says

    Hey Bill, great article. I was just wondering about something.

    I don’t want to push some development files, like sass files to production. But I do want to track these locally with git while I’m developing the site. On other hosts I use a task runner like gulp to build a separate build folder and then push just that to the live site. However the way WP Engine works it looks like you push from the root directory making it difficult to do this.

    Thinking about it I suppose I could have two folders in my theme folder “my-theme-production” and “my-theme-live”. Then I can have a git folder in production which produces the live theme. I only track the live theme from the WP Engine git repo.

    How would you approach this?

    Thanks.

    • Bill Erickson says

      I’m not sure how best to implement it the way you describe. On every project I’ve been involved in, we included the sass files in production. Here’s our standard code structure: https://cl.ly/450O2C1F1s2B

      • Ben Attenborough says

        I went with having two theme folders, a production and live theme. On my localhost I develop with the production theme and when I want to I use gulp to rebuild the live theme. I use git to push only the live theme. This way I can just push live files and not production files (sass but also things like node modules (which I don’t track locally either)). It seems to work.

        This also means I can have a separate production repo which is just for the theme.

  8. Ben Attenborough says

    By the way the BE Media from Production plugin is a really fantastic idea. The main site I maintain has more than 5 gig in the uploads folder and being able to pull images from the live site makes updating my local host version a whole lot easier. I love the fact there are so many people in the WP community who are willing to do cool stuff like this for free.

  9. Flimm says

    Is there a way to ensure that certain files in your Git repo don’t end published in the web server?

    For instance, I would like to include files like `.travis.yml` and `.editorconfig` in my Git repo, but don’t want the server to have them.

    • Bill Erickson says

      I’m not aware of how to exclude them from WPEngine, but you might try contacting WPE Support. About a year ago I spoke with them and they were considering allowing developers to include their own deployment scripts to run when code is pushed there, like the ones they use to check for PHP errors. There might be a way to set it to remove certain files at that point.

  10. Dan Pringle says

    Hi Bill, really useful article. I’m wondering, Do you start every project by initiating git in the site/wordpress root?

    I have a theme I’ve been working on locally and git is setup in the theme root and will be deployed to WPEngine. In this situation would you create a brand new repo in the site root (losing the history) or would you move the repo to the new directory (if that isn’t going to cause more issues).

    • Bill Erickson says

      Yes, I start every project by initializing git at the top level (WordPress root).

      In your case, I’d probably move the repo to the top level, then move all the theme assets back down (wp-content/themes/[theme_name]). To the git repo it will appear as if you moved all the assets deep into a subfolder and it will maintain the version history.