Automating your WordPress Deployment

Last Updated May 9, 2017

What’s the easiest way to launch a WordPress site? It seems like all the hard work is already done. You’ve designed and built the site. Now, it’s just a matter of getting the site on the server. It seems straightforward, enough. So, where’s the hold up?

Plenty of things. Personally, my biggest frustration is time. You’d think as computers get faster and with a decent Internet connection, time wouldn’t be a problem, but it is. I’ve found that manually uploading files to the server, on average, takes about 20 minutes. There are plenty of other things I’d rather be doing with my time. So, let’s talk about some ways to streamline the process.

Table of Contents


What really needs to be done?

To state the obvious, let’s think through all the pieces that we need to consider when launching a site:

  1. Domain Name
  2. Hosting
  3. Database
  4. File Uploads
  5. Plugin Files

Smarter, Not Harder

What are the ways, we can have have our computer do the work for us? Admittedly, there are a several different ways to accomplish this, but these are the two options that I’ve implemented into my workflow. Which option I use, depends on where the site is being hosted. I follow this thought process:

Where am I hosting the site?

  1. On my Digital Ocean account? Use Forge.
  2. On Flywheel account? Use Deploybot
  3. The client is hosting Use Deploybot

Using Forge

I love Digital Ocean. There’s a lot more flexibility on the development side than most other hosting environments. Cliche, but true: with great power comes great responsibility…which is why the cost is a lot cheaper than other options. — You have to install everything yourself and support is limited.

To handle the heavy lifting of setup, I use Forge to set everything up for me. One of the great things about Forge is that there’s a Quick Deploy option. As soon as an update is made to your repository, those changes will automatically be pushed to your server.

I’ve actually written a specific post that explains the entire setup.

Using Deploybot

The other method, uses a third party tool, called DeployBot.

If you’ve ever heard of the Beanstalk, it’s a web application that will host .git and .svn repositories, somewhat similar to GitHub and BitBucket. The biggest difference between the three is that Beanstalk will allow you to deploy your code directly to the server. — So, technically we could go this route. But, personally, I prefer to host my code on GitHub. Not only is it cheaper, but it’s also more popular. As a “best of both worlds,” though, the company that owns Beanstalk (Wildbit), has pulled out the deployment component of their application and made it available separately = Deploybot! This way, you can deploy your sites from any git repository. #Winning!

We’ll walk through the setup. As in all things, programming, there are multiple ways to skin a cat. Here is no different. When we’re setting up our repository, there are a couple of different methods we can take. We can either commit our entire WordPress directory to the repository or we can simply commit our custom theme. I’ve done it both ways and honestly, which method I use, simply comes down to the server I’m hosting the site on.

  • If I’m using a host that is specifically built for WordPress (like Flywheel or WP Engine), I’ll create a repository for the theme directory only. In most cases, these servers have built custom versions of their WordPress installs, specifically for their hosting environment. — Meaning, everything is optimized specifically for their setup. I don’t want to overwrite that. Let’s keep a good thing, a good thing.
  • If I’m using a host where I’m installing WordPress, I’ll commit my entire WordPress directory into the repository. In this case, when I’m setting up the server, I’d be uploading my version of WordPress via FTP anyway. Why not pull this into the system we’re setting up, and automate it. Makes sense to me.

Whichever route you go, there are pros and cons.

Your theme might have plugins that it relies on in order to function properly (like the Advanced Custom Fields plugin), these files are not stored within your theme folder. — Of course, I’ll tell you that with a grain of salt: there are workarounds.

Pros Cons
Custom Theme in the Repository Your repository is smaller and you’re only committing the code that you’re actually working on.
Entire WordPress Install Everything is committed: plugins, WordPress core files, etc. This makes it very easy to roll back to a previous version of the code, especially if something breaks when you’re updating. Your repository is larger and some people would probably say that it’s not good practice to commit code that you’re not maintaining, like the WordPress core files and third party plugins. To combat this, I like to implement a submodule strategy. This simply means that instead of having code I don’t maintain in my repository, I link out to another repository, where it is = a repository inside a repository. I’ve written about this before: for setting up WordPress and for installing WordPress plugins.

NOTE:


Before moving on, I feel like I need to clarify, when I say the “entire WordPress directory” or “the entire WordPress theme.” I still use a .gitignore file that keeps certain files and folders out of the repository. For example:

I actually have my .gitignore file in a gist, if you want to swipe it.

NOTE:

There are several ways to set up your .git repository. My favorite is through an app, called Tower. It will set you back about $59, but in my humble opinion, it’s worth every penny. It’s one of those apps that I have open all the time.

If you’re looking for cheaper alternatives and hosting on GitHub, they have their own free app. The catch is, the repository has to be hosted on GitHub.

Otherwise, you can use the command line. Geeky, but it’s free and without the hosting limitations of the GitHub app.

For convenience (mostly mine ?), I’ll walk through the setup with Tower.

Setting up the repository for your WordPress Theme

If you want to set up your entire WordPress install, you can jump down.

Within Tower, make sure you’re in the repositories section. Click on the plus button in the bottom left of the screen and select Create New Local Repository.

Creating a Local Repository in Tower

Within the Finder window that appears, navigate to your site directory (or theme directory, depending on what direction you’re taking) where WordPress is installed and click Create Repository.

Create a Repository in Tower

Next, you’ll want to “stage” your files to commit.

NOTE:

This is just part of how git works. You “stage” the files, commit them, and then “push” them to the remote server.

Click on the Stage All button.

Stage files in Tower

Enter a commit message into the “Commit Subject” textbox. If you want to write a detailed explanation, you can write more inside the “Detailed Description” text box. — The point is to make it easy for you or other developers to know what changes were made to the code. When you’re setting the repository up for the first time, I like to keep things nice and simple and use, “Initial commit.” Then, click the Commit button.

Tower - Initial Commit Message

Now, let’s add a remote server. Go to GitHub and create a new repository. (If you’re using another service, that’s fine, the process will be very similar.)

Once you’ve logged into your GitHub account, click on the “+” arrow in the top right and select New Repository.

GitHub - New Repository

Next, name your repository. Here, I just named mine selfteachme, but generally, I like to give my repositories a suffix. This helps me identify the contents of the repository simply through the name. For example, if it’s a WordPress repository, I’ll use _wp. Feel free to come up with your own system, but this is the one that I’ve found that works for me. Here’s a table of all the suffixes I use:

WordPress Theme _theme_wp
Laravel _l
Code Igniter _ci
Ruby / Rails _r

So, what’s the advantage, here? Well, if you have several repositories related to the same project, these suffixes help keep everything separate.

Then, you’ll need to select whether your repository is public or private. In GitHub, you get an unlimited number of public repositories. — They like to encourage open source. With a personal GitHub account, you’re paying a little bit of money each month, but you can have an unlimited number of private repositories. Your monthly bill only increases when you start adding collaborators.

If you’re not sure, I would encourage you to consider the contents of your code. Most of the time, there’s no proprietary content within the code I’m writing. Therefore, I could make it public, however, since it’s for a client I usually like to keep it private. Besides (and probably more importantly), if I’m committing the entire WordPress directory, there are WordPress plugins included in the repository that I don’t own. — And some of those plugins are premium plugins. I want to make sure I don’t violate those license agreements! Private is definitely safer.

In my humble opinion, the minimum monthly fee is worth it.

When you’re finished click on the Create repository button.

GitHub - Create Repository Settings

Once your repository is successfully created, you should see a screen, similar to this:

GitHub - Empty Repository

GitHub does a great job of telling you what’s next. If you’re using the command line, it gives you the exact commands you need to execute in order to set everything up on your machine. Since, we’re using Tower though, all we need is the repository’s address. Copy that.

Flip back over to Tower. We need to tell our local repository, that we’re using GitHub for our remote server.

Right click on Remotes and select Add Remote Repository.

Tower - Add Remote

By default, git will call a remote server “origin.” However, I like to name my remotes based on where the server is (GITHUB). This makes it really easy to tell in Tower where the remote is.

Tower - Add Remote Settings

Now that the connections are made, we can “push” our code, drag the master branch to the remote server.

After it’s done processing, all your files should be on GitHub. You can double check by refreshing GitHub in the browser. Instead of the welcome screen, you should see all your files listed and the details from the README.md file (if you have one).

Repository on GitHub

In the future, when you make updates to your code, you’ll go through a similar process, but much simpler.

You’ll make changes to your code.

Within Tower, you’ll select which files you want to “commit.” Provide a message, describing the updates that you made.

Tower - Staging and Committing Code

Then, click on the Commit button. This saves a “snapshot” of your files locally. Next, you’ll want to put those files on GitHub, by clicking on the Push button.

Tower - Push Code

A dialogue window will appear, asking you to confirm the destination. Usually, it’s right, but it’s always good to check and confirm. Click on the Push Head button.

Tower - Push Head

And GitHub is now updated with your latest and greatest!

This is all fine and dandy — your code is backed up and if you’re working with other developers, you can all work together without the fear of someone messing up someone else’s code. But, how do we get the code off GitHub and on to your hosting server?

Setting up Deploybot

Head over to Deploybot.

Deploybot Website

If you don’t have an account, yet, you can create one. Plans are pretty affordable:

Deploybot Pricing Plans

I have the Basic Plan. I’m never working on more than 10 sites at one time, so I can easily rotate repositories in and out.

Once you’ve set up your account, click on Repositories in the main navigation. Once you’ve set up a few repositories (like I have) you’ll see a list of all your connections. Click on the Connect a repository button.

Deploybot - Connect a Repository

Deploybot will ask you a few questions about your repository settings.

Select which service you’re using.

Then, select your account. If you’re using Deploybot for the first time you’ll need to click on the Connect new account button to give DeployBot permission to access your GitHub (or other) account.

Select the name of your repository from the dropdown menu.

Give the project a title. This is purely for use within Deploybot. By default, it names the project based on the repository. For simplicity (and consistency’s) sake, I go with it.

Next, you’ll need to select a color label from the dropdown. Personally, I think this is kind of dumb. It just adds a square of color next to the repository name within DeployBot’s list. I’ll usually pick something related to the color of the project that I’m working on…but, it really doesn’t matter.

Click the Commit button at the bottom of the screen.

Deploybot - Connect a Repository Settings

Once you’ve made all your selections, Deploybot will redirect you to the repositories tab. It may take a while for Deploybot to get everything initialized on their end, but at the very least, you should see your repository in the list immediately.

You’ll also find a column that tells you the last time a deployment was made and a gear icon for changing any settings.

Deploybot - Repositories Tab

We’ve set up the project and made the connection to the repository, but we still haven’t made any connections to our hosting server. — That’s next.

Let’s click on the name of your repository.

You’ll be taken to a screen that will eventually have a list of all the environments you’ve set up. But, first, we’ll need to set one up. Click on the Create environment & Server button.

Deploybot- Create an Environment and Server

Next, you’ll need to provide information about your environment.

Here’s the thing to remember: environments are groups of servers. Typically, I’ll only have 1 server per environment, but I’ve run into situations where I’ve had 2 (if I’m moving to a different server or if a client has subcontracted work out to me and doesn’t want to send their client to one of my servers).

For each project, I’ll usually have 2 different environments: 1 for staging and 1 for production.

Name your environment.

Give your environment a color label. Again, I think this setting is dumb, but I’ll usually label it green for active.

Set the deployment mode. If you select manual, you’ll have to log into the website and click the “deploy” button to trigger the transfer. If you select automatic, anytime you commit code to your repository, the new code will automatically be pushed to your server.

The rule of thumb I use? Automatic for staging and manual for production. Usually this works out. You’ll post a bunch of changes to a staging server for a client to review. Once everything has been approved, those changes, the updates will get posted to production…but, you want to wait until you have client approval, first. — Of course, you can also depend on branching for this type of workflow, which in all honesty, is probably better programming and more responsible.

Select the branch you want to use. Typically this is master, especially if you’re setting up a production environment.

Deploybot - Add an Environment

Scroll down.

One of the tricks I like to use is to have Deploybot send a message to Slack when it’s done uploading all my updated files. — This is especially helpful, if I select the automatic option. Either way, though, I don’t have to keep checking the Deploybot or my website to see if all the updates have been made.

I like to create a separate channel for each project and post all notifications related to that project there. Another popular method is to create a separate “notifications” channel dedicated to all of your project’s notifications.

Of course, you’ll need to set up the initial Deploybot-Slack integration, if you’re doing this for the first time, but after that, it becomes much easier — ticking the checkbox and selecting the appropriate channel from the dropdown.

When you’re done, click on the Save button.

Deploybot - Trigger Slack

Last step (for Deploybot, at least), set up your server.

As soon as you click the Save button, DeployBot will take you to a screen where you’ll be asked to select the type of server you’re using. — Most of the time, I select SFTP or FTP.

Deploybot - Choose Deployment Option

If you’ve done this before and are setting up a website on a server you’ve used before, you can scroll down to the bottom and copy an existing server’s settings. Simply choose the repository from the first dropdown and the server from the second dropdown. Then, click clone.

Deploybot - Clone an Existing Server's Settings

If you cloned one existing server, then Deploybot will profile a lot of the settings for you on the next screen. Otherwise, you’ll have to enter the settings yourself. It’s nothing crazy, though. If you go the SFTP / FTP route, it’s the generic FTP credentials.

The important setting to note, here, is the Destination Path.

If your repository contains your WordPress Theme only, then the destination path tells Deploybot where your theme folder is located.

If your repository contains your entire WordPress install, then the destination path will simply be your site folder’s root.

Deploybot - sFTP General Settings

Scroll down to the bottom of the screen, there are a few extra, advanced options. The only one I modify is the Exclude certain paths from being uploaded. — This simply keeps your server clean. There may be items that you need to commit to your repository, but don’t need to be on the server. Here, you can prevent those files from being uploaded.

Deploybot - Exclude files and folders

NOTE:

In the screenshot above, you may have noticed that I listed node_modules, and bower_components. Technically, those folders are not even in my repository. I’ve excluded them in my .gitignore file. Package.json and bower.json contain the information about the contents of those folders and can easily rebuild them, if necessary.

A better example would be excluding my assets/src folder where I keep my Sass files, precompiled / pre-minified JavaScript files, and uncompressed images.

Before committing code to the repository, I’ll run Gulp, which will compile Sass to CSS, compile and minify JavaScript, and compress all my images, placing all those assets in an assets/dist folder. — Which is the folder that the server needs to render the page. The assets/src folder is only used for development purposes, but still needs to be included in my repository.

Deploybot - Confirmation Screen

Woo hoo! You made it through the Deploybot setup!

Now, when you go to your repository within Deploybot, you’ll see the Staging environment that we set up, with buttons to Deploy (if you’re doing manual deployments) or Settings to adjust the servers.

Deploybot - Environment Setup Complete

Just to give you a feel for what those two options (Deploy and Settings) do, let’s look at those screens.

The Settings screen is simply a summary of our setup. Of course, everything can be modified and adjusted after the fact.

Deploybot - Edit Server Settings

The Deployment screen shows you what code will be pushed to your server.

  • You can enter a deployment note that will be displayed within Deploybot for future reference. By default, Deploybot will use the most recent commit message. I usually keep the commit message, since it keeps everything consistent with what’s in the repository.
  • Under the Review & Deployment section, it will show you how many commits you’re posting to the server. It will also display the commit hash that is referenced within your repository.
  • Once you’re ready to go, click the Start Deployment button at the bottom to start the transfer.

Deploybot - New Deployment

Another feature of Deploybot that I really appreciate is the Users section. If you’re working with other developers or subcontracting work out, this is perfect. You can give them access to make manual deployments.

The users tab shows everyone connected to your account.

Deploybot - User Listing

If you click on an individual, it will take you to a screen where you can manage that particular user’s setting individually. You can give them access to everything or limit their access to individual repositories.

Deploybot - User Access Settings

Migrating the Database

Now that we have our server set up, let’s talk about the database. As we alluded to earlier, the database is completely separate. In fact, it’s handled in a completely different language (MySQL). We have to find a way to sync the two. To do the initial setup, I’ll do everything manually. After that, the best way that I’ve found is to use a plugin called WP DB Migrate Pro. This plugin allows you to

  • Move your local version of the database ? to the server
  • Move the server’s version of the database ? to your local machine

— all from within WordPress. You don’t have to bother with logging into the server and using PHPMyAdmin, SequelPro, or some other tool.

Let’s go through everything step by step.

First, let’s get our initial database setup. I use a free program (for the Mac), called Sequel Pro to manage my local databases. If you’re using MAMP, you can also do this through phpMyAdmin.

NOTE:

On that thought — if you’re using MAMP, I walk through my entire MAMP set up in a separate blog post. There’s also a specific section about setting up Sequel Pro.

Connect to your local server.

Select your site’s database from the dropdown list.

Sequel Pro - Select site's database

Then, go to File > Export.

In our case, we want to export all the tables and save it to our Desktop. Click Export.

Sequel Pro - Export Database

Now, go to your server’s cPanel, and load up phpMyAdmin. Or, if you’re using something like Flywheel, go to the Advanced tab and click on Manage Database.

Flywheel - Manage Databases

I like to make a backup of the existing database, just in case. Click on the Export tab.

The default settings are fine. Scroll down to the bottom and click on the Export button.

Flywheel - Export Database

Next, click on the Database tab. Select all the tables and click on the Drop button the bottom of the screen.

Flywheel - Select all Tables

Now, we need to upload the database from our local machine. Click on the SQL tab.

Click on the Choose Files button and select the local database export. We saved it to our Desktop, remember? Then, click on the Execute button.

Flywheel - Choose SQL File to Upload

There are two settings within our database that we need to adjust. Click on the Database tab and click on the wp_options table.

NOTE:

You can add a prefix to your WordPress tables, so the table might be something like wp_iwh27hj1ne_options instead. That’s the same table we’re looking for.

Flywheel - Edit Options Table

Now, click on the Select Data tab and click on the edit link next to the siteurl row.

Flywheel - Edit siteurl

Since this data came from your local machine, it should reference the URL that you were using for local development. Probably, something like, http://selfteachme.dev. We need to update that to reflect the production URL: http://selfteach.me. Once you’ve adjusted the text, click on the Save button at the bottom.

Flywheel - Submit siteurl Changes

Now, we need to click on the edit link next to the home row. Same thing.

Flywheel - Change home url

Change the URL to the production URL and click on the Save button at the bottom.

Flywheel - Submit home url changes

Awesome! Now, when you go to the production URL, you should be able to see your site.


Troubleshooting

If you’re still having trouble loading your site, here are a few things to check for:

By default, WordPress will use absolute URLs. This means, when you’re working on your local machine, WordPress will use your development URL for everything, probably something like: http://selfteachme.dev. That’s not helpful! Remember, the Internet can’t access http://selfteachme.dev. Within your database, you’ll need to find and replace all the references to your development URL and change it to point to the production URL.

At first glance, it may seem you dodged this bullet. But, I would encourage you turn off MAMP (if that’s you’re using MAMP) and double check your production site. Remember, you can access your local server’s URL because it’s on your machine, but the rest of the world can’t. If you forget this step, you could easily have a situation where your client comes to you and says, “the links and images on my site are broken.” And you say, “That’s funny, everything looks fine on my machine.” This is why!

Don’t worry, it’s pretty easy to fix. On your production server, you can install the Better Search and Replace plugin that will do all the heavy lifting for you.

WordPress Plugin - Better Search and Replace

The nice thing about this plugin, is you can check to run as a dry run, just to make sure that you entered everything correctly. Then, run the search and replace after you’ve confirmed the results.

Once you’ve updated your database, I would recommend deactivating and deleting this plugin. Now that everything’s set up, there are easier ways to get keep your database synced. Plus, if a hacker were to access your WordPress admin panel, they could do some major damage really easily with this plugin.


Check the table prefixes

If you’re using FlyWheel, they use a prefix on all their WordPress database tables. There are two options here:

  1. You can either keep the prefix that Flywheel provides and change all your table names
  2. You can remove the prefix, adjusting the database within Flywheel settings.

For security purposes, I would recommend keeping the prefix that Flywheel provides. Change your local machine’s database to use Flywheel’s convention before exporting your database.

You can install the Change Table Prefix plugin on your local machine and it will handle the change for you.

After you’ve made the change, I would recommend deactivating and removing the plugin. It should be a one and done thing so you shouldn’t need it again. Plus, if a hacker were to access your WordPress admin panel, they could do some major damage really easily with this plugin.


Sometimes, you’ll notice that when you visit your site’s home page, everything loads as you’d expect, but all the other links on your site aren’t working. Strange, I know. In this situation, I would recommend logging into your production server’s WordPress Admin panel and going to Settings > Permalinks. Sometimes, your permalinks setting gets corrupted and doesn’t transfer as you’d expect (or hope). This is easy to fix. You can simply change the setting to Plain, click Save Changes and then immediately change it back to what you had initially (probably Post Name) and click Save. When you do this, WordPress will rewrite your permalink settings in your .htaccess file, thereby resolving any issues related to your permalink settings.


If your repository just contains your WordPress theme…

You also need to move your WordPress plugins (we’ll get into uploads later). I usually just resort to FTP. This may seem like the old fashioned way, but it’s a one and done thing and easy to resolve quickly.


If your repository contains your entire WordPress install…

You also need to move your WordPress uploads folder. Don’t worry, we’ll talk about uploads later in this post.


You may have noticed, this is a lot of work…

Yes, initially. But, now that you’ve got everything set up, there’s an easier way to sync your database, as you continue to make site updates, either to your local machine or the server, you need to be able to sync the two.

As I mentioned, earlier, I use a plugin called WP DB Migrate Pro. This plugin allows you to go both ways:

  • Move your local version of the database ? to the server
  • Move the server’s version of the database ? to your local machine

— all from within WordPress. You don’t have to bother with logging into the server and using PHPMyAdmin, SequelPro, or some other tool.

Unfortunately, this is a premium plugin. I usually just purchase the Developer license and install it on all the sites that I work on.

WP DB Migrate Pro Pricing

So, how does this plugin work? You’ll need to make sure that the plugin is installed and activated on both the production server and your local machine.

Once it’s installed and activated, go to Tools > Migrate DB Pro. You’ll want to click on the Settings tab.

You’ll need to adjust the setting for both installs.

Enter your License key.

Next, make sure that you have the proper permissions turned on. For simplicity’s sake, I went ahead and turned on Push and Pull.

Push means that you’re going to push data from the other site to the current site, (in this instance) overwriting the database on our local machine.

Pull means that we’re going to pull data from the current site to the other site. (In this instance) overwriting our production server.

I know, it can be a little confusing. I’m always paranoid that I’m going to overwrite the wrong database. But, there’s an option to backup before migrating. Sometimes, for security purposes, I won’t turn on both push and pull on the production server, to make sure that it doesn’t get overwritten by accident.

Before, we move on to the next screen, take note of the Connection Info. This is the key that gives the server permission to run. We’ll need to copy and paste the connection key from our local server to the production server and vice versa.

WP DB Migrate Pro Settings

Let’s look at some of our Migrate settings.

Remember, we’re working from our local machine. Say we want to move our local database to the production server. We’ll choose the Push option. The description should help clarify the difference between push and pull (in case you’ve forgotten). We’re pushing, or replacing, the remote database with this site’s database.

NOTE:

Now’s a good time to mention, you can’t be on the production server and pull data from your local machine. Why? Our development domain is not accessible to the rest of the Internet. Your production server won’t be able to find it.

Copy the Connection Info from your remote server and paste it into the Connection Info text area.

Moving through the rest of the settings, there’s a Find and Replace section. This is nice because the plugin will take care of adjusting all your URLs. Remember, how when we did the initial set up, we had to adjust the siteurl and home fields in the database. No more! WP DB Migrate Pro handles all of that for us! The plugin is typically able to pull the file path information it needs through the Connection Info information we provided.

I like to check the Backup the remove database before replacing it. You know. Just in case.

I’ll also opt to Save the Migration Profile. I’ll give it a name that makes it easier to remember what I’m doing, like: Replace PRODUCTION with THIS. In the future, when you load the Migration tab, it will show your saved profiles (or give you the option to start fresh). Smarter, not harder.

When you’re ready, click the Push & Save button.

WP DB Migrate Por - Migration Settings

Bam! WP DB Migrate Pro handles the migration for you. See? Wasn’t that much easier than using PHPMyAdmin or Sequel Pro and doing everything manually? Unfortunately, you still have to move everything manually for the initial set up, but after that it gets a lot easier


It’s not a true sync

I’ll be honest, sometimes this is one of the more frustrating parts of a project, especially, if you’re working with multiple people.

For example, I may be working locally, developing a site, but have a virtual assistant or a client updating the content on the server, simultaneously. There has to be one single source of truth. What does that even mean? Well, if I make changes that effect the database on my local machine, I can’t replace the server’s version with my database. I would overwrite any content that someone else has published. — And vice versa. I can’t use the server’s database to replace the version on my machine. All the work I’ve done will get replaced.

Unfortunately, there’s no easy answer here. You just have to be aware if multiple people are working on the site at the same time. Usually, I’ll make the production server the “Source of Truth.” Any changes I make to the database, I’ll make sure I make them to production and then pull those changes down to my local machine. It’s an extra step, but it keeps things nice and clean.

Now that we’ve talked about your ✅ WordPress files and ✅ the database, there’s still your uploads folder that needs to be accounted for.

Handling File Uploads

As always, there are several different options:

FTP

This is “the old fashioned way”, but it gets the job done. I usually don’t try and keep this folder synced with the production server, so this is a one and done thing. I’ll simply pull up Transmit (my FTP client of choice) and manually move my local machine’s uploads over to the production server.

WP DB Migrate Pro, Media Files Add On

If you purchased a Developer license to WP DB Migrate Pro, you’ll have access to their add on for Media Files. This is very similar to the WP DB Migrate Pro plugin, except instead of handling your database files, it handles your file uploads. As I mentioned, I don’t try and keep these two folders synced, so I usually just default to FTP, but this is a good option if you’re trying to keep both versions synced.

Amazon S3

There are several plugins out there, that allow you to put your file uploads on Amazon S3. This is great from a performance standpoint. Your files are delivered faster because you’re using a CDN (or content distribution network) to serve your media. You’re not weighing down your hosting server, either, which makes your site faster. Double win!

As an added bonus, all your image / media links will be Amazon S3 links. — Meaning, if you’re developing locally and connected to the Internet, all your images will still display, as they would on your production environment.

But wait, it gets even better. The fine folks at Delicious Brains (the company that makes WP DB Migrate Pro) has another (premium) plugin called WP Offload S3. This will handle moving all your image uploads to Amazon S3 for you! I actually have this plugin installed on the SelfTeach.me site and I love it! It makes everything so easy. In my humble opinion, this is an obvious solution, unless of course, you’re trying to watch your cash flow, since you’ll be paying for the plugin plus the space on Amazon S3 (which is minimal).


Additional Resources

  • If you’re looking for other options, besides DeployBot, there’s [a great article on CSS-Tricks](https://css-tricks.com/deployment/) that lists several other methods.

The Conversation