Migrate a Website from Shared Hosting to a Linux VPS

3 min
VPS/VDS Hosting

Moving a PHP/MySQL website to a VPS Linux Infrawire gives you dedicated resources and full control of the stack. The key to a painless migration is to prepare everything on the new server, test it before touching DNS, and only then switch traffic. This guide follows that order.

📋 Prerequisites

  • A Linux VPS with Ubuntu 24.04 or Debian 12 (the IP and root password are in your customer area)
  • Access to the shared hosting (file manager, FTP/SSH and a database tool such as phpMyAdmin)
  • Access to your domain's DNS zone
  • A domain example.com and your VPS IP, written VPS_IP below

1. Inventory the old site

Note what the site needs: PHP version, extensions, database name, cron jobs, .htaccess rules, SSL certificate and especially where your email is hosted. In the old control panel, check the PHP version; if you have SSH access:

Bash
php -v php -m | sort crontab -l

Also lower the TTL of your DNS records to 300 seconds now, at least a day before the migration, so the final switch is fast.

2. Export files and database

From the VPS you can pull the files directly if the old host offers SSH:

Bash
mkdir -p ~/migration && cd ~/migration rsync -avz OLDUSER@OLD_HOST:~/public_html/ ./site/

Without SSH, download an archive through FTP or the file manager and upload it with scp. Export the database with mysqldump (or the Export button of phpMyAdmin):

Bash
mysqldump --single-transaction -u DBUSER -p DBNAME > db.sql

3. Prepare the stack on the VPS

Bash
sudo apt update sudo apt install -y nginx mariadb-server php-fpm php-mysql php-xml php-mbstring php-curl php-zip php-gd sudo mysql_secure_installation php -v

Ubuntu 24.04 ships PHP 8.3 and Debian 12 ships PHP 8.2; the socket is /run/php/php8.3-fpm.sock or /run/php/php8.2-fpm.sock. Create the Nginx site in /etc/nginx/sites-available/example.com:

Nginx
1server { 2 listen 80; 3 listen [::]:80; 4 server_name example.com www.example.com; 5 root /var/www/example.com; 6 index index.php index.html; 7 8 location / { 9 try_files $uri $uri/ /index.php?$args; 10 } 11 12 location ~ \.php$ { 13 include snippets/fastcgi-php.conf; 14 fastcgi_pass unix:/run/php/php8.3-fpm.sock; 15 } 16}
Bash
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx

Nginx ignores .htaccess: translate its rewrite rules into the location blocks.

4. Import files and database

Bash
sudo mkdir -p /var/www/example.com sudo cp -a ~/migration/site/. /var/www/example.com/ sudo chown -R www-data:www-data /var/www/example.com sudo mysql -e "CREATE DATABASE dbname CHARACTER SET utf8mb4;" sudo mysql -e "CREATE USER 'dbuser'@'localhost' IDENTIFIED BY 'STRONG_PASSWORD';" sudo mysql -e "GRANT ALL ON dbname.* TO 'dbuser'@'localhost'; FLUSH PRIVILEGES;" sudo mysql dbname < ~/migration/db.sql

Then edit the application configuration (for example wp-config.php) with the new database name, user and password. The host is now localhost.

5. Test before the switch

On your own computer, point the domain to the VPS by editing the hosts file (/etc/hosts on Linux and macOS, C:\Windows\System32\drivers\etc\hosts on Windows):

Bash
VPS_IP example.com www.example.com

Or test without changing anything:

Bash
curl -I --resolve example.com:80:VPS_IP http://example.com/

Browse the site, log in, submit a form and check the logs in /var/log/nginx/error.log. Remove the hosts line afterwards.

6. Switch DNS and handle email

Freeze content changes on the old site, repeat the rsync and the database export/import to catch recent changes, then update the A record to VPS_IP and the AAAA record to the IPv6 address of the VPS. When DNS has propagated, issue the certificate:

Bash
sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx -d example.com -d www.example.com

Email: only change the A/AAAA records. Leave the MX, SPF and DKIM records untouched if your mailboxes stay at the old provider. Cancel the old hosting only after a few days without problems.

🔧 Troubleshooting

502 Bad Gateway
The PHP socket in fastcgi_pass does not match the installed version. Check with ls /run/php/ and systemctl status php8.3-fpm.

"Error establishing a database connection"
Wrong credentials or host in the config file. Test with mysql -u dbuser -p dbname.

403 or blank page
Check ownership and permissions (chown -R www-data:www-data), and look at sudo tail -n 50 /var/log/nginx/error.log and the PHP logs.

Old site still appears after the switch
DNS caches are still active. Check with dig +short example.com and wait for the TTL to expire.


✅ Your site now runs on its own VPS, migrated without downtime and with a safe way back.

Stay up to date with the latest offers, discounts and special promotions.

View promotions

We use cookies

We use analytics cookies to improve your experience on our site. No data is sold to third parties. Learn more in our privacy policy.