パンジェンシーの「汗だく開発日誌」

システム開発の備忘録です。

【WSL2】Dockerを導入する

パンジェンシー「東の森でシステムエンジニアをしております、パンジェンシーと申します。 最近のシステム開発関係は、開発を効率化するツールやフレームワークが溢れていますね。 エンジニアも、『〇〇言語使える?』じゃなく、『◇◇ってツール使ったことある?』のほうがよく聞かれる気がします。 」

Dockerってなに?

f:id:x-fieldatts:20200731111231p:plain

コンテナとは、「仮想化」という技術の一種です。仮想化といえば、VirtualBoxなどのツールを使ってホストOS上にゲストOSを構築する「仮想マシンVM)」という技術ですよね。対して、コンテナは1個のアプリを動かす環境(ライブラリー、ディレクトリー構成、ネットワークなど)を構築する技術で、OSの機能はホストOSのものをそのまま使います。

コンテナを使う場合、VMに比べてサイズが小さくできるため導入や起動が速く・軽いです。動かなくなった時に環境をリセットしたい場合のストレスも少なくなる気がします。また、作成したコンテナのイメージをチームで共有することも簡単にできます。

このコンテナの技術を実現するツールが「Docker」です!なんか、使ってみたくなりましたよね?前置きが長くなりましたが、導入してみましょう!

「私の理解では、ホストOSを土地に例えると、仮想マシン=マンション(風呂、トイレ、キッチンなどは部屋ごと)、コンテナ=寮(風呂、トイレ、キッチンなどは共用)というイメージでしょうか…?」

1. Dockerの導入

前回のエントリー⇧で構築したWSL2の環境にDockerを導入してみようと思います!

Install Docker Engine on Ubuntu | Docker Documentation

⇧の公式ドキュメントを参考に、Dockerのリポジトリからaptを使ってインストールします。

OSは、Ubuntu 20.04 LTS、アーキテクチャx86_64です。

リポジトリの追加

WSLののターミナルを開き、以下のコードを打ち込んでいきます。

// パッケージ一覧の更新
$ sudo apt-get update

// HTTPS経由でリポジトリを使うためのパッケージのインストール
$ sudo apt-get install apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

// Dockerの公式GPGキーを追加
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

// キーを検索
$ sudo apt-key fingerprint 0EBFCD88

// 以下のように表示されていればOK(?)
pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [  不明  ] Docker Release (CE deb) <docker@docker.com>
sub   rsa4096 2017-02-22 [S]

// 安定版のAMD64アーキテクチャ用のリポジトリを追加
$ sudo add-apt-repository \
    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
    $(lsb_release -cs) \
    stable"

インストール

リポジトリを追加したので、一覧を更新してインストールしましょう。

$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

「ここで、GRUBのインストールをする画面が出てきましたが、特に何も選択せずにOKを押しても問題ありませんでした。」

動作確認

インストールが完了したら、動作確認してみましょう。

// Dockerデーモンを起動
$ sudo service docker start

// `hello-world`イメージをリポジトリからダウンロードし、コンテナを起動
$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:d58e752213a51785838f9eed2b7a498ffa1cb3aa7f946dda11af39286c3db9a9
Status: Downloaded newer image for hello-world:latest

…

⇧のようなメッセージが表示されればOKです!

「ちなみに、システムの裏で常駐してるプログラムを、Linuxでは『デーモン』、Windowsでは『サービス』と呼びます。~~~dみたいな名のプログラムはだいたいデーモンです。」

// コンテナの状態を確認
$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
78a2e818219e        hello-world         "/hello"            2 seconds ago       Exited (0) 2 seconds ago                       angry_curran

⇧2秒前にコンテナが作られて、2秒前に終了したようですね。hello-worldコンテナは、メッセージを出力して終了するだけのコンテナらしいので、これで動作的にはあっています。

// ダウンロード済みのイメージ一覧を確認
$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        6 months ago        13.3kB

hello-worldのイメージがあります。

「Dockerイメージは『設計図』、Dockerコンテナは設計図を基に作った実際の『もの』と考えるとイメージしやすいと思います。」

追加の設定

ここまでの設定だと、sudoしないとdockerコマンドが使えません。sudoなしでも使えるように、ユーザーにdockerグループを追加しておきましょう。

$ sudo usermod -aG docker $USER

// 一度ターミナルを終了して、再度立ち上げ、sudoなしでもコンテナが起動できるか確認
$ docker run hello-world

「WSL起動時にDockerデーモンを自動起動するように設定できればよかったのですが、その時に使うsystemctlというコマンドがWSL2では使えない状態のようです。systemctlを使えるようにする方法はあるようですが今回はやめておきます。 」

nginxを動かしてみる

hello-worldだけだと動かした気がしないので、WEBサーバーを動かしてみましょう。

// NginxのDockerイメージをダウンロード
$ docker pull nginx
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              0901fa9da894        3 days ago          132MB

docker pullは、コンテナの起動はせずにイメージのダウンロードだけ行います。」

// Nginxのコンテナを起動
$ docker run -d --name web-server -p 8080:80 nginx
// -d:バックグラウンドで実行させるオプション
// --name:コンテナに名前をつける
// -p:ポートフォワード設定([ホストOS側のポート]:[コンテナ側のポート])

localhost:8080にアクセスしてみましょう。ブラウザはWindowsでも、WSLでもOKです。

f:id:x-fieldatts:20200714191302p:plain

⇧こんな感じの表示が出ればOKです!

後は⇩のコマンドなどを一通り触って雰囲気を掴んでおくと、応用編の場合でもイメージしやすいと思います。

// コンテナの終了
$ docker stop web-server

// コンテナの開始
$ docker start web-server

// コンテナの削除
$ docker rm web-server

// イメージの削除
$ docker rmi nginx

まとめ

今回は、Dockerとは何か?というところから始まり、WSL2環境への導入に挑戦しました。

まだまだ基本中の基本しかできていませんが、少しずつ覚えていけば、いずれは使いこなせることでしょう(多分)。

「今回の報告は以上です!ではまた!」