0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

VSCodeで始めるDockerコンテナ上にJava開発環境を構築(②Dockerコンテナ編)

Last updated at Posted at 2024-09-22

目的

前回「①WSL環境準備」の続きとして、Dockerコンテナ上にJava開発環境(複数バージョン)を構築します。
本記事では、VSCodeのDev Containers拡張機能を利用し、作成したJava開発環境にアクセスできるところまで確認する予定です。
前回の記事はこちら(①WSL環境準備編)

第2回「②Dockerコンテナ編」における記載範囲

  • VSCodeでDev Containersを利用する準備として、「devcontainer.json」の作成
  • Dockerイメージの元になる「Dockerfile」の作成
  • 複数コンテナ管理を見据え、「docker-compose.yml」の作成 ※1
  • VSCodeのDev Containersを利用し、コンテナ(Java開発環境)にアクセス

※1
今回の記事では1つのコンテナのため、複数のコンテナを管理する想定はありません。
続編としてJenkins環境構築に関する記事を公開予定のため、本記事でも「docker-dompose.yml」を利用する方法としています。

1. 事前準備

  • VSCodeの拡張機能(Extensions)に「Dev Containers」を導入しておきます。

【VSCode手順】

  1. VSCodeの左側ペインにて「EXTENSIONS」(拡張機能)を選択、または「Ctrl + Shift + X」を押下
  2. 検索ボックスにて「Dev Containers」を入力
  3. 「Dev Containers」を選択し、Installを実行

2. Dockerコンテナ上に構築する環境

  • OpenJDK、Mavenを導入した開発環境
  • SDKMAN(※2)を導入し、複数のJavaバージョン(Java17、21)を切り替え可能
  • proxy設定を行い、企業内の環境で利用する想定(※3)

※2
SDKMAN(Software Development Kit Manager)は、JavaやGroovy、ScalaなどのJVM言語やmaven、gradleといったビルドツールのインストールや管理を簡単にし、特定のバージョンへの切り替えを容易にする。

※3
環境によってはproxy設定は不要になるため、別記事で試した内容は投稿したいと思います。

3. Dev Container準備

3.1. VS Code上のディレクトリ構成

VSCodeからは、下記の『ホスト側のディレクトリ構成』の"."位置がカレントディレクトリとなるようにフォルダを開きます。

【VSCode手順】

  1. VSCodeの左側ペインにてExplorer(Ctrl + Shift + E)から「Open Folder」を選択し、カレントディレクトリを指定

Open Folder.PNG

ホスト側のディレクトリ構成

/home/
└── ubuntu/
    ├── .devcontainer/
    │   └── devcontainer.json
    ├── development/
    │   ├── Dockerfile
    │   └── settings.xml
    └── docker-compose.yml
/etc/
├── docker/
│   └── daemon.json
└── systemd/
    └── system/
        └── docker.service.d/
            └── http-proxy.conf
~/.docker/
└── config.json

コンテナ側のディレクトリ構成

/opt/
└── docker/
    └── project/
        ├── .m2/
        │   └── repository/
        └── settings.xml
/home/
└── app01/
    ├── .sdkman/
    │   └── candidates/
    │       ├── java/
    │       │   ├── 17.0.12-tem/
    │       │   │   └── bin/
    │       │   └── 21.0.4-tem/
    │       │       └── bin/
    │       └── maven/
    │           └── 3.9.8/
    └── .bashrc

3.2. devcontainer.jsonの作成

.devcontainerディレクトリ配下に「devcontainer.json」を作成します。

devcontainer.json
{
    "name": "Java Development Environment",
    // devcontainer.jsonを起点としたdocker-compose.ymlのディレクトリパス
    "dockerComposeFile": "../docker-compose.yml",
    "forwardPorts": [8080],
    "service": "app",
    // コンテナログイン時のカレントディレクトリ(存在するディレクトリを指定)
    "workspaceFolder": "/home/app01",
    
    "customizations": {
        "vscode": {
            "settings": {
                "java.configuration.runtimes" : [
                    {
                        "name": "JavaSE-17",
                        "path": "/home/app01/.sdkman/candidates/java/17.0.12-tem",
                        "default": true
                    },
                    {
                        "name": "JavaSE-21",
                        "path": "/home/app01/.sdkman/candidates/java/21.0.4-tem"
                    }
                ],
                "java.jdt.ls.vmargs": "-Xmx2G -XX:+UseG1GC -XX:+useStringDeduplication"
            },
            "extensions": [
                "redhat.java",
                "vscjava.vscode-java-debug",
                "vscjava.vscode-java-test"
            ]
        }
    }
}

4. Dockerfileの作成

アプリケーション環境としてSDKMAN(※2)を導入し、複数のJavaバージョンを管理できるようにDockerfileを作成します。

Dockerfile
FROM ubuntu:22.04

USER root

# 作業ディレクトリを設定
WORKDIR /opt/docker/project

# Mavenローカルリポジトリとなるディレクトリを作成
RUN mkdir -p /opt/docker/tools \
    && mkdir -p /opt/docker/project/.m2

# 必要なパッケージをインストール
RUN apt-get update && apt-get install -y \
    locales \
    subversion \
    unzip \
    curl zip unzip

# ユーザー「app01」を作成し、ディレクトリの所有者を「app01」に変更
RUN useradd -ms /bin/bash app01 && \
    chown -R app01:app01 /opt/docker

# app01ユーザーに切り替え
USER app01

# バージョン管理のためSDKMANをインストール
ARG JAVA17_VERSION=17.0.12-tem
ARG JAVA21_VERSION=21.0.4-tem
ARG MAVEN_VERSION=3.9.8

# SDKMANのインストール、sdkman-init.shの実行権限を付与
RUN curl -s "https://get.sdkman.io" | bash && \
    chmod +x $HOME/.sdkman/bin/sdkman-init.sh && \
    bash -c "source $HOME/.sdkman/bin/sdkman-init.sh && \
        sdk install java ${JAVA17_VERSION} && \
        sdk install java ${JAVA21_VERSION} && \
        sdk install maven ${MAVEN_VERSION}"

# ローカルリポジトリを設定したsettings.xmlをコピー
COPY ./development/settings.xml /opt/docker/project

5. docker-compose.ymlの作成

appサービスを定義したdocker-compose.ymlを作成します。

docker-compose.yml
version: '3.3'

services:
  app:
    build:
      # docker-compose.ymlの配置パスがカレント
      context: .
      dockerfile: ./development/Dockerfile
    environment:
      - TZ=Asia/Tokyo
    ports:
      - "8080:8080"
    stdin_open: true
    tty: true

6. settings.xml

コンテナ内のワークスペース毎にMavenローカルリポジトリを分けて使う想定とし、デフォルトでないディレクトリを設定したsettings.xmlを準備しておきます。
本記事ではMavenの使い方については割愛しますが、Mavenコマンド実行時にオプションでコピーしたsettings.xmlを指定する形で利用する想定です。

$ mvn install -s settings.xml
settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings>
    <localRepsitory>/opt/docker/project/.m2/localRepsitory</localRepsitory>
(省略)
</settings>

7. VSCodeからコンテナを開く

7.1. VSCodeでF1キー(Ctrl + Shift + P)を押下してコマンドパレットを開き、「Reopen in Container」を選択する。

ReOpen in Container.PNG

7.2. コンテナが起動すると、「devcontainer.json」で指定するワークディレクトリを開いた状態となる。

ReOpen in Container_直後.PNG

7.3. sdkコマンドでバージョンを確認する。(SDKMANが正しくインストールされたか確認)

SDKMANのコマンドでバージョン確認.PNG

7.4. Javaバージョンを変更してみる。(Java21に設定された状態)

Java17に変更する例
$ sdk use java 17.0.12-tem

実行ログ

app01@xxx:~$ sdk use java 17.0.12-tem
app01@xxx:~$ sdk current        

Using:

java: 17.0.12-tem
maven: 3.9.8

Using java version 17.0.12-tem in this shell.

おわりに

記事の途中でも少し触れましたが、続編としてJenkinsコンテナ環境を構築する記事も書きたいと思っています。
docker-compose.ymlで複数サービスを定義し、Dev Containerによるコンテナ起動ではなく、docker-composeコマンドを使用した内容となる予定です。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?