1

Some background — WordPress is really annoying in terms of what hostname you access it from, which makes creating testing environments rather painful (That is, I could create a subdomain for staging, y.x.com, but then WordPress would set all the links in the database as being from there and not x.com, which is where they will be as soon as I do the DNS changeover). To get around this, I've setup an alias in my /etc/hosts file, so I don't have to keep changing the domain name in WP's settings.

In other words: right now I have a live site running on IP x and hostname x.com. I want to leave the live site running, and have setup a staging machine at IP y, accessed via the hostname x.com, using an entry in the aforementioned /etc/hosts.

My question: How do I show the staging machine to the client without having them edit their /etc/hosts file? Is there a service online that setups an iframe and shows you a particular IP as a particular hostname?

Thanks!

Edit: I'm not asking how to setup my DNS records; they're good for the moment. I can browse to the staging machine just by typing its IP into the address bar, and WordPress loads and everything's great, except all the links are to x.com, and clicking them takes me to the live/production site. I can rectify this by putting an entry into my local machine's hosts file (I.e., /etc/hosts), which overrides the public DNS records to the live site and instead shows me the staging machine. I'm essentially wanting a way to do this easily for my client, that is, without him having to edit his hosts file.

3
  • 1
    Why you do not change the dns record?
    – Mehraban
    Commented Feb 15, 2014 at 16:16
  • @SAM Because there's an existing live site currently running and it will go offline if I change the DNS record.
    – aendra
    Commented Feb 15, 2014 at 16:39
  • Related: Browser with its own hosts file?
    – Arjan
    Commented Mar 16, 2014 at 8:19

3 Answers 3

1

Map x.com/staging to another server

Assuming you're running on Apache, proxying might do the trick. Running a Reverse Proxy in Apache suggests the following might work, but I did not test it:

ProxyPreserveHost on
ProxyPass /staging/ http://y.y.y.y/
ProxyHTMLURLMap http://y.y.y.y /staging

<Location /staging/>
    ProxyPassReverse /
    ProxyHTMLEnable On
    ProxyHTMLURLMap / /staging/
    # We need to peek into the HTML, so ensure we don't get gzip'd content:
    RequestHeader unset Accept-Encoding
</Location>

Above, a virtual folder /staging maps all from http://x.com/staging/ to / on the other IP address. To still keep using x.com as the host, I added ProxyPreserveHost.

All this will need the trailing slash; some standard rewriting could add that when needed:

# Add trailing slash if omitted
RewriteRule ^staging$ /staging/ [R=302,L]

Avoid sharing cookies: use a dedicated domain

However, to avoid very nasty problems with session cookies, I'd prefer a dedicated domain (preferably not even some subdomain of x.com). For that, remove all references to staging above. And to still send the expected domain name, I assume one could add an additional:

RequestHeader set Host x.com

When using such dedicated domain then Apache also won't have to rewrite any relative URLs, such as /some/page into /staging/some/page. However, this might imply you won't notice failures in rewriting absolute URLs (especially possible when JavaScript is involved). Like a failure to rewrite http://x.com/some/page back into http://client.mycompany.com/some/page might go unnoticed if the same URL exists on the production server, and the browser fetches that directly. That might be a benefit, or could be a disaster when you're still logged in to the production server and think you're changing content on the staging server...

Using .htaccess

Just for posterity, earlier I figured one could also use something like the following in a .htaccess file:

# Does NOT work (for me). On the target server, this gets me:
#   HTTP_HOST = y.y.y.y            - from the proxy request? Expected x.com
#   HTTP_X_FORWARDED_HOST = x.com  - from Host
#   HTTP_X_MY_DUMMY = x.com        - from X-My-Dummy, as expected

RewriteEngine On
RequestHeader set Host x.com 
RequestHeader set X-My-Dummy x.com
RewriteRule ^(.*) http://y.y.y.y/$1 [L,P] 
ProxyPassReverse / http://y.y.y.y/

However, ProxyPassReverse does not seem to be allowed in .htaccess. And some basic testing seems to reveal that the [P] proxy also always adds its own Host header, and translates my Host into X-Forwarded-Host. This could very well be related to the shared virtual hosting that I used for some quick test. But ProxyPreserveHost cannot be used in .htaccess.

See Apache's mod_proxy, mod_headers and mod_rewrite documentation.

6
  • I have this setup as a virtualhost and it seems not to be working — y.y.y.y is the staging machine's IP in both instances, right? Seems like a solid approach though; I've done something similar in the past with Nginx.
    – aendra
    Commented Feb 15, 2014 at 17:11
  • Yup, @aendrew, y.y.y.y is that staging's IP address. Any error? (I can have a closer look tomorrow, 10 hours or more from now...)
    – Arjan
    Commented Feb 16, 2014 at 1:11
  • @aendrew, my testing failed too; see edited answer.
    – Arjan
    Commented Feb 16, 2014 at 15:24
  • And for Nginx, maybe these examples can help. Of course, Nginx might show the same issue with proxy_set_header as Apache's RequestHeader set, when trying to change Host.
    – Arjan
    Commented Feb 16, 2014 at 16:07
  • Any luck, @aendrew?
    – Arjan
    Commented Feb 23, 2014 at 21:13
1

you cannot bind a same hostname to different ip's Either you have to edit your DNS records to point the domain towards staging machine or you have to make local host resolution changes via hosts file.

Also you can add a check/condition variable via PHP or other language your site is running with, if present will open your website on staging machine for example http://examplesite.com/?staging=true

5
  • While true, subdomains can have different IP addresses. (Just in case a reader doesn't know.)
    – Arjan
    Commented Feb 15, 2014 at 16:20
  • Ah yeah Subdomains can be an option too :) Commented Feb 15, 2014 at 16:22
  • Actually you can. That is often used to make a simple resilient service. Wouldn't help here as the first entry would always respond. Commented Feb 15, 2014 at 16:41
  • @Arjan Yes, I could create a subdomain, y.x.com, but then WordPress would set all the links as being from there and not x.com, which is where they will be as soon as I do the DNS changeover. Alas, I can't do that until I get sign-off from the client, and they need to see it first. I'm aware I can just setup WordPress at y.x.com and then use the WP_RELOCATE directive in wp-config.php, which will change all the links over, but then I have to do more DB work every time I push an updated dump.
    – aendra
    Commented Feb 15, 2014 at 16:43
  • @SaurabhSharma The two sites are on different machines, I'd have to setup a bunch of Nginx proxy_pass directives to make that work properly, and at that point I might as well just put it on a subdomain as per Arjan's suggestion. I'm really just looking for a way to view a specific IP address, but send a specific Host header so that links work and whathaveyou.
    – aendra
    Commented Feb 15, 2014 at 16:46
1

Another way is a normal proxy server (like Squid) and an edited /etc/hosts on the proxy server.

When you use a HTTP proxy, the browser of the client does no DNS lookup for x.com but connects to the proxy server and tells it to connect to x.com. Because you have bent x.com to another IP on the proxy server, you get the results from the staging server.

5
  • Seems like an interesting way to go — have any config tips?
    – aendra
    Commented Feb 15, 2014 at 20:23
  • I'm just a user of this server myself - but you don't need anything special - you only need a base configuration (hardened so you don't provide an open proxy for everyone). You could combine the answer of Arjan and me - use the 2 lines with "proxy" in it (without rewrite or headers) and change the /etc/hosts file. Commented Feb 15, 2014 at 20:51
  • If the proxy does the DNS lookup, then how does HTTPS work? (Newer extensions aside, the very first steps in SSL are only based on IP addresses, not on host names, right?)
    – Arjan
    Commented Feb 16, 2014 at 1:09
  • hmm, good question - I know that it definitely works for https and http with the proxy I'm using. Tomorrow I can look at the config and see if there is a trick to it. Commented Feb 16, 2014 at 10:24
  • I looked at the squid.conf settings and there is no magic going on - it's a standard squid.conf with an ldap auth backend so it is no open proxy. For the https part - I have no idea how that works, but I get the certificate of the staging server and no certificate is configured on the proxy itself. Commented Feb 17, 2014 at 18:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .