6.

Java Web アプリのデプロイ方法まとめ(WAR / Spring Boot jar / Docker / CI/CD)

編集
この記事の要点
  • 従来型: WAR を作って Tomcat / WildFly / WebLogic の webapps/ に配置
  • Spring Boot: 実行可能 jar を java -jar app.jar で起動(組み込み Tomcat)
  • Docker: jar / war をイメージに焼いて docker run、k8s と相性 ◎
  • 自動デプロイ: GitHub Actions / GitLab CI / Jenkins から SSH / SCP / Ansible / kubectl
  • Blue-Green / Canary / Rolling で無停止デプロイ。LB or k8s ingress で切替
  • 本番は必ず ヘルスチェック/actuator/health 等)+ ロールバック手順を用意

デプロイ方式の選択肢

方式向いている場面難易度
WAR + Tomcat 手動配置少人数・既存環境
Tomcat Manager (HTTP API)権限のあるオペレータ操作★★
Spring Boot jar + systemd1 ホストに 1 アプリ、シンプル★★
Docker + docker-compose小〜中規模、PaaS 風★★★
Kubernetesマルチアプリ / オートスケール★★★★
AWS Elastic Beanstalk / ECSマネージドにオフロード★★★

方式 1: WAR を Tomcat に配置

# 1. ビルド
mvn clean package
# → target/myapp-1.0.war

# 2. サーバへ転送
scp target/myapp-1.0.war user@prod:/tmp/

# 3. Tomcat の webapps に配置(自動展開)
ssh user@prod
sudo cp /tmp/myapp-1.0.war /opt/tomcat/webapps/myapp.war
sudo chown tomcat:tomcat /opt/tomcat/webapps/myapp.war
# 数秒待つと /opt/tomcat/webapps/myapp/ に展開

# 4. アクセス
curl http://prod:8080/myapp/

方式 2: Tomcat Manager API でデプロイ

# tomcat-users.xml に manager-script ロールを持つユーザを用意
# 

# デプロイ
curl --upload-file target/myapp.war \
    "http://deployer:password@prod:8080/manager/text/deploy?path=/myapp&update=true"

# アンデプロイ
curl "http://deployer:password@prod:8080/manager/text/undeploy?path=/myapp"

# 再ロード
curl "http://deployer:password@prod:8080/manager/text/reload?path=/myapp"

方式 3: Spring Boot jar + systemd

mvn clean package -DskipTests
scp target/app-1.0.jar deploy@prod:/opt/app/
# /etc/systemd/system/app.service
[Unit]
Description=My Spring Boot App
After=network.target

[Service]
User=app
WorkingDirectory=/opt/app
ExecStart=/usr/bin/java -jar /opt/app/app-1.0.jar \
    --spring.profiles.active=prod \
    --server.port=8080
SuccessExitStatus=143
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now app

# ヘルスチェック
curl http://localhost:8080/actuator/health
# {"status":"UP"}

方式 4: Docker でデプロイ

# Dockerfile (multi-stage)
FROM eclipse-temurin:17-jdk AS build
WORKDIR /app
COPY pom.xml mvnw ./
COPY .mvn .mvn
RUN ./mvnw dependency:go-offline
COPY src src
RUN ./mvnw clean package -DskipTests

FROM eclipse-temurin:17-jre
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s \
    CMD wget -q -O- http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["java","-jar","app.jar"]
# ビルド
docker build -t myapp:1.0 .

# レジストリへ push
docker tag myapp:1.0 registry.example.com/myapp:1.0
docker push registry.example.com/myapp:1.0

# 本番で pull & run
ssh prod
docker pull registry.example.com/myapp:1.0
docker stop myapp || true
docker rm myapp || true
docker run -d --name myapp -p 8080:8080 \
    -e SPRING_PROFILES_ACTIVE=prod \
    --restart=unless-stopped \
    registry.example.com/myapp:1.0

方式 5: GitHub Actions で CI/CD

# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'
          cache: maven

      - run: mvn clean package -DskipTests

      - name: Deploy via SCP
        uses: appleboy/scp-action@v0.1.7
        with:
          host: ${{ secrets.PROD_HOST }}
          username: deploy
          key: ${{ secrets.SSH_KEY }}
          source: target/*.jar
          target: /opt/app/

      - name: Restart service
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.PROD_HOST }}
          username: deploy
          key: ${{ secrets.SSH_KEY }}
          script: |
            sudo systemctl restart app
            sleep 5
            curl -f http://localhost:8080/actuator/health

無停止デプロイの戦略

戦略仕組み難易度
Rolling Updatek8s 等で 1 Pod ずつ置換、常に最低 N 個稼働k8s 標準
Blue-Green旧 (Blue) と新 (Green) を同時起動 → LB で切替 → Blue 廃止
Canary新版に 1% トラフィック → 5% → 25% → 100%、異常で即戻し
Feature Flagデプロイ ≠ リリース。コード内フラグで段階公開

必ず用意するもの

  • ヘルスチェック: /actuator/health / 独自 /healthz
  • レディネス vs ライブネス: 起動完了 vs 死活
  • ロールバック手順: 1 コマンドで前バージョンへ(タグ運用)
  • DB マイグレーション: Flyway / Liquibase で SQL 履歴管理
  • ログ集約: CloudWatch / ELK / Loki
  • 監視: Prometheus + Grafana / Datadog / Mackerel

FAQ

Q: war と jar、どちらが本番向き?
A: 新規は jar (Spring Boot)。既存資産が WAR ベースで動いているなら無理に変えなくて良い。

Q: デプロイのたびにセッションが切れる
A: Redis / DB セッションストアで外出し。Spring Session が定番。

Q: 環境ごとの設定どう分ける?
A: application-{profile}.yml + 環境変数(12-factor)。秘密情報は Vault / AWS Secrets Manager。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. Pleades導入方法(Windows)
  2. Tomcatの起動ボタンを表示
  3. 色・テーマの変更
  4. Tomcatプロジェクトのディレクトリ構成
  5. プロジェクトをTomcatプロジェクトとして認識させる方法
  6. Webアプリケーションのデプロイ方法
  7. 便利ショートカット一覧
  8. エラー一覧
  9. サーバーの設定
  10. サーバーとプロジェクトの紐づけ
  11. Tomcatの起動時のログがconsole上に表示されない時の対応
  12. macOSで複数のワークスペースを起動させる方法