👌

WSL2 + VSCode + DockerでのJava17開発環境構築(Desktopなし)

2021/11/30に公開

はじめに

Docker Desktopが有料化を発表し、2022年1月末までに購入しないとライセンス違反になるとのことで、Docker Desktopが不要なJavaの開発環境の構築手順をまとめてみました。

また、WSL上のVS CodeでJavaの開発環境を構築し、Docker Imanengeを作成・実行するところまで行います。Java17は、再度、本番環境を含み無償で提供されるようになり、今後注目されると思っています。

WSL2

WSL2(Windows Subsystem for Linux 2)は、2020年3月にWindows 10 20H1と同時に正式公開されました。そこで、WSL2の特徴をまとめておきます。

  • コンソールを開くだけで、Linuxが起動する。Windows 10 Homeでも利用可能。
  • WSL2からDockerが動かせるようになった。
  • ファイルシステムがNTFS → EXT4になり、書き込み速度が向上。逆にNTFS(C:)への書き込みは遅い。
  • 使用メモリは、メモリ全体の50%または8G、いづれか少ない方。.wslconfigで設定可能。

インストール手順

基本的には、PowerShellから以下のコマンドだけで導入が完了します。デフォルトではUbuntuがインストールされます。

> wsl --install -d Ubuntu
→利用するユーザ名、パスワードを入力する。
$ uname -a
Linux <PCName> 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04 LTS
Release:        20.04
Codename:       focal

基本操作

  • 作業フォルダ
    NTFS(/mnt/c/)は書き込みが遅いので、cdでhomeに切り替えて作業する。
  • WSL停止・起動(メモリを解放したいとき)
    停止: > wsl --shutdown
    起動: shellを開くと自動起動
  • ファイル編集
    VSCodeが便利です。拡張機能「Remote WSL」を入れてください。リモートサーバは、「Remote SSH」で編集できます。
    $ code <ファイル名>
  • WSLからWindows(C:)を参照
    $ cd /mnt/c/
  • Windows(エクスプローラ)からWSLを参照、コピー
    \\wsl$\Ubuntu
    → テキストファイルをコピーするとき、改行コードは必ずLFにすること。
    → コピー後は、rootユーザになるので、chown <ユーザID>:<ユーザID> <ファイル名>で変換するとよい。
  • WSLのIPアドレス、DockerのIPアドレスも後ろに表示される。
    $ hostname -I
  • イメージ初期化(再セットアップしたいとき)
    スタートメニューの[設定]→[アプリ]で、ubuntuを検索。その後、詳細オプションで[リセット]ボタンを押すと、初期化される。その後、数分後にUbuntuから起動できるようになる。

Windows Terminal

2020/5に正式リリースされました。Power ShellやUbuntuがタブで切り替えれるようになり、TeraTermのような操作ができるので、使ってない方はぜひ導入してみてください。デスクトップから右クリックでも起動できるようになります。

あとは、おすすめの設定変更です。

  • フォント変更 ... プロファイル - 規定値 - 外観 - フォントフェイス
    日本語が文字幅が狭いため。おすすめは白源(HackGen Console)です。フォントの見分けにこだわりがあります。Oや0など。
  • Ubuntuの開始ディレクトリ ... Ubuntu - 全般 - 開始ディレクトリ
    \\wsl$\Ubuntu\home<ユーザID>

Docker

Dockerは、説明が長くなるので、公式サイトを参考にしてください。今回は、Docker Imageを作成して、ローカルでコンテナ起動するまでの手順を記載します。
そこから、Docker HubやAzure Container Registryに登録し、k8zや、Azure App Serviceなどにデプロイする手順は、また別の記事で紹介する予定です。

Dockerインストール

Docker Desktopでは、WSL上にDockerをインストールしてくれますが、ここではDockerの公式サイトからDocker EngineDocker Composeをインストールします。

  1. sudoで毎回パスワードが聞かれないようにする。
$ sudo visudo
→ 以下の行を、最終行に追加する。
<ユーザID>    ALL=NOPASSWD:   ALL
  1. VSCodeで以下のファイルを用意し、Docker engine, Docker composeをインストールする。また、dockerを自動起動できるように.bashrcにコマンドを追加している。
dockerInstall.sh
#!/bin/sh
# Set up the repository
sudo apt-get update
sudo apt-get -y install \
  ca-certificates \
  curl \
  gnupg \
  lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install docker engine
sudo apt-get update
sudo apt-get -y install docker-ce docker-ce-cli containerd.io
sudo service docker start
# Install docker compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# Add docker group
sudo gpasswd -a $USER docker
sudo chmod 666 /var/run/docker.sock
# Add service docker start to ~/.bashrc
echo "" >> ~/.bashrc
echo "if [ \$(service docker status | awk '{print \$4}') = \"not\" ]; then" >> ~/.bashrc
echo "  sudo service docker start > /dev/null" >> ~/.bashrc
echo "fi" >> ~/.bashrc
$ chmod 755 dockerInstall.sh
$ ./dockerInstall.sh
  1. Dockerが操作できるか確認する。
$ docker --version
Docker version 20.10.11, build dea9396
$ docker-compose --version
docker-compose version 1.29.2, build 5becea4c
$ docker images

Dockerコマンド一覧

よく利用するDockerコマンドを紹介します。

用途 コマンド
起動中のコンテナ一覧
※コンテナ名=NAMES
docker-compose ps
docker ps
コンテナ内のコマンド実行 docker exec -ti <コンテナ名> <コマンド(bashなど)>
コンテナ開始 docker-compose up -d
docker start <コンテナ名>
コンテナ停止 docker-compose down
docker stop <コンテナ名>
コンテナのログ表示 docker-compose log -f
docker logs -f <コンテナ名>
停止を含むコンテナ一覧 docker ps -a
Dockerイメージ一覧 docker image ls
noneになったDockerイメージを一括削除 docker rmi $(docker images -f "dangling=true" -q)

WSL2 + VSCode + Java17での開発

Javaの開発といえば、EclipseやIntelliJが一般的ですが、今回はVS Codeでの開発を紹介します。Linux上で開発できて、起動もビルドが早いです。操作性も、今ではEclipseと同じぐらい?だと思います。今回は、Java17で開発環境を構築しましたが、どのバージョンでも手順は同じです。

VSCodeセットアップ

まずは、WSL上でJavaの開発するための拡張機能をインストールします。VS CodeとRemote WSLはインストールされている前提です。

  • Extension Pack for Java ... Lint, フォーマッタ、デバッカー、JUnitなどのパッケージ一式
    → Java8を利用する場合は、Language Support for Java(TM) by Red Hatを0.64.1へバージョンダウンが必要になる。
  • Spring Boot Extension Pack ... Spring Initializr, Spring bootに必要なパッケージ一式
  • Docker ... Dockerのビルド、起動、ログ表示など、VS CodeでDockerが操作ができる。

VSCodeでの便利機能

VSCodeでJava開発する際の便利機能について、まとめておきます。詳しくは、VS Codeの公式サイトを参考にしてください。

  • Class, Package追加
    エクスプローラーで右クリック、新しいファイル、新しいフォルダを選択
  • 検索機能 ... Ctrl-P(コマンドパレット)
    <ファイル名> ... ファイル名
    #<パス> ... URLパス
    @<クラス名> ... クラス名
  • コマンドライン切り替え ... Ctrl-#
  • WSLからの起動 ... $ code .
  • 自動フォーマッタ ... 保存、ペースト、改行時に自動整形する。コマンドパレットで、settings.jsonを検索し、以下の内容を追加する。
settings.json
...
  "java.format.settings.url": "eclipse-java-google-style.xml",
  "java.format.settings.profile": "GoogleStyle",
  "[java]": {
    "editor.formatOnSave": true,
    "editor.formatOnPaste": true,
    "editor.formatOnType": true
  },

xmlファイルは、以下の手順で取得する。既存のEclipseフォーマッタも取り込み可能。

$ cd .vscode
$ wget https://raw.githubusercontent.com/google/styleguide/gh-pages/eclipse-java-google-style.xml

Hello World

ここからは、JavaでHello Worldを表示するまでの手順を説明します。

  1. Java17のJDKをインストールし、vscodeを起動する。
$ sudo apt-get install openjdk-17-jdk
→ apt-cache search <パッケージ名>で他のバージョンも検索できる。
$ code .
  1. [F1]を押して、「Spring Initializr: Create a Gradle Project」でプロジェクトを作成する。以下の項目以外は、デフォルトのままにします。
    ・Java version ... 17
    ・Artifact Id ... hello-world
    ・dependencies ... Spring Web, Spring Boot DevTools(hot reload)
    ・出力フォルダ ... /work/<ユーザID>
    → 指定したフォルダの下に、hello-worldが作成されます。
  1. 右下にSuccessfully generated.と表示されるので、Openを押すと、プロジェクトが表示される。
  2. HelloContollerクラスを作成する。
contoller/HelloController.java
package com.example.helloworld.contoller;

import java.util.Date;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @GetMapping("/")
    public String hellowworld() {
        return "Hello world. " + new Date();
    }
}
  1. SPRING BOOT DASHBOARDのhello-worldからデバック実行を行い、ブレークポイントでデバックできるか、URLを変更して即時反映されるかなど、確認してみる。
    http://localhost:8080/

Dockerイメージ作成

今回作成したHello WorldのDockerイメージを作成し、Dockerコンテナでサービス実行してみます。

  1. Dockerfileを作成する。jdkは軽量サイズのalpineを利用しています。
Dockerfile
FROM openjdk:17-alpine
RUN addgroup -S spring && adduser -S spring -G spring
ENV TZ=Asia/Tokyo
USER spring:spring
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} /app/app.jar
ENTRYPOINT java -jar /app/app.jar
  1. docker composeの動作確認用に、docker-compose.ymlを作成する。
docker-compose.yml
version: '3.6'
services:
  app:
    image: hello-world:0.0.1-SNAPSHOT
    ports:
      - 8080:80
  1. gradleでdocker imageをビルドできるように修正する。
build.gradle
plugins {
    ...
    id "com.palantir.docker" version "0.31.0"
}
...
docker {
    name "${project.name}:${project.version}"
    files bootJar
    buildArgs(['JAR_FILE': "${project.name}-${project.version}.jar"])
}
  1. Dockerイメージおよびコンテナを作成し、サービスを起動する。
$ ./gradlew docker
→ ビルド、Dockerイメージ作成
$ docker images
REPOSITORY        TAG              IMAGE ID       CREATED        SIZE
hello-world       0.0.1-SHAPSHOT   a0ab067ed0e3   2 hours ago    343MB
openjdk           17-alpine        264c9bdce361   5 months ago   326MB
$ docker-compose up -d
→ Dockerコンテナ作成、サービス起動
  1. 以下のURLに接続し、画面が表示されることを確認する。
    http://localhost/

  2. VSCode上のDocker画面でもDockerコンテナやイメージの操作ができるので、確認してみる。特に、DockerコンテナのViews Log、Attach Shellは、エラー状況を確認する際に便利。

おわりに

WSL2 + Dockerで開発環境を構築することで、ローカルのWindows環境を汚すことなく、様々な言語、バージョン、データベースがすぐに利用できるようになります。まだ、WSLを利用していない方は、この記事で導入するきっかけになればと幸いです。

Discussion