How to map multi-domains for multi-sites in single Windows/Linux Web App

This post has been republished via RSS; it originally appeared at: New blog articles in Microsoft Tech Community.

Introduction

============

Azure App Service provides you an easy and quick way to deploy your web applications. In this post, I will detail how to map multiple domains for multiple sites in single Windows or Linux Web App. Basically they are leveraging the Web Server like IIS or Nginx to rewrite requests to separate sub-directories like D:\home\site\wwwroot\siteA in Windows or /home/site/wwwroot/sg in Linux.

 

Preparation

============

  1. Web App (Windows/Linux)
  2. Custom domains

 

Topology diagram

============

KevinLi_1-1635429527629.png

 

How to

============

  • Firstly, we can bind domains to the web app by adding custom domain from Portal. After binding, we can see them listed like as below:

KevinLi_1-1635309403162.png

Note: As mentioned on the wizard, Azure must verify that you are the owner of this domain name. So you should create a CNAME/A record and TXT record in a public DNS provider that match your domain to the the Web app public URL.

KevinLi_2-1635309403164.png

 

Windows

  • For Windows Web App, we can go ahead to "Advanced Tools" and choose Go

KevinLi_3-1635309403165.png

  • Then we navigate to D:\home\site\wwwroot, and create two direcotries, for example "a" and "b", and create web.config file if it does not exist by clicking the button near "wwwroot":

KevinLi_4-1635309403166.png

  • In each directory, you can put your separate websites. As an sample, I put an index.html in each of them.

KevinLi_5-1635309403167.png

  • Then click the edit button to open the web.config file.

KevinLi_6-1635309403167.png

  • Pasting below content into it and update the domain names and paths accordingly, then save. They are used to set the redirection rules, note that there is no need to set Virtual applications and directories.

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

  <system.webServer>

    <rewrite>

      <rules>

            <rule name="a.cominaco.com" stopProcessing="true">

            <match url=".*" />

            <conditions>

                <add input="{HTTP_HOST}" pattern="^a\.cominaco\.com$" />

                <add input="{PATH_INFO}" pattern="^/a/" negate="true" />

            </conditions>

                <action type="Rewrite" url="\a\{R:0}" />

            </rule>

 

            <rule name="b.cominaco.com" stopProcessing="true">

            <match url=".*" />

            <conditions>

                <add input="{HTTP_HOST}" pattern="^b\.cominaco\.com$" />

                <add input="{PATH_INFO}" pattern="^/b/" negate="true" />

            </conditions>

                <action type="Rewrite" url="\b\{R:0}" />

            </rule>

 

        </rules>

    </rewrite>

  </system.webServer>

</configuration>

 

  • All done. It would take effect without restarting.

 

Linux

  • For Linux Web App, it is important to know that most official docker images do not support changing configuration of web server, hence it will not work. In this demo, we will use WordPress for Linux as an example as it supports customizing nginx.conf.
  • Suppose we already bind the custom domains and set two sites in /home/site/wwwroot and /home/site/wwwroot/sg

KevinLi_8-1635309403169.png

  • Go to SSH console from portal

KevinLi_9-1635309403170.png

  • Open the config file using 'vim /etc/nginx/conf.d/default.conf' and update the file like as below, please change the server_name and root directory accordingly.

upstream php {

        server unix:/var/run/php/php-fpm.sock;       

        #server 127.0.0.1:9000;

}

 

server {

 

    listen 80;

    server_name sg.cominaco.com;

    root /home/site/wwwroot/sg;

    ## This should be in your http block and if it is, it's not needed here.

    index index.php;

  if ($request_uri ~* "/(cart|checkout|my-account)/*$") {

    set $skip_cache 1;

  }

 

        location / {

                # This is cool because no php is touched for static content.

                # include the "?$args" part so non-default permalinks doesn't break when using query string

                try_files $uri $uri/ /index.php?$args;

        }

 

        location ~* \.php$ {

                #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

                include fastcgi.conf;

                include fastcgi_params;

                fastcgi_intercept_errors on;

                fastcgi_pass php;

 

                fastcgi_read_timeout 300;

                fastcgi_cache_bypass $skip_cache;

                fastcgi_no_cache $skip_cache;

                fastcgi_cache off;

                fastcgi_cache_valid 60m;

        }

 

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {

                expires max;

                log_not_found off;

        }

 

}

 

 

server {

        listen 80;

        ## Your website name goes here.

        server_name main.cominaco.com;

        root /home/site/wwwroot;

        ## This should be in your http block and if it is, it's not needed here.

        index index.php;

 

        location = /favicon.ico {

                log_not_found off;

                access_log off;

        }

 

        location = /robots.txt {

                allow all;

                log_not_found off;

                access_log off;

        }

 

  # Add locations of phpmyadmin here.

 

  # Disable sendfile as per https://docs.vagrantup.com/v2/synced-folders/virtualbox.html

  sendfile off;

 

  set $skip_cache 0;

 

  # POST requests and urls with a query string should always go to PHP

  if ($request_method = POST) {

    set $skip_cache 1;

  }

  if ($query_string != "") {

    set $skip_cache 1;

  }

 

  # Don't cache uris containing the following segments

  if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {

    set $skip_cache 1;

  }

 

  # Don't use the cache for logged in users or recent commenters

  if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {

    set $skip_cache 1;

  }

 

  # Don't cache WooCommerce URLs

  # Cart widgets are still a problem: https://github.com/emcniece/docker-wordpress/issues/3

  if ($request_uri ~* "/(cart|checkout|my-account)/*$") {

    set $skip_cache 1;

  }

 

        location / {

                # This is cool because no php is touched for static content.

                # include the "?$args" part so non-default permalinks doesn't break when using query string

                try_files $uri $uri/ /index.php?$args;

        }

 

        location ~* \.php$ {

                #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

                include fastcgi.conf;

                include fastcgi_params;

                fastcgi_intercept_errors on;

                fastcgi_pass php;

 

                fastcgi_read_timeout 300;

                fastcgi_cache_bypass $skip_cache;

                fastcgi_no_cache $skip_cache;

                fastcgi_cache off;

                fastcgi_cache_valid 60m;               

        }

 

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {

                expires max;

                log_not_found off;

        }

}

 

 

Thanks for reading this post. I hope you enjoyed it. Please feel free to write your comments and views about the same over here.

REMEMBER: these articles are REPUBLISHED. Your best bet to get a reply is to follow the link at the top of the post to the ORIGINAL post! BUT you're more than welcome to start discussions here:

This site uses Akismet to reduce spam. Learn how your comment data is processed.