﻿# 如何將 Spring Boot 3 透過 WAR 檔部署到 Azure Web App (Linux)

前幾天在嘗試將一個 Spring Boot 3 專案部署到 Azure Web App (Linux) 時，一直遇到了 HTTP 404 無法回應的問題，經過了兩三天的嘗試，終於找到解決方法，這篇文章就來記錄一下這個過程。

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/11e5d7153c2fcd30b6f0-12076b5d-a125-4de9-8c4d-fbfed7717d55.webp)

### 建立專案與部署 Azure Web App (Azure App Service on Linux)

以下我就介紹完整的建立專案與部署的過程：

1.  使用 [Spring Initializr](https://start.spring.io/) 建立 Spring Boot 3.2.1 專案
    
    我建立專案的完整參數可以從[這個網址](https://start.spring.io/#!type=maven-project&language=java&platformVersion=3.2.1&packaging=war&jvmVersion=17&groupId=com.example&artifactId=demo&name=demo&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.demo&dependencies=web)看見！
    
2.  加入一個 REST API Controller
    
    ```java
    package com.example.demo.controllers;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class HelloController {
    
        @GetMapping("/hello")
        public String sayHello() {
            return "Hello World";
        }
    }
    ```
    
3.  部署網站到 Azure Web App (Azure App Service on Linux)
    
    如果此時將整個網站部署到 Azure Web App (Azure App Service on Linux) 的話，網站是無法運作的，所有 API 都會回應 HTTP 404 的結果，剛遇到這個狀況的時候，真的完全沒概念，也不清楚問題發生的原因！
    
    若要立即進行部署，可參考 [Quickstart: Create a Java app on Azure App Service](https://learn.microsoft.com/en-us/azure/app-service/quickstart-java?pivots=java-maven-tomcat&WT.mc_id=DT-MVP-4015686) 文件，透過 Maven 自動部署網站到 Azure App Service！
    
    你必須先透過 Azure CLI 登入並選取要部署的訂用帳戶，然後再透過以下 Plugin 自動設定所有 Azure 部署需要的參數：
    
    ```bash
    mvn com.microsoft.azure:azure-webapp-maven-plugin:2.12.0:config
    ```
    
    然後就可以透過 `azure-webapp:deploy` 這個 Goal 來自動部署網站！
    
    ```bash
    mvn package azure-webapp:deploy
    ```
    
    > 部署的過程會自動建立所有必要的 Azure 資源，而且發行時將會把 `target/*.war` 部署到 Azure Web App 並將檔名修改成 `app.war`，放在 App Service 的 `/home/site/wwwroot` 目錄下。
    

### 解決 HTTP 404 的問題

這個步驟是本文的重點，因為 Azure App Service on Linux 會自動替 Java Spring Boot 的應用程式注入一個 [microsoft/ApplicationInsights-Java](https://github.com/microsoft/ApplicationInsights-Java) 代理程式 (auto injected agent)，這個元件會自動監控應用程式的運作狀態，但不知道是什麼原因，只要用 Java 17 + WAR + Tomcat 10 就會導致網站完全無法運作，永遠回傳 HTTP 404 的結果，所以我們必須要加入一些程式碼才能讓網站與 Application Insights 正常運作！

首先，我參考 [Using Azure Monitor Application Insights with Spring Boot](https://learn.microsoft.com/en-us/azure/azure-monitor/app/java-spring-boot?WT.mc_id=DT-MVP-4015686#enabling-programmatically) 設定 Application Insights！

1.  先在 `pom.xml` 加入以下相依套件：
    
    ```xml
    <dependency>
        <groupId>com.microsoft.azure</groupId>
        <artifactId>applicationinsights-runtime-attach</artifactId>
        <version>3.4.19</version>
    </dependency>
    ```
    
2.  請在 `DemoApplication.java` 加入 `ApplicationInsights.attach();` 程式碼 (**關鍵步驟**)
    
    ```java
    @SpringBootApplication
    public class SpringBootApp {
    
      public static void main(String[] args) {
    
        // 這是最重要的一步，請務必加上！
        ApplicationInsights.attach();
    
        SpringApplication.run(SpringBootApp.class, args);
      }
    }
    ```
    
3.  重新部署網站到 Azure Web App
    
    ```bash
    mvn package azure-webapp:deploy
    ```
    
    部署成功後，透過網址 `https://<your-app-name>.azurewebsites.net/hello` 就可以發現 API 正常運作了！ 👍
    

### 相關連結

-   [microsoft/ApplicationInsights-Java](https://github.com/microsoft/ApplicationInsights-Java): Application Insights for Java
-   [Azure app service returning 404 for Spring boot Java 8 based war - Stack Overflow](https://stackoverflow.com/q/72178863/910074)
-   [Spring Boot 2.7.8 application cannot be reached in Azure · Issue #33974 · spring-projects/spring-boot](https://github.com/spring-projects/spring-boot/issues/33974#issuecomment-1468484374)
