(Moving WordPress, SSL Setup, DNS, and Fixing Every Real-World Error)
By the time your fresh WordPress install is running on Hetzner, the real adventure hasn’t even begun.
Installing WordPress on a VPS is easy — migrating your live site without breaking it is where the story gets interesting.
Part 1 – Shared Hosting to VPS — My Real Journey of Moving dtptips.com from Bluehost to Hetzner
In this post, I’ll walk you through exactly how I moved dtptips.com from Bluehost shared hosting to a Hetzner VPS, using Migrate Guru, fixing the classic “Error establishing database connection,” repairing broken layouts, enabling SSL via Certbot, and finally updating DNS — all the way until the site loaded perfectly from its new home.

📬 Step 1 — Preparing for Migration: Emails, Passwords & Safety Notes
Once you’ve set up your VPS (see Part 1), you’ll already have received that crucial Hetzner email containing:
- Your server IP
- The root username
- A temporary root password
Keep that email safe — it’s your lifeline.
Save these details in a password manager or encrypted notes app.
Never post them online or in screenshots.
Before starting migration, you’ll also need:
- The SFTP/SSH credentials of your new server
- Access to your old site’s WordPress dashboard on Bluehost
💡 Tip: It’s wise to temporarily pause any auto-backup or caching plugins before migration. It prevents half-migrated caches from corrupting the transfer.
🧰 Step 2 — Why I Chose Migrate Guru (and What It Actually Does)
When I first thought of migrating manually, I imagined a simple ZIP file and a database export.
Reality? Broken serialization, missing uploads, PHP timeouts, and file-size limits.
That’s when I discovered Migrate Guru by BlogVault.
It automates everything — compresses your site, transfers it to the destination via SFTP, unpacks, and reconfigures URLs — all within one interface.
What it does behind the scenes:
- Creates a temporary clone of your old site.
- Transfers it to your new server using SFTP.
- Updates database URLs automatically.
- Sends you an email once done.
No downtime. No manual import/export.
🚀 Step 3 — Running the Migration
On your old WordPress site (Bluehost):
- Install Migrate Guru from Plugins → Add New → Search “Migrate Guru” → Install → Activate.
- Open Migrate Guru → Migrate Site → Other Host.
- Fill in the details: Field What to Enter Why Destination URL
http://your_server_ip/The temporary IP where new WordPress runs SFTP Hostyour_server_ipAllows file transfer via SSH SFTP UserrootYour server login SFTP Password (your root password) Used once for file copy Port22Standard SSH port Destination Path/var/www/your_site_folder/Where WordPress is installed - Click Migrate and keep the tab open.
You’ll see live progress: “Creating Archive → Transferring Files → Restoring Database → Updating URLs.”
Depending on your site size, it may take 10–30 minutes.
Once complete, you’ll get an email confirmation saying:
✅ Migration completed successfully.
⚠️ Step 4 — The First Login and the First 500 Error
When I opened my IP address after migration, instead of my familiar dtptips layout, I got:
This page isn’t working.
HTTP ERROR 500
That’s usually a PHP or plugin conflict — common right after migration.
🧩 Cause
Caching or optimization plugins (like Autoptimize, LiteSpeed Cache, WP Rocket, SG Optimizer) were still referencing the old environment.
🛠️ Fix
- Go to
http://your_server_ip/wp-admin - Log in with your old site’s credentials (they migrate with the site).
- Deactivate all optimization or SSL plugins.
- Go to Settings → Permalinks → Save Changes twice.
Saving permalinks forces WordPress to rebuild its rewrite rules for the new Nginx environment.
After doing that, the homepage loaded — though the layout still looked strange.
🎨 Step 5 — Why the Layout and Images Broke
The site opened, but everything was plain text — no styling, no images, just bare HTML.
When I inspected the page (right-click → Inspect → Network tab), I saw that CSS and image files were still loading from:
https://dtptips.com/wp-content/...
But the site was currently served from:
http://your_server_ip/
Browsers block mixed (HTTPS ↔ HTTP) resources, so CSS never loads.
💡 Fix 1 — Replace Old URLs in the Database
You can do this directly via MySQL:
mysql -u root -p your_database_name
Then run:
UPDATE wp_options SET option_value = REPLACE(option_value,'https://dtptips.com','http://your_server_ip');
UPDATE wp_posts SET post_content = REPLACE(post_content,'https://dtptips.com','http://your_server_ip');
UPDATE wp_postmeta SET meta_value = REPLACE(meta_value,'https://dtptips.com','http://your_server_ip');
EXIT;
What this does:
Every reference to your old domain is replaced with your temporary IP so images, CSS, and JS files load correctly during testing.
After running these queries, refresh your homepage and press Ctrl + F5 — your site should now show proper styling and images.
💡 Fix 2 — The “Parent Theme Not Found” Problem
If you’re using a child theme (like Trending News based on WalkerPress), WordPress may lose the link between them.
To check, open your themes folder:
ls /var/www/your_site_folder/wp-content/themes/
If you see something like walkerpress-1 instead of walkerpress, rename it:
mv /var/www/your_site_folder/wp-content/themes/walkerpress-1 /var/www/your_site_folder/wp-content/themes/walkerpress
Then, in your dashboard, go to Appearance → Themes, temporarily activate a default theme (Twenty Twenty-Three), then switch back to your child theme.
That refreshes theme inheritance and restores your layout.
🔒 Step 6 — Installing SSL with Certbot (the Easy, Free Way)
Once your site works over HTTP, it’s time to enable HTTPS.
Hetzner doesn’t provide SSL by default, but Certbot from Let’s Encrypt makes it painless.
Install Certbot and the Nginx plugin:
apt install certbot python3-certbot-nginx -y
Then run:
certbot --nginx -d yourdomain.com -d www.yourdomain.com
What happens next:
- Certbot automatically contacts Let’s Encrypt servers.
- It verifies domain ownership via your Nginx configuration.
- It downloads and installs the SSL certificates.
- It updates your Nginx config to redirect HTTP → HTTPS.
You’ll see:
Congratulations! Your certificate and chain have been saved.
⚠️ Common SSL Mistake: Enabling HTTPS Too Early
Before I had a certificate, I enabled “Force SSL” inside WordPress.
The result? A loop of ERR_TOO_MANY_REDIRECTS.
If that happens:
- Edit
wp-config.phpand make sure these lines are set to HTTP until SSL works:
define('WP_HOME', 'http://your_server_ip');
define('WP_SITEURL', 'http://your_server_ip');
- Disable “Really Simple SSL” until after Certbot installation succeeds.
Once SSL works, change both to https://yourdomain.com.
🌍 Step 7 — Updating DNS Records to Point the Domain
Now the final step: connecting your domain name to the new VPS.
At your domain registrar (Bluehost → Domains → Manage DNS, or any other provider), edit or add the following:
| Type | Host | Value | TTL |
|---|---|---|---|
| A | @ | your_server_ip | 3600 |
| A | www | your_server_ip | 3600 |
This tells the internet that dtptips.com now lives at your Hetzner VPS.
Propagation usually takes 15–60 minutes.
During that time, some visitors may still reach the old site — that’s normal.
🧩 Step 8 — Final URL Cleanup After DNS Propagation
Once your domain points to the VPS, update URLs back from IP → domain:
mysql -u root -p your_database_name
Then:
UPDATE wp_options SET option_value = REPLACE(option_value,'http://your_server_ip','https://yourdomain.com');
UPDATE wp_posts SET post_content = REPLACE(post_content,'http://your_server_ip','https://yourdomain.com');
UPDATE wp_postmeta SET meta_value = REPLACE(meta_value,'http://your_server_ip','https://yourdomain.com');
EXIT;
Now every image, CSS, and internal link uses HTTPS again.
🧱 Step 9 — Permission Fix for Missing Images or 403 Errors
If uploads still fail or thumbnails appear broken:
chown -R www-data:www-data /var/www/your_site_folder
find /var/www/your_site_folder -type d -exec chmod 755 {} \;
find /var/www/your_site_folder -type f -exec chmod 644 {} \;
systemctl reload nginx
Why: This ensures your web server (user www-data) owns and can read all files.
If the wrong user owns them (for example root), WordPress can’t access uploads or theme assets.
🧩 Step 10 — Verifying SSL Renewal Automation
Let’s Encrypt certificates expire every 90 days.
Certbot automatically sets up a cron job to renew them.
You can test it manually:
certbot renew --dry-run
You’ll see “Congratulations, all renewals succeeded.”
That means SSL will stay active forever without manual renewal.
⚠️ Step 11 — Real-World Mistakes and What They Taught Me
| Mistake | What Happened | How I Fixed It |
|---|---|---|
Editing configs with nano on Windows | Console froze | Switched to WinSCP + Notepad++ |
| Forgot to deactivate cache plugins | Got 500 error after migration | Logged in via IP, deactivated all optimization plugins |
| Enabled SSL too early | ERR_TOO_MANY_REDIRECTS | Disabled “Force SSL” until Certbot finished |
| Parent theme folder renamed | Layout & CSS disappeared | Renamed back to walkerpress and reactivated theme |
| Wrong file permissions | 403 errors on images | Reset with chown + chmod |
| DNS cached locally | Old site kept opening | Flushed DNS (Windows → ipconfig /flushdns) |
Every one of these cost me an hour the first time — and five seconds the next time.
🧠 Step 12 — Optional: Speed & Security Tweaks
Once everything works, consider these optimizations:
- Install UFW firewall to allow only SSH (22), HTTP (80), HTTPS (443):
ufw allow 22; ufw allow 80; ufw allow 443; ufw enable - Enable Redis Cache for database acceleration.
- Use Fail2Ban to block repeated failed logins.
- Set up automatic backups using a cron job or plugin like UpdraftPlus.
🏁 Final Checklist — Your Migration at a Glance
✅ VPS deployed and secured
✅ WordPress installed and tested
✅ Site migrated using Migrate Guru
✅ 500 error fixed by disabling cache plugins
✅ Database connection verified
✅ Images & CSS restored by URL replacement
✅ SSL installed via Certbot
✅ DNS updated to point to new VPS
✅ Automatic SSL renewal verified
Your site now runs on a fast NVMe VPS with full control and a clear upgrade path — all at roughly half the cost of shared hosting.
💬 Final Thoughts
Migrating dtptips.com from Bluehost to Hetzner taught me that VPS hosting isn’t about complexity — it’s about control.
At first, every command feels intimidating. But once you understand what each line does, you realise it’s just logic: fetch, configure, reload, verify.
The site now loads faster, handles more traffic, and feels future-proof.
And the best part? Every issue you fix manually once becomes permanent knowledge.
⚠️ Disclaimer
All examples and commands are provided for educational purposes.
Replace placeholders such as your_server_ip, yourdomain.com, your_database_name, and your_password with your own secure values.
Never share actual credentials publicly.
dtptips.com and the author accept no responsibility for misuse or data loss from incorrect configurations.
#WordPress #Migration #Hetzner #Bluehost #SSL #VPS #DNS #dtptips #Tutorial