Skip to main content

Migrating from Shared Hosting to a VDS: A Step-by-Step Guide

Migration · 19.04.2026 · 5 min read
Illustration for “Migrating from Shared Hosting to a VDS: A Step-by-Step Guide”

Moving from shared hosting to a virtual dedicated server (VDS/VPS) is a natural step once a site outgrows its resource limits. A VDS gives you full root access, dedicated CPU/RAM resources, and the ability to fine-tune the environment to your needs.

When it's time to move from shared to a VDS

SymptomCauseSolution
Site slows down at peak hoursCompeting for resources with neighborsVDS with dedicated resources
503 errors / limits exceededShared CPU/RAM quotasVDS with no host-imposed limits
Can't install the PHP/Python version you needShared hosting controls the environmentFull root access on a VDS
Need cron to run every minuteShared hosting blocks frequent jobsAny cron schedule on a VDS
Multiple projectsExtra sites are expensiveUnlimited sites on a VDS

Preparing the VDS before migration

# Update the system (Ubuntu/Debian)
apt update && apt upgrade -y

# Install the web stack
apt install nginx php8.3-fpm php8.3-mysql php8.3-mbstring   php8.3-xml php8.3-curl php8.3-zip mariadb-server -y

# Start the services
systemctl enable --now nginx php8.3-fpm mariadb

Step 1: Create a backup on the shared hosting

# Via cPanel: Backup Wizard → Full Backup
# Or manually via SSH (if available)
tar -czf ~/backup-site.tar.gz ~/public_html/
mysqldump -u dbuser -p dbname > ~/backup-db.sql

Step 2: Transfer files to the VDS

># Download the archive from shared hosting to your local PC, then upload it to the VDS
scp backup-site.tar.gz root@YOUR-VDS-IP:/var/www/

# Or directly from shared hosting to the VDS via rsync
rsync -avz --progress user@shared-host:~/public_html/   root@YOUR-VDS-IP:/var/www/example.com/

# Extract
cd /var/www/
tar -xzf backup-site.tar.gz

Step 3: Restore the database

# Create the database and user
mysql -u root -p <<'SQL'
CREATE DATABASE mysite CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'StrongPass123';
GRANT ALL ON mysite.* TO 'myuser'@'localhost';
FLUSH PRIVILEGES;
SQL

# Import the dump
mysql -u myuser -p mysite < backup-db.sql

Step 4: Configure Nginx

# /etc/nginx/sites-available/example.com
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.php index.html;

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

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

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

Step 5: Test before switching DNS

># Add to /etc/hosts on your PC for testing
YOUR-VDS-IP example.com www.example.com

# Check the site in a browser without changing DNS
# After a successful test — revert hosts and switch DNS

Step 6: Switch DNS with zero downtime

Only change your DNS records after successfully testing the site on the VDS:

  1. Lower the A-record TTL to 300 seconds 24 hours before the migration
  2. Make sure the site works on the VDS (via /etc/hosts)
  3. Update the A record to point to your VDS IP
  4. Wait for DNS propagation (5–30 minutes with a TTL of 300)
  5. Keep the old hosting active for another 48 hours as a fallback
Zero downtime: With the TTL lowered properly and testing done via /etc/hosts, the DNS switch happens seamlessly for users — the site stays available the whole time.
Update the application config! After the migration, update wp-config.php (WordPress), .env, or other configs with the new database details. The old credentials from the shared hosting won't work.

Why move from shared hosting to VDS

Shared hosting limits CPU/RAM resources, forbids running background processes, and doesn't allow fine-tuning of PHP/MySQL. A VDS gives you full control.

💡 Signs it's time for a VDS: the site goes down at peak hours, you need cron jobs every minute, or you need PHP 8.2+ or Redis.

Step 1: Backup with cPanel

cPanel → Backup Wizard → Full Backup. Download the archive (.tar.gz) from the server.

Step 2: Installing the stack on the VDS

apt update && apt install -y nginx mysql-server php8.2-fpm   php8.2-mysql php8.2-gd php8.2-xml php8.2-mbstring php8.2-curl php8.2-zip

systemctl enable --now nginx mysql php8.2-fpm

Step 3: Importing the database

mysql -u root -p -e "CREATE DATABASE mydb CHARACTER SET utf8mb4;"
mysql -u root -p -e "CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'pass';"
mysql -u root -p -e "GRANT ALL ON mydb.* TO 'myuser'@'localhost';"
mysql -u root -p mydb < backup.sql

Step 4: Configuring Nginx + PHP-FPM

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

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

Checklist before switching DNS

CheckCommand
Site opens by IPcurl http://NEW_IP
PHP worksphp -r "echo phpinfo();" | head
MySQL is accessiblemysql -u myuser -p mydb -e "SHOW TABLES;"
SSL is configuredcertbot --nginx -d mysite.com
⚠️ Lower the DNS record TTL to 300 seconds 24 hours before the move — this speeds up propagation after changing the A record.
Was this article helpful?
← Back to Knowledge Base Ask Support