Azure App ServiceのTomcatに成果物をデプロイしても、404が返ってくる

このエントリは2024/04/24現在の情報に基づいています。将来の機能追加や変更に伴い、記載内容からの乖離が発生する可能性があります。

問い合わせ

いつもの人から、以下のような問い合わせがあった。

Spring FrameworkベースのWebアプリケーション成果物を、Azure App ServiceのTomcat 10.5 (Linux) にデプロイした。デプロイ自体は成功しているものの、サービスにアクセスすると404が返ってしまう。どうしたらよいか?

これだけだとよくわからないので、デプロイに使っているGitHub ActionsのYAMLファイルを見せてもらった。

name: Build and deploy WAR app to Azure Web App

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up Java version
        uses: actions/setup-java@v1
        with:
          java-version: '17'

      - name: Build with Maven
        run: |
          mvn clean install -DskipTests

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v3
        with:
          name: java-app
          path: '${{ github.workspace }}/target/*.jar'

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'Production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
    permissions:
      id-token: write #This is required for requesting the JWT

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v3
        with:
          name: java-app

      - name: Login to Azure
        uses: azure/login@v1
        with:
          client-id: ${{ secrets.AZURE_CLIENTID }}
          tenant-id: ${{ secrets.AZURE_TENANTID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID }}

      - name: Deploy to Azure Web App
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v2
        with:
          app-name: 'logicomk2-tomcat'
          slot-name: 'Production'
          package: '*.jar'

明らかにおかしいところと、ちょっとわかりづらいところがあるが、勘のいい人ならすぐにわかるかもしれない。

問題点

1. なぜJARファイル?

そもそもTomcatにデプロイするのだから、JARファイルではなくWARファイルでなければならない。上記YAMLファイルでハイライトしている箇所は*.jarから*.warに書き換える必要がある。

upload-artifactアクションはアップロード対象がなくても警告を出すだけだが、download-artifactアクションはダウンロード対象がないと失敗する。そのため、仮にJARファイルを対象にしたとしても、ここで例外を見つけ出せるはずなのだが…。

2. コンテキストパス

WARファイルをデプロイするように変更したが、それでも期待した通りの動作ではない、と言う。というのも、

<FQDN>/hello

でアクセスしたいのに、アクセスできない、ということらしい。ここで問題になるのは、WARファイルのファイル名。App Serviceの場合、ファイル名をコンテキストパスとして使う(具体的には、webapp.warだと、<FQDN>/webapp でアクセスできる)のだが、今回の問い合わせ主の作成したWARファイルはhello.warではなかったので、<FQDN>/helloにアクセスしても404が返ってしまっていた、という具合。

解決方法は、期待されている名前を付けるしかない。

  • 成果物のファイル名をhello.warにする
    • ビルド時に名称を指定
    • ビルド後にGitHub Actions内でWARファイルの名前を変更

上記の点を伝えて修正した後、無事に動作した。

更問が届く

動作するようになるといろいろ試したくなるのが人情、ってもので、ご多分に漏れず、この問い合わせ主からも更問が届いた。

  1. コンテキストパスにWARファイルのファイル名を使うことは理解した。では、<FQDN>でアクセスさせたい場合はどうすればいいか?
  2. 複数のWARファイルを1個のApp Serviceインスタンスにデプロイできるか?

1.は、些かトリッキーではあるが、ROOT.warというファイル名を使えば、<FQDN>だけでアクセスできるようになる。

2.は、確かにWARファイルを変更し、同じApp Serviceインスタンスにデプロイすると、複数のコンテキストパスでアクセスできるようになるが、ドキュメントにも記載の通り推奨されない。

Web アプリを作成してデプロイする / Create and deploy Web App(s)
https://learn.microsoft.com/azure/developer/java/migration/migrate-tomcat-to-tomcat-app-service#create-and-deploy-web-apps

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください