How to migrate your website from another hosting to a Hostini VPS

Technical guide to migrate WordPress, PHP or static websites from shared hosting (cPanel, Plesk, or proprietary panels) to a Hostini VPS without downtime.

Migrating a website from shared hosting to a VPS is a common upgrade: you move from an environment with shared resources, opaque CPU/memory rules and generic panels to a dedicated machine where you control the entire stack. The performance gain is real, but the migration process has pitfalls — misconfigured DNS takes the site down, an incorrectly exported database corrupts data, and missing files break the WordPress theme.

This tutorial covers the complete path to migrate from shared hosting providers to a Hostini VPS running Ubuntu 24.04. The focus is PHP/MySQL sites (WordPress, Magento, Laravel, static sites with forms), but the process applies to any web stack. Reserve between 2 and 4 hours for full execution on a first attempt, and read the entire tutorial before starting — some steps need to be prepared in parallel.

The general strategy is: bring the site up on the VPS in parallel with the old one, validate everything via your local hosts file, and only then change the DNS. This way you never have the site offline and have immediate rollback in case something goes wrong.

Prerequisites

What you need before starting

A Hostini VPS provisioned with Ubuntu 24.04 LTS and SSH access as root. Access to the old hosting’s control panel (cPanel, Plesk or proprietary) with permission to create backups and export the database. Access to your domain registrar’s panel (Registro.br, GoDaddy, etc) to change nameservers or A records. A local SSH client (Terminal on Linux/macOS, or Windows Terminal with OpenSSH).

Note down the VPS details before starting — you will use them several times:

VPS IP address 45.xxx.xxx.xxx
SSH user root
Default SSH port 22
Operating system Ubuntu 24.04 LTS

Inventory of the current site

Before touching anything, map out what exists on the old hosting. Missing a configuration file or a database table in the middle of the migration costs hours of rework.

01

List all domains, subdomains and hosted applications. On cPanel, this appears under “Domains” and “Subdomains”. Also note the PHP version each application runs — legacy sites may need PHP 7.4 or 8.0, while recent WordPress runs on PHP 8.2+.

02

Identify active databases. In phpMyAdmin, note the name of each database and its approximate size. Databases above 1 GB require command-line export — phpMyAdmin chokes on large files.

03

Record external credentials the site uses: payment APIs, SMTP, CRM integrations. These credentials will need to be revalidated at the destination — some APIs lock access when the source IP changes.

Full backup of the source

The backup is the point of no return. Verify each generated file before proceeding.

04

Connect via SSH to the old hosting (if you have access) and generate a compressed archive of the public directory:

cd ~
tar czf site-backup.tar.gz public_html/

This creates a single file containing the entire site structure. On cPanel hosts, the default directory is public_html — on other panels it may be httpdocs, www or similar.

05

Export the database via mysqldump:

mysqldump -u db_user -p database_name > database.sql

If the hosting does not allow direct mysqldump, use phpMyAdmin: select the database, go to “Export”, choose SQL format and check “Add DROP TABLE” — this ensures reimport works even if the destination database already has empty tables.

Check file sizes

Confirm that site-backup.tar.gz and database.sql are not truncated. An ls -lh reveals the size — if database.sql is 0 bytes or much smaller than expected, the export failed silently (common when the PHP execution time limit is exceeded on large databases).

06

Download the files to your local computer with scp (or via the panel’s file manager if you do not have SSH):

scp [email protected]:~/site-backup.tar.gz ./
scp [email protected]:~/database.sql ./

Preparing the Hostini VPS

With the backup in hand, install the minimum stack on the VPS before uploading the files. For WordPress and most PHP sites, this means nginx, PHP-FPM and MySQL.

07

Connect to the VPS and update the system:

ssh [email protected]
apt update && apt upgrade -y
08

Install the full web stack:

apt install -y nginx mysql-server php8.3-fpm php8.3-mysql \
  php8.3-curl php8.3-gd php8.3-mbstring php8.3-xml php8.3-zip \
  certbot python3-certbot-nginx unzip

This bundle covers 95% of PHP sites in production. If your CMS requires specific extensions (imagick, redis, memcached), install them as well.

09

Configure MySQL with a strong password:

mysql_secure_installation

Answer “Y” to all security options. Note down the MySQL root password — you will need it.

Transferring the files

10

Send the files from your local computer to the VPS:

scp site-backup.tar.gz [email protected]:/var/www/
scp database.sql [email protected]:/root/

On slow connections, consider compressing the .sql before sending: gzip database.sql shrinks the file by 70-80% for databases with text data.

11

On the VPS, extract the site into the web directory:

cd /var/www/
tar xzf site-backup.tar.gz
mv public_html yoursite.com
chown -R www-data:www-data yoursite.com
chmod -R 755 yoursite.com
12

Create the database and import the dump:

mysql -u root -p

Inside the MySQL prompt:

CREATE DATABASE yoursite CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'yoursite_app'@'localhost' IDENTIFIED BY 'strong_password_here';
GRANT ALL PRIVILEGES ON yoursite.* TO 'yoursite_app'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Import the dump:

mysql -u root -p yoursite < /root/database.sql
13

Update the database credentials in the site’s configuration file. For WordPress, edit wp-config.php:

nano /var/www/yoursite.com/wp-config.php

Adjust DB_NAME, DB_USER and DB_PASSWORD to the values created in the previous step. For Laravel or other frameworks, edit the matching .env.

Nginx configuration

14

Create the site’s configuration file:

nano /etc/nginx/sites-available/yoursite.com

Paste the base configuration:

server {
    listen 80;
    server_name yoursite.com www.yoursite.com;
    root /var/www/yoursite.com;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}
15

Enable the site and test the configuration:

ln -s /etc/nginx/sites-available/yoursite.com /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx

nginx -t validates the syntax before the reload — always run it. A syntax error in a config file takes down every site served by nginx.

Validation before DNS

Test via the hosts file before touching DNS

Edit /etc/hosts on your computer (or C:\Windows\System32\drivers\etc\hosts on Windows) and add a line mapping the domain to the VPS IP. This way only your browser resolves the domain to the new VPS — visitors continue to see the old version. This lets you test everything without exposing the migration.

Add to the hosts file:

45.xxx.xxx.xxx  yoursite.com www.yoursite.com

Open http://yoursite.com in the browser. If the site loads correctly, navigate through all main pages, sign in to the admin panel (if it is a CMS) and test forms. Visual errors at this stage indicate missing files — check permissions on /var/www/yoursite.com/wp-content/uploads/ or equivalent.

HTTPS before DNS points over

16

Generate the SSL certificate via Let’s Encrypt. Since DNS still points to the old hosting, use manual DNS validation mode:

certbot certonly --manual --preferred-challenges dns \
  -d yoursite.com -d www.yoursite.com

Certbot will ask you to create TXT records in your DNS. Create them on the registrar’s panel, wait for propagation (usually 1-5 minutes), and confirm in certbot.

17

Update nginx to use SSL. Edit the configuration file and replace the server block with:

server {
    listen 443 ssl http2;
    server_name yoursite.com www.yoursite.com;
    ssl_certificate /etc/letsencrypt/live/yoursite.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yoursite.com/privkey.pem;

    root /var/www/yoursite.com;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }
}

server {
    listen 80;
    server_name yoursite.com www.yoursite.com;
    return 301 https://$host$request_uri;
}

Reload nginx: systemctl reload nginx.

DNS change

With everything validated, it is time to point the domain to the VPS. Access the registrar’s panel (Registro.br for .com.br, or another) and change the domain’s A record to the VPS IP.

Lower the TTL before the switch

If possible, lower the A record’s TTL to 300 seconds a few hours before the change. This shortens propagation time — instead of hours, the change appears within minutes for most visitors.

Remove the local /etc/hosts entry to test real resolution. Use tools such as dig yoursite.com +short (Linux/macOS) to verify the correct IP is propagating.

Verification

After DNS propagation, validate the production environment:

curl -I https://yoursite.com

The response should show HTTP/2 200 and valid SSL headers. Also verify on SSL Labs (ssllabs.com/ssltest/) that the certificate grade is A or A+.

Monitor the site during the first 48 hours: nginx logs at /var/log/nginx/access.log reveal 500 errors, and Google Search Console shows whether there is an abnormal traffic drop (usually there is not, if the migration was done correctly).

Troubleshooting

Site shows “Error establishing a database connection”

Confirm MySQL is running: systemctl status mysql. If active, verify the credentials in wp-config.php (or equivalent) match the ones created for the database. Passwords with special characters sometimes need to be escaped.

Images do not appear or 403 error

Wrong permissions on the uploads directory. Run:

chown -R www-data:www-data /var/www/yoursite.com
find /var/www/yoursite.com -type d -exec chmod 755 {} \;
find /var/www/yoursite.com -type f -exec chmod 644 {} \;

502 Bad Gateway error

PHP-FPM is not responding. Check with systemctl status php8.3-fpm. Also confirm that fastcgi_pass in the nginx config points to the correct socket for the installed version.

Next steps

With the site migrated and stable, consider adding layers of robustness to your VPS:

  • Configure automatic daily backups to avoid data loss in case of hardware failure.
  • Add uptime monitoring (UptimeRobot, BetterUptime) to be alerted if the site goes down.
  • Enable a firewall with ufw allowing only ports 22, 80 and 443.
  • Configure automatic SSL certificate renewal via cron: certbot renew --quiet weekly.
  • Consider using a CDN (free Cloudflare) in front of the VPS to speed up delivery and reduce load.

If you are migrating multiple sites at once or have high-availability requirements, a Hostini VPS offers automatic snapshots, additional IPs and included DDoS protection — useful to avoid the headache of volumetric attacks that take down shared hosting.

Frequently asked questions

How long does the full migration take?

For a typical WordPress site up to 5 GB with a small MySQL database (< 500 MB), the process takes between 2 and 4 hours — including backup, transfer, stack installation and DNS adjustment. Larger sites or multi-application setups may require a planned maintenance window.

Will I lose Google ranking during the migration?

No, as long as you keep the same URLs, properly redirect any paths that change, and configure HTTPS on the new VPS before pointing the DNS. Google recovers rankings within a few days if the content remains identical and the server responds quickly.

Do I need to shut down the old site before bringing up the new one?

No. The correct practice is to keep the old site running while you bring up a functional copy on the VPS, validate it via the hosts file or a temporary subdomain, and only then change the DNS. Keep the old hosting active for an additional 48-72h after propagation as a safety net.

How do I handle email accounts that were on the shared hosting?

A VPS does not include an email service by default. The recommendation is to migrate email accounts to a dedicated provider (Google Workspace, Zoho, Microsoft 365) before changing the DNS. Avoid setting up your own SMTP server on a new VPS — deliverability is low due to IP reputation.

What if the site uses PHP SMTP functions to send email?

Configure PHP to send via authenticated SMTP from a transactional provider (Amazon SES, Brevo, Mailgun, Postmark). Plugins like WP Mail SMTP on WordPress handle this without code changes. Avoid the native mail() function on a VPS — it almost never delivers.

What if I do not have SSH access on the old hosting?

Use the panel's file manager to create a .tar.gz archive of public_html and download it via HTTPS, and export the database via phpMyAdmin as raw SQL. It works but is slower — for large sites, request temporary SSH access from the old hosting's support team.

Topics:
Next steps Ryzen cloud with NVMe storage and always-on DDoS protection.Go live on a Hostini VPS →
Was this tutorial helpful?
Chat on WhatsApp