Monday, May 4, 2009

Run IIS, ASP.net and Apache Together Without Multiple IP Addresses

Many people want to run both IIS and Apache Web Server together. We have already blogged on similar lines: how to add or assign multiple IP addresses to your computers and how to configure their hosts files to loopback virtual hosts to development servers and how to run IIS and Apache together when your computer has multiple IP addresses. Additionally, we have written about configuring Apache to handle different hostnames.

This post will help you run IIS and Apache Web Server together even if you can't manage to add multiple IP addresses (may be because your ISP refuses to assign you so).

It is fairly simple to use Apache Web Server as a proxy to reach IIS. Your sites users will make direct requests to Apache Web Server and when we have finally configured our Apache Web Server, all requests will be proxyed to IIS. You can also configure multiple domains (blogged earlier) in to only proxy requests for particular virtual hosts (particular websites).

Here is what you need to do:

  1. Configure your IIS website to listen to port number 8080 or any other number not in use in your system. So if your website URL was http://www.my-site.com, it will now be http://www.my-site.com:8080/
  2. Start Apache Web Server and make sure Apache can listen to port 80. If Apache web server FAILS, you can use bind settings specified in the earlier post that includes info on changing bind settings of IIS. You may have to restart your server.
  3. Make sure you can start both web server and hit both IIS and Apache from local machine using different ports.
  4. Now open Apache configuration file, httpd.conf. This file is located inside the installation directory under /conf folder. Usually it is placed under: C:\Program Files\Apache Software Foundation\Apache2.2\conf
  5. Scroll to the bottom of this file and add the following text to tell Apache Web Server to load the two following modules and enable proxy sites capability:
    LoadModule proxy_module modules/mod_proxy.so
    LoadModule proxy_http_module modules/mod_proxy_http.so
    
    ProxyRequests Off #keep proxy to OFF or your server will act as a forward proxy
    
    
  6. At the bottom, add a new virtual host in the following way: (read howto if you are not sure about vhosts)
    NameVirtualHost *:80
    
    <VirtualHost *:80>
    ServerName www.my-site.com
    ServerAlias *.my-site.com
    DefaultType text/html
    <Directory "C:\Inetpub\wwwroot">
    Options Indexes FollowSymLinks
    AllowOverride none
    Order allow,deny
    Allow from all
    </Directory>
    # sends all requests made to port 80 to another port 8080
    ProxyPass / http://www.my-site.com:8080/
    #makes proper changes to server-side redirection header
    ProxyPassReverse / http://www.my-site.com:8080/ 
    </VirtualHost>
    
  7. Restart Apache Web Server and bingo, you're done!

Now if you access www.my-site.com your requests will be proxied to IIS by Apache Web Server and the only Web server users will be in direct access of will be Apache. Apache and IIS connection will be hidden from your end-users.

ProxyPass is the magic statement and the power of mod_proxy_http and mod_proxy means that you can run any other Application Server or Web Server behind your Apache Web Server and enjoy the benefits of multiple web servers.


This effectively means that you can now run ASP.net with Apache Web Server!
Note: Don't use this technique to create fake Yahoo or GMail sites inside a office network!

15 comments:

Anonymous said...

Well that is a good start for me thanks! What if you are running a vmware server with linux on top of windows and you need to forward your request to windows and "Directory "C:\Inetpub\wwwroot" is not accessible directly as windows is on a different internal ip (bridge) not NAT? Thanks.

codecurry.com said...

Hello, if you are running VMWare, you can use the shared folder feature.

VMWare on Windows will allow you to designate a folder to be shared with your Linux image.

Have Fun!

Francis said...

I have followed the steps as mentioned above in my Windows XP machine and I'm able to access the IIS Sites like this http://localhost:8080/mysitename/ but while trying to access the other sites which I have a host entry in Apache are getting a message like "We could not find your www.testsite.com". Can you please tell me what went wrong?

codecurry.com said...

Francis, you need to add host entries on windows 'host' file as well. The 'hosts' file is located in windows/system32/drivers/etc folder.

You will need admin rights to edit the file. You can copy the file, then edit it and then paste it back.

Francis said...

After adding the host entry I'm able get the site accessible. My IIS has default site which is accessible at localhost itself like this http://localhost:8080/ in windows XP. On hitting that it will loads up the site content. But now I’m getting another issue or it might be another question.

I have created a host entry “www.mytestapp.loc” for a new test site and I set the document root as “DocumentRoot "D: /Projects/mytestapp" in the virtual host. Now when I hit the “www.mytestapp.loc” its re-routing to the content of IIS site “http://localhost:8080/” but all I want to load is the content of "D: /Projects/mytestapp" location. Is that possible to do this?

Host Entry: 127.0.0.1 www.mytestapp.loc

Apache Virtual host Entry:


ServerName www.mytestapp.loc
ServerAlias *.mytestapp.loc
DocumentRoot "D:/Projects/mytestapp"

Options Indexes FollowSymLinks
AllowOverride none
Order allow,deny
Allow from all

#sends all requests made to port 80 to another port 8080
ProxyPass / http://www.mytestapp.loc:8080/
#makes proper changes to server-side redirection header
ProxyPassReverse / http://www.mytestapp.loc:8080/

Francis said...

<VirtualHost *:80>
ServerName www.my-site.com
ServerAlias *.my-site.com
DefaultType text/html
DocumentRoot "D:/Projects/mytestapp"
<Directory "C:\Inetpub\wwwroot">
Options Indexes FollowSymLinks
AllowOverride none
Order allow,deny
Allow from all
Here is the full host entry.
Apache Virtual host Entry:
</Directory>
#sends all requests made to port 80 to another port 8080
ProxyPass / http://www.mytestapp.loc:8080/
#makes proper changes to server-side redirection header
ProxyPassReverse / http://www.mytestapp.loc:8080/
</VirtualHost>

codecurry.com said...

Francis,

Your IIS is still listening to port 80.

You need to run one of the following command lines for your OS version:

For Win XP use:
httpcfg.exe set iplisten -i 0.0.0.0:8000

For Vista and Windows server 2008 or later:
netsh http add iplisten ipaddress=0.0.0.0:8000

Read the article in detail here:
http://www.codecurry.com/2009/02/installing-and-running-iis-and-apache.html

Matt said...

So, I think I have my IIS only listening to requests on port 8080 and Apache is set to listen to port 80. I've confirmed this is working by typing in the IP of the pc and appending the port: 192.168.1.3:8080 resolves to the IIS default site, while 192.168.1.3 resolves to the only other site set up under Apache. So, it appears the ports are set correctly. Here's what my httpd.conf file looks like:

#Add proxy redirect to IIS for iissite.com

ServerName iissite.com
ServerAlias *.iissite.com
DefaultType text/html

Options Indexes FollowSymLinks
AllowOverride none
Order allow,deny
Allow from all

# sends all requests made to port 80 to another port 8080
ProxyPass / http://www.iissite.com:8080/
#makes proper changes to server-side redirection header
ProxyPassReverse / http://www.iissite.com:8080/


#Add matttyree.com as virtual host

ServerName apachesite.com
ServerAlias *.apachesite.com
DocumentRoot "C:/xampp/htdocs/apachesite.com/"


The apache site works perfectly. But when I request the iis site, I get a "Service Temporarily Unavailable" error from apache.

What am I missing?

Thanks,
Matt

codecurry.com said...

@Matt

Since both Apache and IIS are running on the same server, you should use:

ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/


# Let me know if that works.

-Sameer

Matt said...

I got it to work once passing it to 192.168.1.103:8080....which is basically what you're suggesting. But, it only loaded the default IIS site. Not the site I wanted. How would I point it to a particular site when using host headers in IIS. In other words, all the sites use the same IP and port, so how do I tell Apache to send the discerning info to IIS?
Thanks!!!

codecurry.com said...

@Matt

You can have IIS listen to single IP and multiple port numbers. I have detailed it here: http://www.codecurry.com/2009/02/installing-and-running-iis-and-apache.html

In nutshell, use (depending on your version of Wndows):

netsh
http
add iplisten 0.0.0.0:8080
add iplisten 0.0.0.0:8081

OR

httpcfg set iplisten -i 0.0.0.0:8080
httpcfg set iplisten -i 0.0.0.0:8081
----

You will also have to add multiple VHost entries in Apache - that is implicit since you have multiple domains.

Eddie said...

Hi Sameer, I did everything you suggested, domain1 is using IIS + PHP 4 + port 8080, domain2 using Apache + PHP5 + port 80. Domain 2 works fine, but whatever I do, domain1 always points to domain2's default doc root. The httpd.conf setting is:

ProxyRequests Off

NameVirtualHost *:80

ServerName domain1
ServerAlias *.domain1
DefaultType text/html

Options Indexes FollowSymLinks
AllowOverride none
Order allow,deny
Allow from all


#ProxyPreserveHost On
# sends all requests made to port 80 to another port 8080
ProxyPass / http://localhost:8080/
#makes proper changes to server-side redirection header
ProxyPassReverse / http://localhost:8080/



Also in the windows\system32\drivers\etc\hosts, I added:
87.xxx.xxx.xxx www.domain1

Could you please kindly tell me what I did wrong? Thank you!
Regards,
Eddie

codecurry.com said...

Can you try to uncomment, ProxyPreserveHost - that can pass required host-header to IIS and then IIS can serve multiple sites.

Eddie said...

Hi, thanks very much for getting back. After uncommenting the line, domain1 still pointing to domain2. I also moved this line outside the '<'VirtualHost'>' group.
Any suggestions please?

Eddie said...

Do apologize. I wrote the wrong '<'VirtualHost *:80'>' tag, I used a dot instead of colon.
Now after I restart Apache, all the sites goes to Domain1. Even Domain2 is pointing to Domain1's default page.
Please help! Thank you very much!

Post a Comment

Be relevant. Spammers will be banned.

☛ Quick Links

♥ Recommended For You