Using Git in WordPress development and the right project migrating to D2C

Anybody who works with Git has already appreciated the benefits of such a tool. You can easily roll back damaging changes, establish collaboration between dozens of developers and transparently monitor all changes that occur with the code.

It just so happens that the vast majority of developers who use WordPress don’t use the tool. This is partly due to the lack of a built-in “development staging production” model inside the engine.

Artyom Zaytsev


In fact, there is an advanced version of the WordPress implementation called Bedrock, but its use requires a more detailed exploration and I’ll tell you about the solution in the next articles.

Learn more about Bedrock

Migrating a project to production forces you to do a lot of manual actions that do not allow you to fully integrate Git into the development cycle. Roughly speaking, to change the code on the local machine and upload files using FTP much easier. I will illustrate to what problems such an organization of work leads.

The usual method of deploying a WP project to Production

The method has some disadvantages:

  1. If you need to deploy a copy of the site locally, you will have to download all the static files: images, documents, etc.
  2. The actual changes in the production version and the local cannot be controlled. The task comes much more difficult if you connect several developers. It means that you should download the source of the application for a short time and every time.
  3. If you made a lot of changes on the local machine, then uploaded them to a working project and found errors, the site may stay broken for a very long time until you understand the reason. In the case of Git, there’s no problem to rollback the version.

Deploying the WP project directly to Production from Git

Such the method is devoid of the above disadvantages:

  1. The application is organized in such a way that all the static files are stored on a separate file server, not need to download/upload files from/to FTP.
  2. The version is always up to date, and its changes are under control. It is enough to a new developer to clone the repository, to carry out a couple of simple steps and get to work.
  3. If there were changes that broke the project in production (well, for example, you are a kind of fearless man who deploys everything in production without testing), you can roll back the version without problems.

There are two points that prevent you to deploy WordPress directly from Git: strictly specified paths and storing the uploads directory inside the engine. If these limitations are removed, using Git will be easier.

Creating 2 versions of the configuration for development and production

To push and deploy directly from Git, we should create 2 configs with different DB credentials and settings. To do that, we need to take as the basis the default config.

To do that, we need to take as the basis the default config. Let’s copy it a couple of times and rename it to “production-config” and “local-config”. The first one is for Git, the second one for local development.

Now we should check if the “local-config” file exists. If it is not available, the “production-config” will be used.

if ( file_exists( dirname( __FILE__ ) . '/local-config.php' ) ) {

include( dirname( __FILE__ ) . '/local-config.php' );

define( 'WP_LOCAL_DEV', true );

} else {

include( dirname( __FILE__ ) . '/production-config.php' );


In the local config, Also let’s turn on the display of errors and warnings to simplify the debug process.

define('WP_DEBUG', true);

@ini_set('display_errors', 1);


In both configs, it is necessary to write the corresponding DB credentials.



In order not to replace the site address in the database every time, we will specify the site address and the main page strictly. For a local site, the address will be http://wordpress, for production, for example,



To correctly functioned SSL in “Production-config”, we’ll specify:

$_SERVER['HTTPS'] = 'on';
define('FORCE_SSL_ADMIN', true);
define('FORCE_SSL_LOGIN', true);
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)

To push into the Git only the necessary files, we should forbid indexing a number of files in .gitignore:


Done. Now in the Git will only the app: no static files and no local config.

Move all the static files to a separate server

Statics are better to be stored separately. For this purpose, we could use AWS, as there is a ready-made plugin. Alternatively, I use Selectel.


To use AWS, you will need an Offload S3 plugin. To configure the plugin to work with your buckets, you need to specify in wp-config.php access keys of your Amazon account.

Access ID and Secret key can be obtained in the section “My security credentials” in your personal account.

After the steps, you may create a bucket directly from the plugin.

Or you may choose from existing ones.

When you select a Bucket, AWS and the detailed settings page are activated. I usually prefer not to store static on the application server, so I choose the next option.

Any images and attachments will now be stored on a remote AWS server.

If you need to synchronize a batch of existing files with AWS, you’ll need to purchase a paid version of the plugin.


To store statics on Selectel you need a plugin called “Selectel Storage Upload”. You will need to create a public container to configure it.

Then create a user with write access to this container.

After that, you should take the login, password, and the name of the container and specify them in the plugin settings page.

To replace all links on the site, you need to specify the Full URL-path. In your case, it will be As you see, the content will be distributed via CDN.

If you don’t want to store files on the application server, check the “Store files only in the Selectel storage” box.

In conclusion

After these steps, you can easily place your project in Git and deploy directly from there. In D2C you should just specify the link to the project’s Git for that.

Now all the static is stored on a separate file server, and local and production configs are separated. Next time I’ll tell you how to use Bedrock and do not store database credentials in Git. Have good commits!