...

What to Do If a Website Won’t Open After Moving to a VPS: DNS, SSL, Firewall, Nginx, and the Database

Martin Klein

Reading time 1 minute

If a website does not open after being moved to a VPS, troubleshoot the issue layer by layer. Do not start changing every setting at once: first check DNS, then port availability, the web server, SSL, PHP, the database, file permissions, and CMS settings.

A basic post-migration checklist looks like this:

LayerWhat to checkWhy it matters
ClientWhether the site works on another device using a different internet providerThe problem is often investigated on the server, even though it may actually be on the client side
DNSThe domain points to the new IP addressIf the A record is still old, users will reach the previous server
ResolutionThe domain actually resolves to the correct IP addressDNS may not update for everyone at the same time because of TTL
FirewallPorts 80 and 443 are openEven a working Nginx instance will not help if the ports are closed
Web serverNginx or Apache is runningThe server must accept HTTP/HTTPS requests
Virtual hostThe domain is mapped to the correct directoryOtherwise, the wrong site, a 404 page, or the default page may open
SSLThe certificate has been issued and HTTPS worksSSL errors and redirects can break access
PHPPHP-FPM or PHP in Apache is workingWordPress and other CMS-based sites will not load without PHP
DatabaseThe CMS connects to the new databaseOtherwise, a database connection error will appear
FilesPaths, permissions, and hidden files have been migratedWithout .htaccess, .env, or correct permissions, the site may return 403/500 errors
CMSThe new domain is specified in the settingsThe old URL may cause a redirect loop or send users to the previous site

Symptoms help narrow down the search. A white screen is most often related to PHP errors, 403 to permissions or access restrictions, 404 to the virtual host, rewrite rules, or an incorrect directory, and 500 to an application error, .htaccess, PHP, or configuration files. A database connection error points to wp-config.php, .env, the database user, password, host, or database access permissions.

If some users see the old site while others see the new one, it is not always a server error. The cause is often DNS propagation, TTL, the local DNS cache, different resolvers, or old nameservers. That is why after migration it is important to check the domain using dig, nslookup, public DNS, and the local machine.

Before switching DNS, it is useful to test the site via the hosts file. This lets you open the new VPS by domain name before all traffic starts going to the new IP address. It helps you identify SSL, virtual host, PHP, database, path, uploads, and CMS issues in advance.

Common migration mistakes include changing nameservers without understanding TTL, forgetting to update .env or wp-config.php, failing to migrate hidden files such as .htaccess, not testing the site via the hosts file before switching DNS, and trying to fix everything at once without identifying the root cause.

The correct approach is to first make sure the domain points to the new IP address, then check ports 80/443 and the web server, then the virtual host and SSL, and after that PHP, the database, permissions, hidden files, and CMS settings. This turns migration from a chaotic search into a clear checklist.

Post-Migration Checklist

After moving a website to a VPS, it is best to troubleshoot from the top down: first check for client-side issues, then verify where the domain points, whether the server is reachable from the outside, and then check the web server, SSL, application, database, and CMS settings.

This approach helps avoid trying to fix everything at once. For example, there is no point in examining wp-config.php if the domain still points to the old IP address. Conversely, if DNS is already correct but the site returns a 500 error, the issue is most likely at the application, PHP, database, or permissions level.

Client-side check

The first thing to check is whether there are any issues on the client side. This could be a computer malfunction, the browser cache, ISP issues, entries in the hosts file, or various antivirus software.

The simplest way to check is to use another device, preferably with a different provider. For example, if you are testing from a computer over Wi-Fi, you can also test from a mobile phone using a cellular carrier.

Only once you are sure that the issue is not local but widespread should you proceed to diagnosing the server side.

DNS and the New IP Address

The first server-side item to check after the migration is whether the domain points to the new VPS IP address. If the A record still points to the old address, some users will continue to reach the previous server even if the new VPS is already fully configured.

You can check the A record as follows: dig A example.com +short

Or by using nslookup: nslookup example.com

If the domain should be accessible both with and without www, you need to check both versions:

dig A example.com +short

dig A www.example.com +short

It is important to account for TTL. After DNS records are changed, propagation can take time: different providers, resolvers, and users may still have the old IP address cached. As a result, if one user already sees the new site while another still sees the old one, this does not necessarily indicate a VPS issue.

Once DNS points to the new IP address, the next question is whether the server itself is accessible over HTTP and HTTPS.

80/443 and the firewall

Even if the domain points to the correct IP address, the website will not load if ports 80 and 443 are closed on the VPS. Port 80 is required for HTTP and for issuing a Let’s Encrypt certificate via an HTTP challenge; port 443 is used for HTTPS.

You can check the firewall on the server. If UFW is in use: sudo ufw status

A website typically requires the following rules:

sudo ufw allow 80/tcp

sudo ufw allow 443/tcp

You should also check whether the server is listening on these ports: sudo ss -tulpn | grep -E ‘:80|:443’

If 80/443 are closed at the provider control panel, security group, or external firewall level, the settings inside Linux may be correct, but the website will still be inaccessible from the outside.

After checking the network, make sure that requests are actually being accepted by the web server.

Nginx/Apache and virtual hosts

On a VPS, a website is usually served by Nginx or Apache. If the web server is not running, the domain may resolve to the correct IP address, but the browser will receive a connection error or an empty response.

Check Nginx: systemctl status nginx

Check Apache: systemctl status apache2

If the service is running, check the configuration. For Nginx: sudo nginx -t

For Apache: sudo apachectl configtest

The virtual host must be mapped to the correct domain and website directory. For example, in Nginx, it is important to check server_name and root:

server_name example.com www.example.com;

root /var/www/example.com/public;

If root points to the wrong location, the site may return a 404, a default page, or an empty directory. If server_name does not match the domain, the request may be routed to a different virtual host.

Once the web server accepts the request and routes it to the correct directory, check HTTPS. After a migration, SSL and redirects are often what make it seem as though the site “won’t open.”

SSL and HTTPS Redirects

After migrating to a VPS, the SSL certificate must be issued or reconfigured for the new server. The old certificate may have remained on the previous hosting service, while the new VPS may not yet be ready to accept HTTPS requests.

If you use Let’s Encrypt, Certbot is commonly used: sudo certbot –nginx -d example.com -d www.example.com

For Apache, the command may be different: sudo certbot –apache -d example.com -d www.example.com

Before issuing the certificate, the domain must already point to the new IP address, and port 80 must be accessible externally. Otherwise, the HTTP challenge may fail.

After issuing the SSL certificate, check the redirects. A common post-migration issue is a redirect loop: Nginx redirects to HTTPS, the CMS also redirects, the CDN adds its own SSL mode, and the browser ultimately sees endless redirects.

You can check the redirect chain as follows:

curl -I http://example.com

curl -I https://example.com

If SSL is working but the site still does not load, the next layer to check is PHP and the database.

PHP and the database

For WordPress, Laravel, OpenCart, and other dynamic websites, transferring the files is not enough. PHP must be running, the database must be imported, and the application must connect to it using the correct credentials.

If PHP-FPM is used, check the service: systemctl status php8.2-fpm

The version may differ: php8.1-fpm, php8.3-fpm, or another version.

Also make sure Nginx uses the current PHP-FPM socket or port: fastcgi_pass unix:/run/php/php8.2-fpm.sock;

For the database, verify that MySQL or MariaDB is running: systemctl status mysql

Also confirm that the database is accessible using the credentials specified in the CMS: mysql -u db_user -p database_name

For WordPress, the credentials are stored in wp-config.php; for Laravel and many other applications, they are stored in .env.

If the site displays Error establishing a database connection, the cause is often the database name, username, password, host, user permissions, or a database dump that was not imported correctly on the new server.

Once PHP and the database are working, the remaining step is to check the files. After a migration, a site may break because of paths, permissions, or hidden files that were not included in the transfer.

Paths, permissions, and hidden files

When migrating a site, it is important to preserve not only visible files but also hidden files: .htaccess, .env, .user.ini, framework configuration files, and other files whose names start with a dot.

If hidden files are not migrated, the site may behave unpredictably: rewrite rules may be missing, environment variables may not be loaded, routes may break, and 403, 404, or 500 errors may appear.

You can check for hidden files as follows: ls -la /var/www/example.com

Access permissions are also important. If the files are owned by the wrong user, the web server may be unable to read the site files or write to uploads, cache, and storage.

Example owner check: ls -la /var/www/example.com

For a typical setup using www-data, you can adjust ownership as follows: sudo chown -R www-data:www-data /var/www/example.com

However, this is not a universal rule for every project. Some control panels, Docker builds, and deployment workflows use a dedicated site user. The goal is not simply to grant permissions “to everything,” but to understand which user the web server or PHP-FPM runs as.

For WordPress, check wp-content/uploads separately. For Laravel, check storage and bootstrap/cache. For other CMSs, check the cache, logs, uploads, and temporary directories.

Once the files, permissions, and hidden files are in place, the final validation layer is the domain settings inside the CMS itself.

Domain in CMS Settings

After the migration, the site may technically work, but the CMS may still treat the old domain, old URL, or old path as the primary one. This can lead to redirects, broken links, mixed content, redirect loops, or redirects to the previous site.

In WordPress, check siteurl and home. You can do this via the database:

SELECT option_name, option_value

FROM wp_options

WHERE option_name IN (‘siteurl’, ‘home’);

If the domain has changed, update the values carefully. In WordPress, you can also temporarily set the URL in wp-config.php:

define(‘WP_HOME’, ‘https://example.com’);

define(‘WP_SITEURL’, ‘https://example.com’);

For Laravel and other applications, check the .env file: APP_URL=https://example.com

For online stores and CMS platforms, it is also important to check the base URL, canonical URL, cookie domain settings, upload paths, HTTPS settings, and redirects.

If the CMS still sees the old domain, the site may open on the new VPS, but individual pages, the admin area, styles, images, or forms may still point to the previous address.

Ultimately, the post-migration checklist should cover the entire chain: the domain points to the new IP address, ports 80/443 are accessible, the web server is running, the virtual host points to the correct directory, SSL works, PHP connects to the database, the files were migrated together with hidden files, permissions are correct, and the CMS knows the current domain.

Symptom-Based Troubleshooting

After a migration, a website may “fail to open” in different ways. Sometimes the browser shows a specific error code, sometimes it displays a blank white screen, and sometimes some users see the old version of the site while others see the new one.

That is why it is useful to start with the symptom rather than assumptions. The symptom helps you identify more quickly where to look for the root cause: DNS, the firewall, Nginx/Apache, SSL, PHP, the database, access permissions, or CMS settings.

White screen

A white screen after a migration is most often caused by an application, PHP, or CMS error. The server may be accepting requests and the domain may point to the correct IP address, but the application is not rendering a normal page.

In WordPress, this is often called the “white screen of death.” Possible causes include:

  • A PHP error after the migration;
  • An incompatible PHP version;
  • A plugin or theme was not migrated;
  • A broken wp-config.php file;
  • Incorrect file paths;
  • Insufficient memory for PHP;
  • An error in .htaccess or in rewrite rules;
  • File permissions prevent files from being read.

Start with the web server and PHP logs. For Nginx: sudo tail -n 100 /var/log/nginx/error.log

For Apache: sudo tail -n 100 /var/log/apache2/error.log

If PHP-FPM is used, check its status and logs:

systemctl status php8.2-fpm

journalctl -u php8.2-fpm -n 100 –no-pager

The PHP version may differ. On the server, it may be php8.1-fpm, php8.3-fpm, or another version.

For WordPress, you can temporarily enable debug mode in wp-config.php, but do so carefully: errors must not be displayed publicly on a production site.

define(‘WP_DEBUG’, true);

define(‘WP_DEBUG_LOG’, true);

define(‘WP_DEBUG_DISPLAY’, false);

After that, errors will be written to the log instead of being shown to visitors.

If the browser shows a 403, 404, or 500 status code instead of a white screen, diagnostics should shift to permissions, the virtual host, routes, and internal server errors.

403, 404, or 500

403, 404, and 500 errors after migration point to problems at different levels.

403 Forbidden usually means that the server understood the request but is not granting access. After a migration, this is often related to file permissions, directory ownership, a missing index file, or a restriction in the Nginx/Apache configuration.

You can check permissions and ownership like this: ls -la /var/www/example.com

You should also make sure the directory contains an index file:

index.php

index.html

404 Not Found may mean that the domain is mapped to the wrong virtual host, the root points to the wrong directory, rewrite rules were not migrated, or the CMS cannot handle pretty URLs.

For Nginx, check server_name and root:

server_name example.com www.example.com;

root /var/www/example.com/public;

For Apache and WordPress, .htaccess is especially important. If hidden files were not migrated, permalinks may break and internal pages may start returning 404 errors.

500 Internal Server Error is more often related to an application error, PHP, .htaccess, permissions, incompatible settings, or missing dependencies.

For a 500 error, the first thing to check is the logs:

sudo tail -n 100 /var/log/nginx/error.log

sudo tail -n 100 /var/log/apache2/error.log

If the site runs on PHP, also check PHP-FPM and the application logs.

These errors help confirm that the request has already reached the VPS. If the site shows a database connection error instead, the problem is usually deeper—in the CMS and MySQL/MariaDB settings.

Database connection error

A database connection error after migration means that the CMS or application cannot connect to MySQL/MariaDB. The web server itself may still be working normally.

In WordPress, a typical error is Error establishing a database connection. The cause is most often in wp-config.php:

define( ‘DB_NAME’, ‘database_name’ );

define( ‘DB_USER’, ‘database_user’ );

define( ‘DB_PASSWORD’, ‘database_password’ );

define( ‘DB_HOST’, ‘localhost’ );

For Laravel, Symfony, and many other applications, the equivalent settings are in .env:

DB_DATABASE=database_name

DB_USERNAME=database_user

DB_PASSWORD=database_password

DB_HOST=127.0.0.1

After migration, check the following:

  • Whether the database has been imported to the new VPS;
  • Whether the database name is specified correctly;
  • Whether the database user exists;
  • Whether the password is correct;
  • Whether the user has privileges for this database;
  • Whether the host is specified correctly: localhost, 127.0.0.1, or an external address;
  • Whether MySQL/MariaDB is running.

Check the MySQL status: systemctl status mysql

Test the connection manually: mysql -u database_user -p database_name

If the manual connection fails, the issue is not with the CMS, but with the database, user, password, privileges, or whether MySQL/MariaDB is running.

If the database connects but the site still behaves strangely, the next common post-migration scenario is an infinite redirect loop.

Redirect loop

A redirect loop occurs when a site endlessly redirects a user between URLs. For example, from HTTP to HTTPS, from HTTPS to HTTP, from www to non-www, back to www, or to an old domain.

After a migration, this is often caused by redirects being configured in multiple places at once:

  • in Nginx or Apache;
  • in .htaccess;
  • in the CMS;
  • in a redirect plugin;
  • in the CDN;
  • in the application configuration.

You can check the redirect chain as follows:

curl -I http://example.com

curl -I https://example.com

If you need to see several redirects in sequence: curl -IL http://example.com

For WordPress, check siteurl and home:

SELECT option_name, option_value

FROM wp_options

WHERE option_name IN (‘siteurl’, ‘home’);

If the site is supposed to run at https://example.com, but the database still contains http://example.com or the old domain, incorrect redirects, mixed content, and authentication issues may occur.

If a CDN is used, it is important to check the SSL mode. For example, if the CDN connects to the origin over HTTP while the site on the VPS forcibly redirects to HTTPS, an infinite loop may occur.

A redirect loop usually means that the server and the CMS disagree about the correct site URL. Choose a single canonical version—HTTPS, with or without www—and align Nginx/Apache, the CMS, and the CDN with it.

Another post-migration symptom is less dramatic: the site opens, but some users still see the old version.

Some users still see the old site

If, after the migration, some users see the new site while others still see the old one, DNS is usually the cause. This is normal during the first few hours after DNS records are changed, especially if the TTL was high before the migration.

DNS responses can be cached:

  • By the internet service provider;
  • In public DNS resolvers;
  • In the user’s operating system;
  • In the browser;
  • In the corporate network;
  • By the CDN.

You can check which IP address the domain resolves to on the current machine as follows: dig A example.com +short

To check through a specific DNS server:

dig @8.8.8.8 A example.com +short

dig @1.1.1.1 A example.com +short

If different resolvers return different IP addresses, DNS has not yet updated everywhere, or the nameservers are not configured consistently.

You should also check www and the root domain separately:

dig A example.com +short

dig A www.example.com +short

Sometimes only example.com is migrated, while www.example.com is overlooked, causing some users to reach a different server.

If new nameservers are being used, it is important to make sure the DNS zone has been fully migrated to them: A records, CNAME, MX, TXT, SPF, DKIM, DMARC, and other important records.

This can also happen when some clients use IPv6 and others use IPv4, so remember to check both A records and AAAA records.

When some users still see the old site, it does not always require an urgent fix. However, it is best to keep the old hosting active for a few days after the migration so that users with a stale DNS cache do not end up on a non-working page.

Ultimately, symptom-based diagnostics help narrow the search more quickly: a white screen points to PHP and the application; 403/404/500 to the web server, permissions, and configuration; database error to the database; redirect loop to SSL and the domain; and some users seeing the old site to DNS, TTL, and caches.

What to Check on the VPS

If DNS already points to the new IP address, the ports are open, and the site still does not work, you need to move on to checks inside the VPS. At this level, it is important to determine whether the server is accepting requests, whether the virtual host is configured correctly, whether the application can access the database, and whether the file permissions are adequate.

It is better not to start by editing every configuration file one after another. First, check the status of the services, then the site configuration, followed by the logs, the database, and access permissions.

Service status

After migration, the site depends on several services. These typically include Nginx or Apache, PHP-FPM, MySQL/MariaDB, and sometimes Redis, Node.js, supervisor, Docker, or a task queue.

You can start with the web server. For Nginx: systemctl status nginx

For Apache: systemctl status apache2

If the site runs on PHP-FPM, check PHP: systemctl status php8.2-fpm

The version may be different: php8.1-fpm, php8.3-fpm, or another version.

For the database: systemctl status mysql

Or, if MariaDB is used: systemctl status mariadb

It is important to look not only for the word active, but also at the most recent errors in the systemctl output. A service may be running but constantly restarting, failing after requests, or operating with an incorrect configuration.

If the services are active, the next step is to check whether the site is correctly defined in the web server configuration.

Site configuration files

A site configuration defines which domain the web server responds to, which directory it serves files from, and how it passes requests to PHP or the application.

For Nginx, first check the syntax: sudo nginx -t

Then open the configuration file for the relevant site. It is usually located in one of these directories:

/etc/nginx/sites-available/

/etc/nginx/conf.d/

In Nginx, server_name, root, and PHP handling are especially important:

server_name example.com www.example.com;

root /var/www/example.com/public;

location ~ \.php$ {

fastcgi_pass unix:/run/php/php8.2-fpm.sock;

}

If server_name does not match the domain, the request may be routed to a different virtual host. If root points to the wrong location, the site may return a 404, serve the default page, or show an empty directory. If fastcgi_pass points to an old PHP-FPM socket, PHP pages may fail to open.

For Apache, check the virtual host configuration files: /etc/apache2/sites-available/

And check the syntax: sudo apachectl configtest

After changing the configuration files, remember to reload: sudo systemctl reload nginx

Or for Apache: sudo systemctl reload apache2

If the configuration looks correct but the site still returns an error, the next place to check is the logs. They usually reveal the real cause faster than repeatedly changing settings at random.

Nginx/Apache and PHP Logs

Logs help you understand exactly what is happening during a request. Without them, it is easy to mistake a 403 for a permissions issue, a 404 for an incorrect root, a 500 for a PHP error, or a 502 for a PHP-FPM problem.

For Nginx, check the error log: sudo tail -n 100 /var/log/nginx/error.log

If a separate log is configured for the site, check that file: sudo tail -n 100 /var/log/nginx/example.com.error.log

For Apache: sudo tail -n 100 /var/log/apache2/error.log

For PHP-FPM: journalctl -u php8.2-fpm -n 100 –no-pager

PHP errors may also be written to a separate file if this is configured in php.ini, the pool configuration, or the CMS itself.

In the logs, look for phrases such as:

permission denied

file not found

primary script unknown

connect() failed

upstream timed out

PHP Fatal error

Access denied

Permission denied often indicates a permissions issue. File not found and Primary script unknown point to an incorrect root, fastcgi_param, or project structure. PHP Fatal error indicates an application error, an incompatible PHP version, a missing module, or a code issue.

If the logs show that the application cannot connect to the database, move on to checking MySQL/MariaDB and the CMS settings.

Connecting to the database

After migration, the database must not only be imported, but also accessible to the application. The issue may be the database name, username, password, host, permissions, or the fact that the database was not migrated at all.

First, check whether the database service is running: systemctl status mysql

Then try connecting manually using the same credentials specified in the CMS: mysql -u db_user -p database_name

If the connection fails, check the user and privileges: SHOW GRANTS FOR ‘db_user’@’localhost’;

For WordPress, the settings are in wp-config.php:

define( ‘DB_NAME’, ‘database_name’ );

define( ‘DB_USER’, ‘db_user’ );

define( ‘DB_PASSWORD’, ‘db_password’ );

define( ‘DB_HOST’, ‘localhost’ );

For Laravel and many other applications, they are in .env:

DB_DATABASE=database_name

DB_USERNAME=db_user

DB_PASSWORD=db_password

DB_HOST=127.0.0.1

Pay special attention to localhost and 127.0.0.1. In some configurations, this can matter: socket connections and TCP connections are handled differently.

If the database connection works manually but the site still shows an error, check whether the application is reading the current configuration. After migration, an old .env file, cached configuration, or an incorrect path to the settings file may remain.

If the database is accessible but the site still returns 403 or 500 errors, or does not display images, check the permissions for files and uploads.

File permissions and uploads

After migration, files may belong to the wrong user. For example, the archive may have been extracted as root, while the web server or PHP-FPM runs as www-data. As a result, the site may load partially but be unable to write to cache, logs, sessions, or uploads.

You can check the owner and permissions as follows: ls -la /var/www/example.com

For WordPress, also check:

ls -la /var/www/example.com/wp-content

ls -la /var/www/example.com/wp-content/uploads

For Laravel:

ls -la /var/www/example.com/storage

ls -la /var/www/example.com/bootstrap/cache

If the standard web server user is being used, ownership is often set to www-data: sudo chown -R www-data:www-data /var/www/example.com

Basic permissions for many PHP projects usually look like this:

find /var/www/example.com -type d -exec chmod 755 {} \;

find /var/www/example.com -type f -exec chmod 644 {} \;

However, this is not a universal rule. Some projects require specific permissions for storage, cache, uploads, logs, or temporary directories. If the site runs through a control panel, Docker, or a dedicated user, you need to follow that setup’s permission model.

It is also important not to forget hidden files. If .htaccess, .env, .user.ini, or other hidden files were not included during the migration, the site may not behave the same way as it did on the old server.

You can check whether they are present as follows: ls -la /var/www/example.com

Ultimately, the VPS check should confirm several things: the services are running, the virtual host points to the correct directory, the logs show no critical errors, the database is accessible, and the files, uploads, and hidden files are in place with the correct permissions.

Common Post-Migration Issues

After a migration, a site may fail to open not because of a single major failure, but because of several small oversights. DNS may have been updated without accounting for TTL, the application configuration may have been overlooked, hidden files may not have been transferred, the site may not have been tested in advance, and after the domain was switched over, checks may have been limited to the home page.

These issues are especially frustrating because they often do not appear immediately. The home page may load, while the admin area, forms, images, cart, permalinks, or database may not work correctly.

Nameservers and TTL Without a Plan

One common mistake is changing nameservers or DNS records without understanding TTL. As a result, some users are already reaching the new VPS, while others still see the old site.

TTL indicates how long a DNS response can be cached. If a record had a high TTL before the migration, the IP update may take longer to propagate. This is not always a problem with the new server: different resolvers and providers may simply still have the old data cached.

Before migrating, it is best to lower the TTL for key records in advance:

example.com.      A      203.0.113.10

www.example.com.  A      203.0.113.10

After the cutover, you should check not just your own browser, but also different resolvers:

dig A example.com +short

dig @8.8.8.8 A example.com +short

dig @1.1.1.1 A example.com +short

If you are changing nameservers, it is important to migrate the entire DNS zone, not just the site’s A record. Otherwise, you may accidentally break email, SPF, DKIM, DMARC, subdomains, verification TXT records, and other services.

Even when DNS already points to the new IP address, the site may still fail to work because of application configuration files. The most critical settings are often found in .env or wp-config.php.

A forgotten .env or wp-config.php file

After moving files, it is easy to forget the application’s configuration file. For WordPress, this is wp-config.php; for Laravel, Symfony, Node.js applications, and many other projects, it is .env.

These files may store:

  • Database name;
  • Database user;
  • Password;
  • Database host;
  • Site URL;
  • Application keys;
  • SMTP settings;
  • Cache settings;
  • Environment mode;
  • Credentials for external APIs.

If wp-config.php or .env was not migrated, the site may display a database connection error, return a 500 error, show a white screen, or start running with incorrect settings.

For WordPress, check:

define( ‘DB_NAME’, ‘database_name’ );

define( ‘DB_USER’, ‘database_user’ );

define( ‘DB_PASSWORD’, ‘database_password’ );

define( ‘DB_HOST’, ‘localhost’ );

For applications that use .env:

APP_URL=https://example.com

DB_HOST=127.0.0.1

DB_DATABASE=database_name

DB_USERNAME=database_user

DB_PASSWORD=database_password

Also remember that .env is a hidden file. If you copied the site using a command that does not include hidden files, it may simply not have made it to the new server.

This issue is not limited to .env. Other hidden files are also often lost during migration.

Hidden files that were not migrated

Hidden files are files and directories whose names begin with a dot. They may not appear in a standard file listing, but they are often critical for a website.

These include:

  • .htaccess;
  • .env;
  • .user.ini;
  • .well-known;
  • .gitignore;
  • framework configuration files;
  • verification files;
  • CMS or deployment service settings.

For WordPress on Apache, .htaccess is especially important. It may contain rewrite rules for permalinks. If the file is not migrated, the home page may load, while internal pages return 404 errors.

You can check for hidden files as follows: ls -la /var/www/example.com

When copying via scp, rsync, archives, or a file manager, make sure hidden files are included in the migration. It is better not to rely only on the visual file list in the control panel; check the directory over SSH instead.

If hidden files are lost, the site may appear to be partially working. As a result, the issue is sometimes not noticed immediately: the home page loads, but routes, environment variables, SSL challenges, cron jobs, cache, or APIs start failing later.

To avoid exposing users to migration errors right away, it is best to test the new VPS in advance using the hosts file.

No testing via the hosts file

Testing via the hosts file lets you open the site on the new VPS before switching DNS for all users. This is one of the most useful steps during a migration.

The idea is simple: temporarily configure your own computer so that the domain resolves to the new IP address. This lets you test the site using the usual domain, while the requests go to the new server.

Example entry for the hosts file: 203.0.113.10 example.com www.example.com

On Windows, the file is usually located here: C:\Windows\System32\drivers\etc\hosts

On Linux and macOS: /etc/hosts

This lets you check the following in advance:

  • virtual host;
  • SSL;
  • redirects;
  • PHP;
  • database connection;
  • authentication;
  • admin panel;
  • uploads;
  • forms;
  • shopping cart;
  • user account area;
  • internal pages;
  • how the CMS works with the new domain.

If you do not test the site via the hosts file, errors will only be discovered after the DNS switch, when real users start reaching the new VPS.

However, testing via the hosts file does not replace the final test after the DNS switch. Once the domain is actually pointing to the new server, you need to go through the site again.

No final test after the DNS cutover

The last common mistake is treating the migration as complete as soon as DNS has been updated. The home page loads, so everything must be ready. In practice, that is not enough.

After the DNS cutover, you need to test real-world scenarios:

  • Whether the home page loads;
  • Whether internal pages work;
  • Whether the admin panel opens;
  • Whether HTTPS works correctly;
  • Whether there is a redirect loop;
  • Whether images and uploads are visible;
  • Whether forms work;
  • Whether emails are sent;
  • Whether the database connection works;
  • Whether the cart and checkout work;
  • Whether any links still point to the old domain;
  • Whether there are any errors in the logs.

For WordPress, it is worth checking permalinks, media files, plugins, the theme, siteurl, and home. For an online store, check the catalog, product page, cart, checkout, payment, customer emails, and administrator notifications.

You should also keep the old hosting active for a few days, if possible. Users with a stale DNS cache may still reach the previous server. If the old site has already been shut down, they will see an error even though the new VPS is working normally.

After the final test, it is useful to record the outcome: which IP address became the primary one, which DNS records were changed, which errors were found, what was fixed, and when the old server can be decommissioned.

This turns a site migration into a controlled process rather than a sudden cutover left to chance.

Conclusion

If a website does not open after being migrated to a VPS, you should not immediately start changing every setting. A migration affects multiple layers at once: DNS, firewall, web server, SSL, PHP, the database, files, permissions, and CMS settings.

Proper diagnostics start with a simple question: is the domain already pointing to the new IP address, or is the user still reaching the old server? After that, check ports 80/443, the status of Nginx or Apache, the virtual host, the SSL certificate, PHP-FPM, the database connection, hidden files, uploads, and the domain configured inside the CMS.

Symptoms help narrow down the issue faster. A white screen is most often related to PHP or the application. A 403 error indicates permissions or an access restriction. A 404 points to an incorrect root, virtual host, or rewrite rules. A 500 indicates an application, .htaccess, PHP, or configuration error. A database connection error almost always points to wp-config.php, .env, the database user, password, host, or database access permissions.

DNS propagation and TTL must also be taken into account. If some users still see the old site, it does not always mean the new VPS is configured incorrectly. The old IP address may remain cached by the ISP, resolver, operating system, or browser.

The best way to reduce risk is to test the site through the hosts file before switching DNS. This lets you identify issues with SSL, the virtual host, PHP, the database, paths, permissions, uploads, and CMS settings in advance.

After switching DNS, the migration should not be considered complete just because the home page opens. You need to test real user flows: internal pages, the admin panel, forms, authentication, the cart, checkout, emails, images, redirects, and logs.

FAQ

Why doesn’t the website load after being migrated to a VPS?

The cause can be at any level: the domain may still point to the old IP address, ports 80/443 may be closed, Nginx or Apache may not be running, the virtual host may be configured incorrectly, the SSL certificate may not have been issued, PHP-FPM may not be working, the database connection may be failing, or the CMS may still be using the old domain.

It is best to start troubleshooting with DNS and server availability, then move on to the web server, SSL, PHP, the database, files, and CMS settings.

Why do some users still see the old site?

This is usually due to DNS caching and TTL. After you change an A record or nameservers, different resolvers do not update their data at the same time. One user may already be reaching the new VPS, while another may still be reaching the old server.

You can check the current IP address as follows:

dig A example.com +short

dig @8.8.8.8 A example.com +short

dig @1.1.1.1 A example.com +short

It is best to keep the old hosting active for a few more days so that users with a stale DNS cache do not encounter an error.

What should I do if a database error appears after migration?

Check the database connection settings. For WordPress, this is wp-config.php; for Laravel and many other applications, it is .env.

Verify the database name, user, password, host, and user permissions. Also make sure the database dump has actually been imported to the new VPS and that MySQL or MariaDB is running.

systemctl status mysql

mysql -u db_user -p database_name

If you cannot connect manually, the issue is not with the CMS but with the database, user, password, host, or permissions.

Why did a redirect loop occur after the migration?

A redirect loop occurs when a site endlessly redirects the user between URL versions. For example: HTTP → HTTPS → HTTP, www → non-www → back to www, or the new domain → the old domain.

Look for the cause in Nginx/Apache, .htaccess, the CMS, redirect plugins, the CDN, and SSL settings.

You can check the redirect chain as follows:

curl -IL http://example.com

curl -IL https://example.com

For WordPress, also check siteurl and home in the wp_options table.

Why test a site using the hosts file before switching DNS?

The hosts file lets you access the new VPS via the domain name before DNS starts directing all users to the new IP address. This is a safe way to test the site in advance under conditions close to real-world use.

Example entry: 203.0.113.10 example.com www.example.com

This allows you to test the virtual host, SSL, PHP, database, admin panel, forms, uploads, redirects, shopping cart, and CMS settings before the public cutover.

Which hidden files are most often forgotten during migration?

The most commonly overlooked items are .env, .htaccess, .user.ini, .well-known, verification files, and service configuration files for the framework or CMS.

You can check for hidden files as follows: ls -la /var/www/example.com

For WordPress on Apache, .htaccess is especially important because permalinks may break without it. For Laravel and many other applications, .env is critical because it stores environment settings and database connection details.

When can you shut down the old hosting after the migration?

It is best not to shut down the old hosting immediately after updating DNS. Some users may still reach the old IP address because of TTL and DNS caching.

The old server is usually kept active for several days. Before shutting it down, make sure the domain consistently resolves to the new IP address, the site is running on the new VPS, forms and email have been tested, the database is not getting out of sync between the old and new versions, and the old server logs show almost no real visitors.

Sources

1. Nginx Documentation — Beginner’s Guide

2. Apache HTTP Server Documentation — VirtualHost Examples

3. Certbot Documentation — User Guide

4. WordPress Developer Resources — Editing wp-config.php

Subscribe to our newsletter and receive articles and news

    Check out our other materials