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:
- PHP
- Bedrock
- Local (by Flywheel) or your preferred local server
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
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.
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:
define(‘ABSPATH’, …);
Config::apply(); // ✅ Safe, because ABSPATH is needed early
In newer Bedrock boilerplates, they changed it to:
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..