Select Page

How I Hardened My WordPress Setup Using Bedrock

With billions of websites getting hacked every year, I became increasingly concerned about the security of my WordPress installation. That’s when I decided to upgrade the structure of my WordPress project using Bedrock — a modern WordPress boilerplate developed by the Roots team.

Why Not Just Use Vanilla WordPress?

While standard (vanilla) WordPress works fine for many, it’s highly vulnerable to attacks — especially when all files, including sensitive configuration like wp-config.php, are located directly inside the public directory (public_html). This default setup exposes your site to common threats such as:

  • Database credential leaks
  • Plugin/theme injection
  • Arbitrary file inclusion exploits

By contrast, Bedrock separates the WordPress core, configuration, and content, making your site harder to compromise.

Prerequisites

Before you start, make sure the following tools are installed:

In this tutorial, I’ll walk you through the process of setting up a Bedrock-based WordPress environment, improving both your development workflow and your site’s security by keeping sensitive files out of the public directory and adopting modern development practices.

A: Replacing Standard WordPress To WP Bedrock on Local Flywheel

1. Installing Composer ( Bedrock Dependent)

First, you need to install the dependencies to make the Bedrock work.

2. Install A Flywheel Local For WordPress

Go to flywheel local to download the application. Run a regular WordPress website.

3. Run The Bedrock Project

Note: If you cannot see wp folder in your bedrock which usually happen if you install the old version, just run the

php


composer create-project roots/bedrock

⚠️ If you’re using an older version of Bedrock, the wp folder (which holds WordPress core files) might be missing. If that happens, just run composer install again inside the bedrock folder.

3A. Configuring the .env File

Bedrock uses a .env file to manage environment-specific settings, such as:

  • Database credentials (DB_NAME, DB_USER, etc.)

  • Table prefix (DB_PREFIX)

  • Authentication salts

Make sure your .env variables are set correctly. You can generate unique WordPress salts using roots.io/salts.

php


DB_NAME=’local’

DB_USER=’root’

DB_PASSWORD=’root’

DB_HOST=’localhost’

WP_CORE_DIR=’web/wp’

WP_ENV=’production’

WP_SITEURL=”https://testing2.local/wp/”

WP_HOME=’https://testing2.local’

Generate the auth to https://roots.io/salts.html

3B: application.php and .env Priority

While the config/application.php file controls how your app boots, the .env file should be treated as your environment-specific config — think of it as your new wp-config.php. To keep things dynamic, ensure application.php reads from .env. This allows for flexible deployments across development, staging, and production environments.

4. Adjusting site.config.hbs (for Local by Flywheel users)

By default, site.config.hbs may point to the root directory. Since Bedrock modifies the public web root to /web or a custom folder like /public_html/wp, you’ll need to:

  • Set an absolute path to the correct document root in your local environment. Find your absolute url e.g root ‘C:/Users/Windows 10/Local Sites/testing2/app/bedrock/web’;

  • Update this path again during deployment to your staging or production server.

B: Migrating Bedrock WP To Share Hosting

Let’s Migrate Your Bedrock To Shared Hosting!

⚠️ Situational: WordPress Database Error After Moving to Shared Hosting

In new version of WordPress bedrock, you might experience unstable database error due to how ABSPATH declared in the application.php

In older Bedrock versions (pre-2024), the loading order looked like this:

php


define(‘ABSPATH’, …);

Config::apply(); // ✅ Safe, because ABSPATH is needed early

In newer Bedrock boilerplates, they changed it to:

php


Config::apply(); // 🚨 Now comes before ABSPATH

define(‘ABSPATH’, …);

Make sure you follow the old version (pre-2024) especially if you’re deploying in Shared Hosting.

Why It Breaks in Real Deployments

  • In practice, many plugins and even parts of WordPress:
  • Still expect ABSPATH to be defined early
  • Use it during AJAX calls or redirects
  • Write files or load includes using ABSPATH

In hosting like Siteground or theme like Divi, usually a core hook runs during Config::apply() so usually it is expected to declare after the ABSPATH is declared so it won’t fails silently, or causes downstream issues like:

  • database error on save
  • exit builder crashing
  • 500 on post.php redirects

To learn more about how you can manipulate your WordPress plugins, themes and core files using ABSPATH approach, check my YouTube video here

C. How To Create A Staging Bedrock In Shared Host Like Hostinger And Siteground

Coming soon..