目次
- Dockerを使用したJava開発環境の基礎知識
- DockerでJava開発環境を構築するメリット
- 必要な前提知識と環境準備
- JavaアプリケーションのDockerfile作成方法
- 基本的なDockerfileの構造と書き方
- マルチステージビルドによる最適化テクニック
- 実践的なDockerfileテンプレート集
- Docker Composeを活用した開発環境の構築
- docker-compose.ymlの基本設定方法
- データベースとの連携設定
- 開発環境と本番環境の切り替え方法
- 実践的なパフォーマンスチューニング
- JVMのメモリ設定最適化
- コンテナリソースの適切な設定方法
- ビルド時間を短縮するテクニック
- セキュリティ対策とベストプラクティス
- 脆弱性スキャンの導入方法
- セキュアなイメージ構築のポイント
- 権限管理とセキュリティ設定
- CI/CDパイプラインへの統合
- GitHub Actionsとの連携方法
- 自動テストと品質チェックの実装
- 本番環境へのデプロイメント戦略
- トラブルシューティングガイド
- よくあるエラーと解決方法
- デバッグとログ収集のテクニック
- パフォーマンス問題の診断と改善
Dockerを使用したJava開発環境の基礎知識
DockerでJava開発環境を構築するメリット
Docker(コンテナ技術)を使用してJava開発環境を構築することで、以下のような大きなメリットが得られます:
メリット
1. 環境の一貫性確保
- 開発環境の標準化
- 全開発者が同じJavaバージョン、同じライブラリバージョンを使用
- 「自分の環境では動くのに」問題の解消
- 本番環境との一致
- 開発環境と本番環境の差異を最小化
- デプロイメントリスクの低減
2. 迅速な環境構築
- 新規メンバーのオンボーディング時間短縮
docker-compose upだけで環境構築完了- 複雑な設定作業が不要
- プロジェクト切り替えの容易さ
- 異なるJavaバージョンのプロジェクトも共存可能
- コンテナの起動/停止で即座に切り替え
3. リソース効率の向上
- システムリソースの最適化
- 必要なときだけコンテナを起動
- 複数プロジェクトの効率的な管理
- クリーンな環境維持
- 不要になったら
docker rmで完全削除 - ホストマシンを汚さない
必要な前提知識と環境準備
1. 必要な前提知識
| 分野 | 必要な知識レベル | 具体的な内容 |
|---|---|---|
| Java | 基本的な理解 | – JDKの基礎知識 – ビルドツール(Maven/Gradle)の使用経験 |
| Docker | 基本概念の理解 | – コンテナの概念 – イメージとコンテナの違い – 基本的なDockerコマンド |
| Linux | 基本的なコマンド | – シェルの基本操作 – ファイル操作コマンド |
2. 環境準備手順
- Dockerのインストール
# macOSの場合(Homebrew使用) brew install --cask docker # Ubuntuの場合 sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io # Windowsの場合 # Docker Desktop for Windowsをインストール
- Docker Composeのインストール(Docker Desktopには同梱)
# Linux環境での個別インストール sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose
- 動作確認
# Dockerデーモンの起動確認 docker --version docker-compose --version # テストコンテナの実行 docker run hello-world
3. プロジェクト固有の準備
- プロジェクトフォルダ構成
project-root/ ├── src/ │ └── main/ │ └── java/ ├── Dockerfile ├── docker-compose.yml ├── .dockerignore └── pom.xml(または build.gradle)
- .dockerignoreファイルの作成
target/ .git/ .gitignore *.md
- 必要なポートの確認
- アプリケーションサーバー用ポート(デフォルト: 8080)
- デバッグポート(デフォルト: 5005)
- データベース接続ポート(MySQL: 3306、PostgreSQL: 5432など)
開発環境の要件確認チェックリスト
- [ ] JDKバージョンの決定
- [ ] 使用するビルドツールの選択(Maven/Gradle)
- [ ] 必要なミドルウェアの特定(DB、キャッシュなど)
- [ ] 開発ツール連携の確認(IDE、デバッガー)
- [ ] チーム内での運用ルール策定
以上が基礎知識セクションの内容となります。次のセクションに進むべきでしょうか?
JavaアプリケーションのDockerfile作成方法
基本的なDockerfileの構造と書き方
Dockerfileは、Javaアプリケーションのコンテナイメージを作成するための設計図です。以下で、基本的な構造と重要な命令について説明します。
1. 基本構造
# ベースイメージの指定 FROM eclipse-temurin:17-jdk # 作業ディレクトリの設定 WORKDIR /app # ビルドに必要なファイルのコピー COPY pom.xml . COPY src ./src # Mavenビルドの実行 RUN mvn clean package # JARファイルの実行 CMD ["java", "-jar", "target/application.jar"]
2. 重要なDockerfile命令の解説
| 命令 | 用途 | 使用例 |
|---|---|---|
| FROM | ベースイメージの指定 | FROM eclipse-temurin:17-jdk |
| WORKDIR | 作業ディレクトリの設定 | WORKDIR /app |
| COPY | ファイルのコピー | COPY src ./src |
| ADD | ファイルの追加(圧縮ファイルは解凍) | ADD archive.tar.gz /app |
| RUN | ビルド時のコマンド実行 | RUN mvn package |
| CMD | コンテナ起動時のコマンド | CMD ["java", "-jar", "app.jar"] |
| ENTRYPOINT | 固定の起動コマンド | ENTRYPOINT ["java"] |
| ENV | 環境変数の設定 | ENV JAVA_OPTS="-Xmx512m" |
マルチステージビルドによる最適化テクニック
マルチステージビルドを使用することで、最終的なイメージサイズを大幅に削減できます。
1. マルチステージビルドの基本構造
# ビルドステージ FROM maven:3.8.4-eclipse-temurin-17 AS builder WORKDIR /build COPY pom.xml . COPY src ./src RUN mvn clean package # 実行ステージ FROM eclipse-temurin:17-jre-alpine WORKDIR /app COPY --from=builder /build/target/*.jar app.jar ENTRYPOINT ["java", "-jar", "app.jar"]
2. 最適化のポイント
- 依存関係のキャッシュ
- レイヤーの最適化
- 変更頻度の低いレイヤーを先に配置
- 適切なキャッシュ戦略の採用
- 不要なファイルの除外
# 依存関係のキャッシュ層 FROM maven:3.8.4-eclipse-temurin-17 AS deps WORKDIR /build COPY pom.xml . RUN mvn dependency:go-offline # ビルド層 FROM deps AS builder COPY src ./src RUN mvn clean package # 実行層 FROM eclipse-temurin:17-jre-alpine WORKDIR /app COPY --from=builder /build/target/*.jar app.jar ENTRYPOINT ["java", "-jar", "app.jar"]
実践的なDockerfileテンプレート集
1. Spring Bootアプリケーション用テンプレート
# ベースイメージの選択 FROM maven:3.8.4-eclipse-temurin-17 AS builder # キャッシュ最適化のためのpom.xmlコピー WORKDIR /build COPY pom.xml . RUN mvn dependency:go-offline # ソースコードのコピーとビルド COPY src ./src RUN mvn clean package -DskipTests # 実行環境の準備 FROM eclipse-temurin:17-jre-alpine WORKDIR /app # ヘルスチェック用のツール追加 RUN apk add --no-cache curl # アプリケーションのコピー COPY --from=builder /build/target/*.jar app.jar # 環境変数の設定 ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0" # ヘルスチェックの設定 HEALTHCHECK --interval=30s --timeout=3s \ CMD curl -f http://localhost:8080/actuator/health || exit 1 # 起動コマンド ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
2. マイクロサービス用軽量テンプレート
# ビルドステージ FROM maven:3.8.4-eclipse-temurin-17 AS builder WORKDIR /build # 依存関係の管理 COPY pom.xml . RUN mvn dependency:go-offline # ソースコードのビルド COPY src ./src RUN mvn clean package -DskipTests # 実行ステージ FROM eclipse-temurin:17-jre-alpine WORKDIR /app # セキュリティ強化 RUN addgroup -S appgroup && adduser -S appuser -G appgroup USER appuser # アプリケーションのコピー COPY --from=builder /build/target/*.jar app.jar # 環境変数とポートの設定 ENV JAVA_OPTS="-Xms256m -Xmx512m" EXPOSE 8080 # 起動コマンド ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
3. 開発環境用デバッグ対応テンプレート
FROM eclipse-temurin:17-jdk
WORKDIR /app
# 開発ツールのインストール
RUN apt-get update && apt-get install -y \
maven \
git \
&& rm -rf /var/lib/apt/lists/*
# デバッグポートの公開
EXPOSE 8080 5005
# デバッグモードでの起動スクリプト
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
# docker-entrypoint.sh
#!/bin/sh
exec java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 \
-jar app.jar
以上のテンプレートは、実際のプロジェクトの要件に応じてカスタマイズしてご利用ください。特に環境変数、メモリ設定、ポート番号などは、プロジェクトの要件に合わせて適切に調整することをお勧めします。
Docker Composeを活用した開発環境の構築
docker-compose.ymlの基本設定方法
Docker Composeを使用することで、複数のコンテナを一元管理し、開発環境を簡単に構築・運用できます。
1. 基本的な構造
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=dev
volumes:
- ./:/app
- ~/.m2:/root/.m2
depends_on:
- db
2. 主要な設定項目の解説
| 設定項目 | 説明 | 使用例 |
|---|---|---|
| version | Compose fileのバージョン | version: '3.8' |
| services | コンテナの定義 | services: app: ... |
| build | ビルド設定 | build: context: . |
| ports | ポートマッピング | ports: - "8080:8080" |
| environment | 環境変数設定 | environment: - KEY=VALUE |
| volumes | ボリュームマウント | volumes: - ./:/app |
| depends_on | 依存関係の定義 | depends_on: - db |
データベースとの連携設定
1. データベースサービスの設定
version: '3.8'
services:
app:
build: .
ports:
- "8080:8080"
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/myapp
- SPRING_DATASOURCE_USERNAME=postgres
- SPRING_DATASOURCE_PASSWORD=secret
depends_on:
- db
db:
image: postgres:14-alpine
ports:
- "5432:5432"
environment:
- POSTGRES_DB=myapp
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=secret
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
volumes:
postgres_data:
2. データベース初期化スクリプト(init.sql)
-- テーブル作成
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 初期データ投入
INSERT INTO users (username, email) VALUES
('test_user', 'test@example.com');
3. データベース管理ツールの追加
adminer:
image: adminer
ports:
- "8081:8080"
depends_on:
- db
開発環境と本番環境の切り替え方法
1. 環境別の設定ファイル構成
project/ ├── docker-compose.yml # 基本設定 ├── docker-compose.dev.yml # 開発環境用 ├── docker-compose.prod.yml # 本番環境用 └── docker-compose.test.yml # テスト環境用
2. 開発環境設定(docker-compose.dev.yml)
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
volumes:
- ./:/app
- ~/.m2:/root/.m2
environment:
- SPRING_PROFILES_ACTIVE=dev
- JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
ports:
- "8080:8080"
- "5005:5005"
db:
ports:
- "5432:5432"
volumes:
- ./init-dev.sql:/docker-entrypoint-initdb.d/init.sql
3. 本番環境設定(docker-compose.prod.yml)
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.prod
environment:
- SPRING_PROFILES_ACTIVE=prod
- JAVA_OPTS=-XX:+UseG1GC -XX:MaxRAMPercentage=75
deploy:
resources:
limits:
cpus: '2'
memory: 2G
restart: always
db:
volumes:
- postgres_prod_data:/var/lib/postgresql/data
deploy:
resources:
limits:
memory: 1G
restart: always
volumes:
postgres_prod_data:
4. 環境切り替えコマンド
# 開発環境の起動 docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d # 本番環境の起動 docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d # テスト環境の起動 docker-compose -f docker-compose.yml -f docker-compose.test.yml up -d
5. 環境別の設定管理のベストプラクティス
- 環境変数の管理
# .env.dev
POSTGRES_DB=myapp_dev
POSTGRES_USER=dev_user
POSTGRES_PASSWORD=dev_password
# .env.prod
POSTGRES_DB=myapp_prod
POSTGRES_USER=prod_user
POSTGRES_PASSWORD=${PROD_DB_PASSWORD}
- プロファイル別の設定
# application-dev.yml
spring:
datasource:
url: jdbc:postgresql://db:5432/myapp_dev
username: dev_user
password: dev_password
# application-prod.yml
spring:
datasource:
url: jdbc:postgresql://db:5432/myapp_prod
username: prod_user
password: ${PROD_DB_PASSWORD}
これらの設定を使用することで、開発からプロダクションまでのスムーズな環境移行が可能になります。また、各環境に特化した最適な設定を維持しながら、統一的な管理が実現できます。
実践的なパフォーマンスチューニング
JVMのメモリ設定最適化
コンテナ環境でのJavaアプリケーションのパフォーマンスを最大化するには、適切なJVMメモリ設定が不可欠です。
1. コンテナ対応のJVMオプション
ENV JAVA_OPTS="\
-XX:+UseContainerSupport \
-XX:MaxRAMPercentage=75.0 \
-XX:InitialRAMPercentage=50.0 \
-XX:+UseG1GC \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/dumps"
| オプション | 説明 | 推奨値 |
|---|---|---|
| UseContainerSupport | コンテナリソースの認識を有効化 | 常に有効化 |
| MaxRAMPercentage | 最大ヒープサイズの割合 | 70-80% |
| InitialRAMPercentage | 初期ヒープサイズの割合 | 40-60% |
| UseG1GC | G1GCの使用 | 標準設定 |
2. メモリ使用量のモニタリング設定
# docker-compose.yml
services:
app:
environment:
- JAVA_TOOL_OPTIONS="-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false"
ports:
- "9010:9010"
コンテナリソースの適切な設定方法
1. リソース制限の設定
services:
app:
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '1'
memory: 1G
2. スケーリング戦略
services:
app:
deploy:
mode: replicated
replicas: 3
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
max_attempts: 3
window: 120s
3. リソースモニタリングの設定
services:
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
depends_on:
- prometheus
ビルド時間を短縮するテクニック
1. マルチステージビルドの最適化
# ベースイメージのキャッシュ
FROM maven:3.8.4-eclipse-temurin-17 AS deps
WORKDIR /build
COPY pom.xml .
RUN mvn dependency:go-offline
# ビルドステージ
FROM deps AS builder
COPY src ./src
RUN mvn package -DskipTests \
-Dmaven.javadoc.skip=true \
-Dmaven.source.skip=true
# 実行環境
FROM eclipse-temurin:17-jre-alpine
COPY --from=builder /build/target/*.jar app.jar
2. Mavenビルドの最適化
<!-- pom.xml -->
<properties>
<maven.test.skip>true</maven.test.skip>
<maven.javadoc.skip>true</maven.javadoc.skip>
<maven.source.skip>true</maven.source.skip>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<fork>true</fork>
<meminitial>128m</meminitial>
<maxmem>512m</maxmem>
</configuration>
</plugin>
</plugins>
</build>
3. ビルドキャッシュの最適化戦略
Dockerビルドキャッシュの設定
# docker-compose.yml
services:
app:
build:
context: .
dockerfile: Dockerfile
cache_from:
- myapp:latest
args:
BUILDKIT_INLINE_CACHE: 1
ビルドスクリプトの例
#!/bin/bash # build-optimized.sh # キャッシュの活用 docker pull myapp:latest || true # BuildKitを使用したビルド DOCKER_BUILDKIT=1 docker build \ --cache-from myapp:latest \ --build-arg BUILDKIT_INLINE_CACHE=1 \ -t myapp:latest . # キャッシュの保存 docker push myapp:latest
4. パフォーマンス最適化チェックリスト
- JVMメモリ設定
- [ ] コンテナ認識の有効化確認
- [ ] ヒープサイズの適切な設定
- [ ] GCログの有効化と監視
- コンテナリソース
- [ ] CPU制限の確認
- [ ] メモリ制限の確認
- [ ] スケーリング設定の最適化
- ビルド最適化
- [ ] マルチステージビルドの利用
- [ ] キャッシュ戦略の実装
- [ ] 不要な処理のスキップ
これらの設定とテクニックを適切に組み合わせることで、開発環境から本番環境まで、効率的なコンテナ運用が可能になります。特に、リソース使用状況を定期的にモニタリングし、必要に応じて設定を調整することが重要です。
セキュリティ対策とベストプラクティス
脆弱性スキャンの導入方法
コンテナセキュリティを確保するための第一歩は、継続的な脆弱性スキャンの実施です。
1. Trivyを使用した脆弱性スキャン
# .github/workflows/security-scan.yml
name: Security Scan
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 0 * * *'
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:latest'
format: 'table'
exit-code: '1'
severity: 'CRITICAL,HIGH'
2. スキャン結果の管理
services:
defectdojo:
image: defectdojo/defectdojo
ports:
- "8080:8080"
environment:
- DD_DATABASE_URL=postgresql://defectdojo:secret@db:5432/defectdojo
volumes:
- defectdojo_media:/app/media
3. 自動スキャンスクリプト
#!/bin/bash
# scan-image.sh
IMAGE_NAME=$1
TAG=${2:-latest}
# イメージのスキャン
trivy image --severity HIGH,CRITICAL \
--output trivy-results.json \
--format json \
${IMAGE_NAME}:${TAG}
# 結果の解析と報告
if [ $? -eq 0 ]; then
echo "No security issues found"
else
echo "Security issues detected. Check trivy-results.json"
exit 1
fi
セキュアなイメージ構築のポイント
1. セキュアベースイメージの選択
# セキュアなベースイメージを使用
FROM eclipse-temurin:17-jre-alpine
# 必要最小限のパッケージのみインストール
RUN apk add --no-cache \
curl \
tzdata \
&& rm -rf /var/cache/apk/*
# 非rootユーザーの作成と切り替え
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# アプリケーションの配置
COPY --chown=appuser:appgroup target/*.jar app.jar
# 最小限の環境変数設定
ENV JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom -Dfile.encoding=UTF-8"
# ヘルスチェックの追加
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["java", "-jar", "app.jar"]
2. マルチステージビルドでのセキュリティ強化
# ビルドステージ FROM maven:3.8.4-eclipse-temurin-17 AS builder WORKDIR /build # 依存関係のチェック COPY pom.xml . RUN mvn dependency-check:check # ソースコードの静的解析 COPY src ./src RUN mvn verify -Psecurity # 実行環境 FROM eclipse-temurin:17-jre-alpine USER appuser COPY --from=builder --chown=appuser:appgroup /build/target/*.jar app.jar
3. セキュリティスキャン自動化の設定
# docker-compose.security.yml
services:
clair:
image: quay.io/coreos/clair
ports:
- "6060:6060"
depends_on:
- clairdb
clairdb:
image: postgres:14-alpine
environment:
- POSTGRES_PASSWORD=secret
権限管理とセキュリティ設定
1. アプリケーションの権限設定
# docker-compose.yml
services:
app:
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
read_only: true
tmpfs:
- /tmp
2. シークレット管理
version: '3.8'
services:
app:
environment:
- SPRING_PROFILES_ACTIVE=prod
secrets:
- db_password
- api_key
secrets:
db_password:
file: ./secrets/db_password.txt
api_key:
file: ./secrets/api_key.txt
3. ネットワークセキュリティ設定
# docker-compose.yml
networks:
frontend:
driver: overlay
internal: false
backend:
driver: overlay
internal: true
services:
app:
networks:
- frontend
- backend
db:
networks:
- backend
セキュリティベストプラクティスチェックリスト
- イメージセキュリティ
- [ ] 最小限のベースイメージ使用
- [ ] 定期的な脆弱性スキャン実施
- [ ] マルチステージビルド採用
- [ ] 不要なパッケージの除去
- 実行時セキュリティ
- [ ] 非rootユーザーでの実行
- [ ] 必要最小限の権限設定
- [ ] read-onlyファイルシステム
- [ ] セキュアな環境変数管理
- アクセス制御
- [ ] ネットワークセグメンテーション
- [ ] シークレット管理の適切な実装
- [ ] コンテナ間通信の制限
- [ ] ポート公開の最小化
- モニタリングと監査
- [ ] セキュリティログの収集
- [ ] 異常検知の実装
- [ ] 定期的なセキュリティ監査
- [ ] インシデント対応計画の策定
これらのセキュリティ対策を適切に実装することで、コンテナ化されたJavaアプリケーションの安全性を大幅に向上させることができます。定期的なセキュリティ評価と更新を行うことも重要です。
CI/CDパイプラインへの統合
GitHub Actionsとの連携方法
GitHub Actionsを使用してJava×Dockerの継続的インテグレーション/デリバリーを実装します。
1. 基本的なCI/CDワークフロー
# .github/workflows/ci-cd.yml
name: Java Docker CI/CD
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: 'maven'
- name: Build and Test
run: mvn clean verify
- name: Build Docker image
run: docker build -t myapp:${GITHUB_SHA} .
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Push Docker image
run: |
docker tag myapp:${GITHUB_SHA} ghcr.io/${{ github.repository }}/myapp:${GITHUB_SHA}
docker push ghcr.io/${{ github.repository }}/myapp:${GITHUB_SHA}
2. 環境別のデプロイメントワークフロー
# .github/workflows/deployment.yml
name: Deploy to Environment
on:
workflow_run:
workflows: ["Java Docker CI/CD"]
types:
- completed
branches:
- main
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment: staging
steps:
- name: Deploy to Staging
uses: azure/webapps-deploy@v2
with:
app-name: myapp-staging
images: ghcr.io/${{ github.repository }}/myapp:${GITHUB_SHA}
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment: production
steps:
- name: Deploy to Production
uses: azure/webapps-deploy@v2
with:
app-name: myapp-production
images: ghcr.io/${{ github.repository }}/myapp:${GITHUB_SHA}
自動テストと品質チェックの実装
1. テスト自動化の設定
# .github/workflows/tests.yml
name: Automated Tests
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Unit Tests
run: mvn test
- name: Integration Tests
run: |
docker-compose -f docker-compose.test.yml up -d
mvn verify -P integration-test
- name: Code Coverage
run: mvn jacoco:report
- name: SonarQube Analysis
run: |
mvn sonar:sonar \
-Dsonar.host.url=${{ secrets.SONAR_URL }} \
-Dsonar.login=${{ secrets.SONAR_TOKEN }}
2. 品質ゲートの設定
jobs:
quality-check:
runs-on: ubuntu-latest
steps:
- name: Code Style Check
run: mvn checkstyle:check
- name: Dependency Check
run: mvn dependency-check:check
- name: SpotBugs Analysis
run: mvn spotbugs:check
- name: Quality Gate
run: |
if [ $(mvn sonar:sonar -Dsonar.qualitygate.wait=true) -eq 1 ]; then
echo "Quality Gate failed!"
exit 1
fi
3. テスト結果の保存と可視化
- name: Publish Test Results
uses: actions/upload-artifact@v3
with:
name: test-results
path: |
target/surefire-reports
target/failsafe-reports
target/site/jacoco
本番環境へのデプロイメント戦略
1. ブルーグリーンデプロイメントの実装
# .github/workflows/blue-green-deployment.yml
name: Blue-Green Deployment
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy Green Environment
run: |
# 新バージョンをGreenにデプロイ
kubectl apply -f k8s/green-deployment.yml
# ヘルスチェック
./scripts/health-check.sh green
# トラフィックの切り替え
kubectl apply -f k8s/switch-to-green.yml
# 古いBlue環境の削除
kubectl delete -f k8s/blue-deployment.yml
2. デプロイメントスクリプト例
#!/bin/bash
# scripts/deploy.sh
# 環境変数の設定
ENV=$1
VERSION=$2
# イメージの準備
docker pull ghcr.io/myapp:${VERSION}
# 新環境のデプロイ
envsubst < k8s/deployment.template.yml | kubectl apply -f -
# ヘルスチェック
attempt=1
max_attempts=30
until $(curl --output /dev/null --silent --head --fail http://localhost:8080/actuator/health); do
if [ ${attempt} -eq ${max_attempts} ]; then
echo "Max attempts reached. Deployment failed!"
exit 1
fi
printf '.'
attempt=$(( attempt + 1 ))
sleep 2
done
echo "Deployment successful!"
3. デプロイメント設定例
# k8s/deployment.template.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-${COLOR}
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
spec:
containers:
- name: myapp
image: ghcr.io/myapp:${VERSION}
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 10
periodSeconds: 3
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
デプロイメントベストプラクティス
- 段階的なデプロイメント戦略
- ステージング環境での事前検証
- カナリアリリースの活用
- ロールバック手順の整備
- モニタリングと検証
- デプロイメント前後の健全性確認
- パフォーマンスメトリクスの収集
- エラーレート監視
- セキュリティ考慮事項
- シークレット管理の自動化
- 環境変数の適切な取り扱い
- アクセス制御の確保
- 自動化のポイント
- デプロイメントの完全自動化
- ロールバックの自動化
- 通知の自動化
これらのCI/CD設定により、安全で効率的な開発・デプロイメントサイクルを実現できます。
トラブルシューティングガイド
よくあるエラーと解決方法
Docker×Java環境で発生する主なエラーとその解決方法をまとめます。
1. メモリ関連の問題
| エラー | 原因 | 解決策 |
|---|---|---|
java.lang.OutOfMemoryError: Java heap space | JVMヒープメモリ不足 | – コンテナメモリ制限の確認 – JVMメモリ設定の調整 |
java.lang.OutOfMemoryError: Metaspace | メタスペース領域不足 | – -XX:MaxMetaspaceSizeの増加– 不要なクラスロードの削減 |
# メモリ使用状況の確認 docker stats # JVMメモリ設定の調整例 docker run -e JAVA_OPTS="-Xmx1g -XX:MaxMetaspaceSize=256m" myapp
2. コンテナ起動の問題
# コンテナログの確認 docker logs <container_id> # 詳細なシステム情報の取得 docker inspect <container_id> # コンテナ内でのデバッグ実行 docker exec -it <container_id> /bin/sh
3. ネットワーク接続の問題
# docker-compose.debug.yml
services:
app:
networks:
- backend
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 10s
timeout: 5s
retries: 3
デバッグとログ収集のテクニック
1. リモートデバッグの設定
# Dockerfile.debug FROM eclipse-temurin:17-jdk ENV JAVA_TOOL_OPTIONS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005" EXPOSE 5005
# デバッグモードでの起動 docker-compose -f docker-compose.debug.yml up
2. ログ収集システムの構築
# docker-compose.logging.yml
services:
app:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
filebeat:
image: docker.elastic.co/beats/filebeat:7.15.0
volumes:
- ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.15.0
environment:
- discovery.type=single-node
kibana:
image: docker.elastic.co/kibana/kibana:7.15.0
ports:
- "5601:5601"
3. デバッグスクリプト集
#!/bin/bash
# debug-tools.sh
# ヒープダンプの取得
get_heap_dump() {
container_id=$1
docker exec $container_id jmap -dump:format=b,file=/dumps/heap.hprof 1
docker cp $container_id:/dumps/heap.hprof ./heap.hprof
}
# スレッドダンプの取得
get_thread_dump() {
container_id=$1
docker exec $container_id jstack 1 > thread_dump.txt
}
# GCログの有効化
enable_gc_logging() {
docker run -e JAVA_OPTS="-Xlog:gc*=debug:file=/logs/gc.log" myapp
}
パフォーマンス問題の診断と改善
1. パフォーマンス監視設定
# docker-compose.monitoring.yml
services:
app:
ports:
- "8080:8080"
- "9090:9090" # JMX Exporter
environment:
- JAVA_OPTS=-javaagent:/app/jmx_prometheus_javaagent.jar=9090:/app/config.yaml
volumes:
- ./monitoring/jmx_prometheus_javaagent.jar:/app/jmx_prometheus_javaagent.jar
- ./monitoring/config.yaml:/app/config.yaml
2. パフォーマンス診断スクリプト
#!/bin/bash
# performance-analysis.sh
# CPU使用率の確認
check_cpu() {
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"
}
# ボトルネック検出
detect_bottlenecks() {
container_id=$1
echo "=== CPU Hot Spots ==="
docker exec $container_id jcmd 1 VM.native_memory
echo "=== Thread Analysis ==="
docker exec $container_id jcmd 1 Thread.print
echo "=== GC Analysis ==="
docker exec $container_id jcmd 1 GC.heap_info
}
# パフォーマンステスト実行
run_performance_test() {
docker run --rm -v $(pwd):/scripts gatling/gatling:latest \
-sf /scripts/gatling/simulations \
-rf /scripts/gatling/results
}
3. パフォーマンス最適化チェックリスト
- アプリケーションレベル
- [ ] JVMメモリ設定の最適化
- [ ] GC設定の調整
- [ ] スレッドプール設定の確認
- [ ] コネクションプール設定の確認
- コンテナレベル
- [ ] リソース制限の適切な設定
- [ ] ネットワーク設定の最適化
- [ ] ボリュームマウントの効率化
- [ ] キャッシュ戦略の確認
- 監視と分析
- [ ] メトリクス収集の設定
- [ ] アラート閾値の設定
- [ ] パフォーマンステストの自動化
- [ ] ログ分析の実装
4. トラブルシューティングフローチャート
graph TD
A[問題発生] --> B{エラー種別判断}
B -->|メモリエラー| C[メモリ診断]
B -->|起動エラー| D[コンテナログ確認]
B -->|パフォーマンス低下| E[リソース使用率確認]
C --> F[ヒープダンプ分析]
D --> G[Dockerfile確認]
E --> H[モニタリング確認]
F --> I[メモリ設定調整]
G --> J[イメージ再ビルド]
H --> K[リソース制限調整]
これらのトラブルシューティングツールと手順を活用することで、Docker×Java環境での問題をより効率的に解決できます。
まとめ
Docker×Java開発環境構築の重要ポイント
1. 環境構築の基本原則
- 一貫性のある開発環境の維持
- 適切なベースイメージの選択
- 効率的なビルドプロセスの確立
- セキュリティを考慮した設計
2. 実装時の注意点とベストプラクティス
開発効率の最適化
- マルチステージビルドの活用
- 依存関係のキャッシュ戦略
- 開発環境と本番環境の分離
- 適切なリソース管理
セキュリティの確保
- 脆弱性スキャンの定期実行
- 最小権限の原則の遵守
- セキュアな設定の徹底
- 監査ログの適切な管理
パフォーマンスの最適化
- JVMの適切な設定
- コンテナリソースの最適化
- ビルドプロセスの効率化
- 監視体制の確立
次のステップとリソース
1. さらなる学習のために
- Docker公式ドキュメント: https://docs.docker.com/
- Spring Boot with Docker: https://spring.io/guides/topicals/spring-boot-docker/
- Java Performance Tuning: https://docs.oracle.com/en/java/javase/17/performance/
2. 推奨ツール
- Container Security Scanner: Trivy
- Performance Monitoring: Prometheus + Grafana
- CI/CD: GitHub Actions
- Log Management: ELK Stack
3. コミュニティリソース
- Docker Community Forums
- Stack Overflow – Docker タグ
- GitHub – Java Docker サンプルプロジェクト
以上が、Docker×Java開発環境の構築から運用までの包括的なガイドでした。このガイドで紹介した手法やベストプラクティスを活用することで、効率的で安全な開発環境を構築できます。技術の進化に合わせて定期的に設定を見直し、常に最適な開発環境を維持することを推奨します。
注意: 本記事の内容は2024年時点のものです。Docker、Java、および関連ツールのバージョンアップに応じて、適宜設定を調整してください。
Last edited 5 時間前