Change TeamCity IP address and port number on multi-homed Windows Server 2008 running IIS 7

iis-7ipmulti-homedteamcitywindows-server-2008

After two full days of "research" (read: banging my head against my keyboard) and cursing at TeamCity/MSDN/Tomcat documentation as well as phantom IIS bindings, I've come up with an answer to a very perplexing issue: How can I change TeamCity's IP address and port number on a multi-homed server running Windows Server 2008 as well as IIS 7 which is serving a necessary purpose?.

First, a bit of background. Our build server is running Windows Server 2008 with two IP addresses (192.168.1.30 and 192.168.1.31) on one NIC. I've configured IIS to explicitly bind its one and only site to 192.168.1.30 on port 80. At this point I'm thinking that 192.168.1.31 is wide open and ready to be used for TeamCity… not quite.

First annoyance: when installing TeamCity, it completely disregards the fact that there are multiple IP addresses associated with this server asking only which port it should bind to. For server-grade software, this is pretty surprising.

Second annoyance: TeamCity defaults to port 8080 (wha??). Due to the first annoyance, the port selection is somewhat ambiguous: is TeamCity going to bind to port 8080 on both IP addresses? Changing the port selection to 80 yields a warning that another service is already bound to port 80. Hmm, IIS should only be bound to port 80 on 192.168.1.30; nothing should be bound on 192.168.1.31. Obviously TeamCity is competing with IIS on 192.168.1.30.

Finishing TeamCity's installation, after choosing port 80 and ignoring the binding warning, I open up "C:\TeamCity\server.xml". Sidenote: "C:\TeamCity\" is the default installation directory for TeamCity while "C:\Users\.BuildServer" is the default data directory. Anyway, "server.xml" is the configuration file where you can set things like the port and IP address of TeamCity's web interface. After a bit of research I come up with the configuration for binding the IP address 192.168.1.31 on port 80:

Look for either

<Connector
    port="8080"
    protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443" />

or

<Connector
    port="80"
    protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443" />

depending on the port you chose during installation. Change either to (note: change the IP address!)

<Connector
    port="80"
    protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443"
    address="192.168.1.31" />

Should be as easy as that, right… right? Well, restarting TeamCity's Web Server (via Windows' Services Manager) yields nothing on 192.168.1.31. Ugh.

It turns out that even though IIS's one and only site has been explicitly bound to 192.168.1.30 on port 80, IIS still listens on all IP addresses. This, of course, throws off TeamCity's Web Server (Tomcat) which halts before even coming online. After manually starting Tomcat from the command-line to dissect its stdout error and even more research, I happen upon this little gem from StackOverflow: How can I control which IP address IIS7 uses?

So, from an Administrative command line I run (note: again, change the IP address! This time to the IP address that you want IIS to be bound)

netsh http add iplisten ipaddress=192.168.1.30

Now I restart TeamCity's Web Server and voila, it works!! I can browse to 192.168.1.31 without having to specify a port number and TeamCity's web interface comes up. A quick sanity check shows that IIS is still correctly bound to 192.168.1.30. All is well.

Sorry for the long post for such a simple fix. I hope this helps someone else as it sure would have saved me hours of aggravation.


Edit: After using TeamCity for a while, I noticed that the Build Agent which had been installed with TeamCity was not being recognized correctly. To fix this, I had to point the Build Agent to the new URL for TeamCity. This configuration change is done in "C:\TeamCity\buildAgent\conf\buildAgent.properties". Again, this is the path for a default install of TeamCity and might be different depending on how you customize your installation of TeamCity.

Inside "buildAgent.properties" make sure "serverUrl" points to the new TeamCity URL. In my case, I updated it to:

serverUrl=http\://192.168.1.31

After making this change, restart both TeamCity Web Server and TeamCity Build Agent.

Best Answer

Answer is part of the original "question" above.