Hi, I prepared a virtual machine with a webserver, php and database to prepare a wordpress installation before it goes live. The idea is to move the whole VM to the hosting server which is behind a haproxy that does SSL offloading and then forwards http to the proper port of the VM where wordpress is listening.
So far everything works in the testing environment; I have a haproxy on localhost that redirects to the VM port on localhost that maps to port 80 in the VM, so I worked on http://localhost in my browser the whole time to create the wordpress site. This is just like the production is intended to work, except with another domain.
As my site is now ready and the hosting server is now ready, I moved the VM to the hosting server after changing the home and site-url setting from http://localhost to my real domain (say, https://example.com, including the https:// part and no trailing slash, as required by the documentation).
The wp_options table in the database looks ok, regarding siteurl and home, they point to https://example.com like intended.
The site is reachable, but broken. Some CSS elements are pointing to http://example.com instead of https://example.com (I found this in the code of the site) and even if I don't enforce https on my proxy, the page still stays broken. For example I can see an X-Button and a Button with two lines on it which both don't exist in the original and the entries of my site navigation are written on top of each other and embedded video URLs still point to "http://localhost/wp-content". No idea why that is and I am tempted to do a search and replace for http://example.com and http://localhost on the database dump.
Is there a real way to fix this? Why are CSS and embedded media URLs even hardcoded? I just picked the videos from my own wordpress media library and assumed the link would not be hardcoded. Is there a way to make it honor the siteurl or home setting from wordpress?
Except for using the wordpress default theme I did not do anytthing fancy, design-wise; I just wrote like 5 articles and removed stuff from the main example page that I did not need.
Also, and that is the bigger issue, the wp-login.php page redirects to itself in an infinite loop; here is my curl -v https://example.com/wp-login.php output (so it has nothing to do with browser cookies):
[TLS and http/2 stuff here, all ok]
> GET /wp-login.php HTTP/2
> Host: example.com
> User-Agent: curl/8.9.1
> Accept: */*
>
* Request completely sent off
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/2 302 <----- why redirect in the first place?
< date: Thu, 03 Oct 2024 09:59:47 GMT
< server: Apache
< x-powered-by: PHP/8.2.20
< x-redirect-by: WordPress
< location: https://example.com/wp-login.php <------ why redirect to itself? Of course this loops...
< content-length: 0
< content-type: text/html; charset=UTF-8
Some howtos say it might be the .htaccess file, but it is auto generated by wordpress, so/and I don't know why something would be wrong with it:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
So if I understand correctly it says in the 2nd rule: any URL that has to do with authorization is not to be rewritten, right? ("RewriteRule Pattern Substitution [flags]" –> pattern is anything, substitution is a dash and "a dash indicates that no substitution should be performed (the existing path is passed through untouched)." with the environment variable HTTP_AUTHORIZATION).
The fun part is: if I set example.com to point to localhost in my DNS, the site continues to work. But the difference there is I don't have a TLS deployment, so at the moment I can test http mode only.
How can I fix the redirect issue, how can I fix the CSS and link mess? Thank you for reading all this 🙂
1. You might have hardcoded references to localhost in the DB. Using WP-CLI you can try a “wp db search localhost” to spot where those might be (other than home/siteurl options) and do a search replace or make other modifications to reference a relative path without the scheme and hostname, depending on where it is being set. It’s most likely hardcoding localhost in some wp_posts entries.
2. Your haproxy config needs to pass a x-forwarded-proto https header to the backend so that WordPress doesn’t think it needs to redirect you from http to https. Sharing your haproxy config would be helpful.