How to Restore a Backup When the Host Has No Restore Tool
To restore backup without a host restore tool, you rebuild the site yourself: put the files back where the web server expects them, load the SQL dump into a database, and rewrite the configuration so the application points at the new database. The host panel may have no button for it, but the pieces you need are already in your backup, and everything below runs from a terminal you control.
Before touching anything, work on a copy. Unpack the archive into a scratch directory, never straight into the live document root, and keep the original archive untouched until the new site is serving correctly.
What a backup actually contains
Most backups are two things glued together: a file tree, usually a tarball or zip, and a database dump, usually plain SQL text or a compressed .sql.gz. The file tree holds the application code, uploaded media, and a configuration file with the database credentials baked in. The dump holds the rows. If you only have one of the two, stop and find the other, because a file tree with no database gives you a site that loads and then throws errors on every page, and a database with no file tree gives you rows nothing can read.
Unpack the file archive first and look at the top level. You want to see the document root, the directory the web server serves from. Sometimes the archive has an extra wrapper directory and sometimes it does not, and getting this wrong is the single most common reason a manual restore appears to work but serves a directory listing instead of the site.
tar -tzf backup.tar.gz | head -20
# look for index.php, wp-config.php, public_html/ or htdocs/
tar -xzf backup.tar.gz -C /tmp/restore
If the archive is a zip, unzip -l lists it and unzip extracts it. The principle is the same: list before you extract, and extract somewhere harmless.
Loading the database dump
Create an empty database and a user for it on whatever database server you are moving to. Then feed the dump in. Use the client binary, not a web based import form, because large dumps time out in browsers and truncate silently.
mysql -u dbuser -p dbname < dump.sql
# or, for a compressed dump:
zcat dump.sql.gz | mysql -u dbuser -p dbname
Two things go wrong here often enough to check for them. The first is a dump that begins with CREATE DATABASE and USE statements naming the old database, which will either fail on permissions or write to the wrong place. You can strip those lines, or import into the named database directly. The second is a dump that assumes a specific character set. If the source was utf8mb4 and you import with a different default, accented characters and emoji come back as question marks, and no amount of later fixing will recover them. Pass --default-character-set=utf8mb4 on the import if the dump does not set it itself.
After the import, confirm the row counts in a couple of the big tables against what you expect. A dump that half loaded is worse than one that failed loudly, because the site comes up and looks fine until someone opens an old page.
Pointing the application at the new database
The application does not care that the host changed. It cares that its configuration file names the right host, database, user and password. Find that file. For a typical PHP application it sits in the document root and is named something like wp-config.php or config.php. For a framework it may live in an environment file or a .env at the project root.
define('DB_NAME', 'dbname');
define('DB_USER', 'dbuser');
define('DB_PASSWORD', 'secret');
define('DB_HOST', 'localhost');
Change those four values to match the database you just created. If the application stores its own base URL in the database, and many content management systems do, you also have to update that value, or every link on the site will point at the old address. The honest way is a query against the options table or its equivalent.
UPDATE options SET option_value='https://example.com'
WHERE option_name IN ('siteurl','home');
Run that against the database you imported into, not the old one. If the site uses absolute URLs inside post content as well, those need the same treatment, which is usually a broader UPDATE with a REPLACE() on the relevant columns. Take a fresh dump before running any bulk replace, because a careless one corrupts serialized data, and serialized data is very hard to repair by hand.
Restoring files and permissions
Move the extracted tree into the document root. Preserve the directory structure exactly. Then fix ownership and permissions, because files extracted from an archive often arrive owned by whoever ran the extraction, and the web server user may not be able to read them or write to the uploads directory.
chown -R www-data:www-data /var/www/site
find /var/www/site -type d -exec chmod 755 {} \;
find /var/www/site -type f -exec chmod 644 {} \;
Replace www-data with whatever user your web server actually runs as, which you can confirm from the process list. Do not make everything world writable as a shortcut. That is how a restored site becomes a compromised site within days.
Verifying the restore
Serve the site and check it in layers. First, does the home page return 200 rather than a redirect loop or a blank screen. Second, does a page that reads from the database render real content rather than an error. Third, does an uploaded image load, which confirms the file paths and permissions are right. Fourth, does logging in work, which exercises write access to the database and to any session storage.
Watch the error log while you do this. A missing extension, a stale cached configuration file, or a database user without the right grants all show up there with a specific message, and reading that message is faster than guessing. If the site loads but looks unstyled, the theme or asset directory did not come across. If it loads but every page 404s except the home page, the rewrite rules are missing, which usually means the web server configuration from the old host needs to be recreated on the new one.
Once the site is verified, take a fresh backup of the working state and store it somewhere other than the server. The next restore will be easier because you will know exactly which files matter and which configuration values have to change. If you are unsure whether a step is safe, test it against a copy first, and only then repeat it on the live site.
