How to Recover a Site When Only the Files Survive

How to Recover a Site When Only the Files Survive

To restore a website from a files only backup, you rebuild the missing pieces around the files you still have: the database, the configuration, and the metadata that told your old tooling what belonged where. The files are the hard part to recreate, so treat them as the source of truth and reconstruct everything else to match them.

What a Files Only Backup Actually Contains

Most site backups are a bundle of three things: the document root, a database dump, and a manifest describing paths, ownership and sometimes checksums. When only the files survive, you usually have the first and neither of the other two. That means you have the code, the themes, the plugins and any user uploaded media, but not the rows that map those uploads to posts, not the users table, and not the settings that lived in the database.

Start by taking an inventory before you touch anything. Work on a copy, never on the only surviving set.

$ find ./site-files -maxdepth 2 -type d | head -40
./site-files
./site-files/wp-content
./site-files/wp-content/uploads
./site-files/wp-content/themes
./site-files/wp-content/plugins

That shape tells you a lot. A wp-content tree with uploads, themes and plugins is a conventional content management layout. A bare public_html with index.php and an app directory is a custom application. The directory names are your first clue about what has to be recreated.

Look for leftover configuration files, because they often survive even when the database does not. A wp-config.php, a .env, a config/database.php or a settings.py may still hold credentials, a table prefix, or a cache salt. Copy those values somewhere safe before you overwrite anything.

Reconstructing Configuration From the Files

Configuration is the part people panic about, but the files frequently document themselves. If the application reads an environment file, that file names every variable it expects. If it does not, the code that reads configuration will.

$ grep -rn "getenv\|process.env\|ENV\[" ./app --include=*.php --include=*.js | head
./app/bootstrap.php:12: $dbHost = getenv('DB_HOST');
./app/bootstrap.php:13: $dbName = getenv('DB_NAME');
./app/bootstrap.php:14: $dbUser = getenv('DB_USER');

Each hit is a variable you must supply. Grep for the database layer specifically, because the connection details are what you need first. Then write the configuration file the application expects, using the paths and names you found. Do not guess a table prefix: search the code for it, since a hardcoded prefix in a query will not match a database you create with a different one.

If the application stored its schema in migration files, you are in good shape. A directory of numbered migration scripts is a complete, ordered description of the database structure. Run them in order against a fresh database and you get the tables back, empty but correctly shaped.

Rebuilding the Database When There Is No Dump

Without a dump you rebuild the schema from migrations or from the code, then repopulate it from the files. The schema is mechanical. The content is the interesting problem.

Uploaded files usually carry their own metadata. Image formats embed dimensions and often a timestamp. Many content systems also store a record of each upload in the database, but if that table is gone, you can regenerate it by walking the uploads directory and inserting a row per file, then letting the application re-derive thumbnails. The original post to which an image was attached is often unrecoverable, so plan to re-link media by hand or accept orphaned files.

Text content is the real loss. If the database held the posts, the files will not contain them unless the site cached rendered pages. Check for a cache directory, a static export, or a search index. A cached HTML page is a faithful copy of what a visitor saw, and you can parse the body out of it.

$ grep -rl "<article" ./cache | wc -l
$ python3 -c "import sys,re; \
print(re.sub('<[^>]+>','',open(sys.argv[1]).read()))" ./cache/post-1.html

That second command is crude, but it shows the technique: strip the markup and you have the text. Do this for every cached page, collect the results, and reinsert them. It is tedious and it will not recover metadata like authors or publish dates, but it recovers the words.

Recreating Users and Access

User accounts almost never survive a files only loss, because password hashes live in the database. Do not try to recover the old hashes. Instead, create a fresh administrative account through the application's own mechanism, which is usually a command line tool or a one time setup script. Then reissue credentials to real users and force a reset.

If the application supports sign in through an external identity provider, check whether the files contain the client identifier and issuer URL. That configuration is often in a plain file, and restoring it lets users sign in without any local password at all.

Verifying the Restore Before You Go Live

Bring the site up on a hostname that is not public, then walk it. Request the home page and confirm a 200. Request a page that should not exist and confirm a 404, because a misconfigured rewrite rule will happily return the home page for every URL.

$ curl -sI https://staging.example.com/ | head -1
HTTP/2 200
$ curl -sI https://staging.example.com/no-such-page | head -1
HTTP/2 404

Check that static assets load, that logins work, and that any scheduled task still points at a valid path. Then compare the rendered output against the cached pages you recovered, if you have them, to catch content that failed to reinsert.

What to Do Next

Once the site is stable, fix the reason you ended up here. Take a backup that includes the database and a manifest alongside the files, and test a restore on a throwaway host so you know the archive is complete before you need it. Keep at least one copy off the machine that runs the site, and verify it periodically rather than trusting that it exists.

Related articles

Subscribe to our newsletter

Get the latest hosting tips, performance insights, and industry news.