23.

本番サーバーへのデプロイ方法 (例)

編集
この記事の要点
  • Spring Boot アプリの本番デプロイ方法
  • ① jar 直接実行: java -jar app.jar + systemd でサービス化
  • ② Docker: イメージ化してオーケストレーションツール (Kubernetes 等) で運用
  • ③ WAR + 外部サーバ: 既存 Tomcat / WebLogic に WAR デプロイ
  • CI/CD: GitHub Actions / GitLab CI で自動ビルド・自動デプロイ

 

方法 1: jar 直接実行 (Embedded Tomcat)

Spring Boot は内蔵 Tomcat を含む実行可能 jar を作れます。シンプルで運用しやすい方法。

ビルド

# Maven
$ ./mvnw clean package
# → target/myapp-1.0.0.jar

# Gradle
$ ./gradlew bootJar
# → build/libs/myapp-1.0.0.jar

実行

# 基本実行
$ java -jar myapp.jar

# プロファイル指定 (application-prod.properties を読み込む)
$ java -jar myapp.jar --spring.profiles.active=prod

# 外部の設定ファイルを使う
$ java -jar myapp.jar --spring.config.location=/etc/myapp/application.yml

# JVM オプション
$ java -server -Xms1g -Xmx4g -XX:+UseG1GC -jar myapp.jar

systemd でサービス化

# /etc/systemd/system/myapp.service
[Unit]
Description=My Spring Boot App
After=network.target

[Service]
Type=simple
User=appuser
Group=appuser
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/java -server -Xms1g -Xmx4g -jar /opt/myapp/myapp.jar --spring.profiles.active=prod
SuccessExitStatus=143
Restart=on-failure
RestartSec=10s
StandardOutput=append:/var/log/myapp/app.log
StandardError=append:/var/log/myapp/error.log

[Install]
WantedBy=multi-user.target
# 有効化と起動
$ sudo systemctl daemon-reload
$ sudo systemctl enable myapp
$ sudo systemctl start myapp

# 状態確認
$ sudo systemctl status myapp
$ sudo journalctl -u myapp -f

方法 2: Docker でデプロイ

Dockerfile

# マルチステージビルド (jar をビルド → 軽量ランタイムに配置)
FROM eclipse-temurin:17-jdk AS builder
WORKDIR /workspace
COPY . .
RUN ./gradlew bootJar

FROM eclipse-temurin:17-jre
RUN useradd -m appuser
USER appuser
WORKDIR /app
COPY --from=builder /workspace/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app/app.jar"]

ビルドと実行

# イメージビルド
$ docker build -t myapp:1.0.0 .

# コンテナ起動
$ docker run -d \
  --name myapp \
  -p 8080:8080 \
  -e SPRING_PROFILES_ACTIVE=prod \
  -e SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/mydb \
  -v /var/log/myapp:/app/logs \
  myapp:1.0.0

# レジストリにプッシュ
$ docker tag myapp:1.0.0 my-registry.example.com/myapp:1.0.0
$ docker push my-registry.example.com/myapp:1.0.0

docker-compose

version: "3.8"
services:
  app:
    image: myapp:1.0.0
    ports:
      - "8080:8080"
    environment:
      SPRING_PROFILES_ACTIVE: prod
      SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/mydb
    depends_on:
      - db
  db:
    image: postgres:15
    environment:
      POSTGRES_DB: mydb
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

方法 3: WAR デプロイ(外部 Tomcat)

WAR 化に必要な設定

// メインクラスを SpringBootServletInitializer 継承に
@SpringBootApplication
public class MyApp extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(MyApp.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }
}

war


  
  
    org.springframework.boot
    spring-boot-starter-tomcat
    provided
  
# ビルドして WAR を配置
$ ./mvnw clean package
$ cp target/myapp-1.0.0.war $CATALINA_HOME/webapps/myapp.war
# Tomcat が自動デプロイ
# → http://localhost:8080/myapp/ でアクセス

CI/CD パイプライン

GitHub Actions の例

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

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: 17

      - name: Build
        run: ./gradlew bootJar

      - name: Test
        run: ./gradlew test

      - name: Build Docker
        run: docker build -t myapp:${{ github.sha }} .

      - name: Push to Registry
        run: |
          echo ${{ secrets.REGISTRY_PASSWORD }} | docker login -u ${{ secrets.REGISTRY_USER }} --password-stdin
          docker push myapp:${{ github.sha }}

      - name: Deploy to Server
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.PROD_HOST }}
          username: ${{ secrets.PROD_USER }}
          key: ${{ secrets.PROD_SSH_KEY }}
          script: |
            docker pull myapp:${{ github.sha }}
            docker stop myapp || true
            docker rm myapp || true
            docker run -d --name myapp -p 8080:8080 myapp:${{ github.sha }}

本番運用のチェックリスト

  • 環境別プロファイル: application-prod.yml で本番設定を分離
  • シークレット管理: パスワード等は環境変数 / Vault / AWS Secrets Manager
  • JVM オプション: -Xmx, -XX:+HeapDumpOnOutOfMemoryError
  • ヘルスチェック: actuator/health エンドポイント有効化
  • メトリクス: Prometheus / Micrometer で監視
  • ロギング: 集約ログ (ELK / Loki / CloudWatch)
  • リバースプロキシ: nginx で TLS 終端、X-Forwarded-* ヘッダ伝達
  • ローリングデプロイ: ダウンタイムなしの更新(K8s rolling update / Blue-Green)
  • DB マイグレーション: Flyway / Liquibase で自動実行
  • ロールバック手順: 失敗時の即座復旧

本番設定の例 (application-prod.yml)

spring:
  datasource:
    url: ${DB_URL}
    username: ${DB_USER}
    password: ${DB_PASSWORD}
    hikari:
      maximum-pool-size: 50
  jpa:
    hibernate:
      ddl-auto: validate
  flyway:
    enabled: true

server:
  port: 8080
  tomcat:
    threads:
      max: 200
  compression:
    enabled: true
  forward-headers-strategy: native  # nginx 後ろなら必須

management:
  endpoints:
    web:
      exposure:
        include: health,metrics,prometheus
  endpoint:
    health:
      show-details: never

logging:
  level:
    root: INFO
    com.example: DEBUG
  file:
    name: /var/log/myapp/app.log

関連記事

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. インストールと設定
  2. クイックスタート & チュートリアル(初心者向け)
  3. クイックスタート & チュートリアル(中級者向け)
  4. ルーティング
  5. Bladeテンプレート(ビュー/レイアウト)
  6. コントローラー
  7. マイグレーションとテーブル定義
  8. データベースの設定
  9. Eloquentモデル (ORM)
  10. SQLとクエリビルダー
  11. バリデーション
  12. .envファイルの設定値へのアクセス
  13. 動作環境による分岐処理
  14. configフォルダ配下の設定値へのアクセス
  15. assetヘルパーを利用したpublicフォルダへのアクセス
  16. storageフォルダへのアクセス
  17. アプリケーション名の変更
  18. メンテナンス
  19. ログイン画面(認証システム)の作成
  20. ログインの必須化
  21. ログインユーザー情報の取得
  22. ルートの認証化
  23. 本番サーバーへのデプロイ方法
  24. 多言語化
  25. csrf_field
  26. ファイルのダウンロード
  27. CSVのアップロードおよび読み込み(maatwebsite/excel)
  28. ページタイトルの設定
  29. コマンド一覧
  30. エラー一覧
  31. SQLの実行ログ出力方法
  32. キャッシュのクリア
  33. Selectの結果の最初もしくは最後に任意の値を追加する方法
  34. ajaxでPOST通信する際の注意点
  35. ソーシャルログインの実装
  36. セッション情報の確認
  37. ログイン、ユーザー登録、パスワードリセット後のリダイレクト先の変更方法
  38. redirectやreturn viewにメッセージを付与する方法
  39. クッキー(cookie)の設定と取得
  40. クラスの再読み込み
  41. csrfの有効時間を変更する方法
  42. ViewComposerを用いてviewに共通の値を付与する方法
  43. View::shareを用いて共通の値を各ビューに渡す方法
  44. ミドルウェアを用いた処理の共通化
  45. Middleware内でAuth::check()などを使用する方法
  46. Controller以外でリダイレクトする方法
  47. セッションの値の取得/保存/更新/削除
  48. $requestの値を変更する方法
  49. 常時SSL化
  50. ページング(ページネーション)をする方法
  51. vue.jsとの連携
  52. Vue.jsと連携するSPA実行環境構築
  53. .envの値をvue.jsで参照する方法
  54. vue.jsを本番環境にリリースする方法
  55. could not find driver(Windows, MySQL編)