Wednesday, July 8, 2020

Deploy Angular and spring boot apps to Azure app service or storage account

1. Deploy angular web app as static html web app
One typical web project structure is Angular (front SPA web app) communicating with backend Spring boot (API function app), and deployed to Azure cloud. The app can use Azure Active Directory or Azure B2C for user authentication.

To demo the various options for this architecture, a simple prototype web application will be created and deployed to Azure.

1. Create Angular SPA app with git repository
Create a new angular app with two button, one for login and one for sending a request to service api app. For now both button just logs a console log.
Add the project into a new git repository, so it can be deployed to azure from git using the Azure Static Web App service. The git repository is at https://github.com/lijo2/angularspa

2. Deploy the angular project to Azure 

2.1 Option 1 - Host static html web site with app service
2.1.1 First create an app service plan , for example, haiquanserviceplan, and a resource group, for example, angularwebapp. 

2.1.2 Second, from azure portal, find the storage account created by Azure for supporting cloud shell bash, the storage account name starts with "cs". In storage account's file service, create a new directory, and copy the angular's production build's dist folder to this new directory. In this example, all html and js files are copied to a directory called "spa" in the storage account.
Note, the azure cloud shell only provides function to upload/download a single file, so it cannot be used to upload a folder in this case.

2.1.3 open azure cloud shell from azure portal, and cd into the new directory just created in 2.2, the folder should contain the html and js files used by the static web app, then run the below command to create the static web app
az webapp up --location eastus --name spawebappli --html -p haiquanserviceplan -g azuretest

The above command will create a new web app containing static html and js resource in the resource group, if later, you need to update the resource or include some sub folder, then you can send the web app resource as a zip file by using az webapp deployment source config-zip command, or using a FTP client. 
az webapp deployment source config-zip -g azuretest -n spawebappli --src app.zip
-g: resourcegroup name
-n: app name

Note for creating zip file with npm command:
npm package 'npm-build-zip' can be installed and automatically zip the dist folder to generate a zip file with npm
 npm install npm-build-zip

Update the scripts in package.json to automatically generate the zip file and deploy to azure app service.
    "zip": "npm-build-zip --source=dist/angularspa --destination=dist",
    "deploy": "az webapp deployment source config-zip -g azuretest -n spawebappli --src dist/angularspa_0.0.0.zip"
 
To create a new deployment, run from visual studio code terminal:
npm run zip
npm run deploy

2.1.4 browser to the new app's url to verify the html web app has been created properly

2.1.5 Using FTP to update and upload/download web resource
Azure web app allows FTP access to the web application's site/wwwroot/folder. For this purpose, you will need to first install FTP client (for example, WinSCP). The ftp url and username/password are available in Azure portal's app service's deployment/deployment Center/FTP page.
 
2.2 Option 2 - host static web site in Azure storage account
2.2.1 Create a storage account 
2.2.2 In storage account's Setting/Static Website blade, enable static website
2.2.3 Download and install Azure Storage Explorer to upload the static website's resource files from local to storage account's $web container as shown below. You can also do so with azcopy from command line. Azure Storage Explorer can easily create sub folder, and upload files to sub folder.
2.2.4 Test the static web site from the url shown in storage account's Setting/Static Website blade
3. Deploy spring boot app to azure app service

As azure already created a maven plugin for web app, so it can be used to deploy the spring boot project to azure as web app.

3.1 create and test the spring boot project in localhost with 
mvn spring-boot:run

3.2 run  to create the jar file
mvn package

3.3 run 
mvn com.microsoft.azure:azure-webapp-maven-plugin:1.9.0:config
to config azure maven web app plugin by entering the appname, service plan, pricingtier and other information.

3.4 update pom file's azure mvn plugin setting to specify a port number 
   <plugin> 
        <groupId>com.microsoft.azure</groupId>  
        <artifactId>azure-webapp-maven-plugin</artifactId>  
        <version>1.9.0</version>  
        <configuration> 
          <schemaVersion>V2</schemaVersion>  
          <resourceGroup>azuretestspring</resourceGroup>  
          <appName>springapitestli</appName>  
          <pricingTier>B1</pricingTier>  
          <region>eastus</region>  
          <runtime> 
            <os>linux</os>  
            <javaVersion>java11</javaVersion>  
            <webContainer>java11</webContainer> 
          </runtime>  
          <appSettings> 
            <property> 
              <name>JAVA_OPTS</name>  
              <value>-Dserver.port=80</value> 
            </property> 
          </appSettings>  
          <deployment> 
            <resources> 
              <resource> 
                <directory>${project.basedir}/target</directory>  
                <includes> 
                  <include>*.jar</include> 
                </includes> 
              </resource> 
            </resources> 
          </deployment> 
        </configuration> 
      </plugin> 
3.5 run
mvn azure-webapp:deploy
to deploy the web app to azure app service plan.

3.6 after the spring boot app is updated, you will need to run
mvn package
mvn azure-webapp:deploy
to update the azure's deployment.

4. Send request from Angular project to sprint boot project
After deploying both angular and spring boot project to azure, the next step is enabling angular project to send xmlhttprequest to spring boot project. The following example shows how to send simple xhr request when a button is clicked in Angular project
  onClick() {
    console.log('call backend api to get data');
    const str = this.textField.value;
    this.http.get('https://springapitestli.azurewebsites.net/jsonapi/' + str).subscribe((resp) => {
      this.textField.setValue(JSON.stringify(resp));
    });
  }
Note, as angular project and spring boot project are deployed to different root url in azure, so sending xhr request from angular project to spring project will fail by default due to CORS. To make it work, the azure app service for spring boot project must add the angular app's url to its allowed CORS url. Alternatively, spring boot annotation of @ can also be used to specify allowed CORS origin headers.

No comments:

Post a Comment