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:
| Layer | What to check | Why it matters |
| Client | Whether the site works on another device using a different internet provider | The problem is often investigated on the server, even though it may actually be on the client side |
| DNS | The domain points to the new IP address | If the A record is still old, users will reach the previous server |
| Resolution | The domain actually resolves to the correct IP address | DNS may not update for everyone at the same time because of TTL |
| Firewall | Ports 80 and 443 are open | Even a working Nginx instance will not help if the ports are closed |
| Web server | Nginx or Apache is running | The server must accept HTTP/HTTPS requests |
| Virtual host | The domain is mapped to the correct directory | Otherwise, the wrong site, a 404 page, or the default page may open |
| SSL | The certificate has been issued and HTTPS works | SSL errors and redirects can break access |
| PHP | PHP-FPM or PHP in Apache is working | WordPress and other CMS-based sites will not load without PHP |
| Database | The CMS connects to the new database | Otherwise, a database connection error will appear |
| Files | Paths, permissions, and hidden files have been migrated | Without .htaccess, .env, or correct permissions, the site may return 403/500 errors |
| CMS | The new domain is specified in the settings | The 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
