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

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

【Docker】Node.jsのコンテナを作成する

パンジェンシ氏「東の森でシステムエンジニアをしております、パンジェンシーと申します。 最近は、とにかく情報が多すぎて覚えていられないので、細かい内容もできるだけメモに残しておこうと思います。 」

Node.jsのインストール再び!

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

5年前くらいのエントリーで、「Node.jsをインストールしてみよう!」的なことをやりました。

その後状況がだいぶ変わっていると思いますので、やり方を調べてよさげなものをメモしておきます。

1. Node.jsをインストール?

現在の私の環境は、Windows 10 HomeにWSL2を使ってUbuntu 20.04 LTSを入れているような状態で、このUbuntuにNode.jsをインストールしてみたいと思います。

デーヴァ「Dockerを使えばいいのデヴァ?」

パンジェン氏「!?デーヴァさん!?」

デーヴァ「せっかくDockerを入れたんだから、Node.jsがインストールされたDockerイメージを使えばすぐなのデヴァ?」

パンジェン氏「た…たしかに…。そのためのDockerですよね…。(何でデーヴァさんがここに…?)」

2. Node.jsのDockerコンテナを作成

というわけで、Node.jsを直接ホストOSにインストールするのはやめて、Node.jsのDockerコンテナを作ってみましょう!

ディレクトリとファイルを作成

まずは、必要なディレクトリとファイルを作成します。

// どこか適当なディレクトリで以下のように
$ mkdir node-app-sample && cd node-app-sample
$ touch docker-compose.yml
$ mkdir src
$ touch src/server.js

// こんな感じの構成になります。
任意のディレクトリ
└── node-app-sample
    ├── docker-compose.yml
    └── src
        └── server.js

このserver.jsというファイルに、Node.js公式ページのサンプルを貼り付けます。

const http = require("http");

const hostname = "127.0.0.1";
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader("Content-Type", "text/plain");
  res.end("Hello World");
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

3行目のhostname127.0.0.1(ローカルホスト)となっていますが、この設定ではホストマシンからコンテナにアクセスできません。

調査の結果、0.0.0.0と設定しておけばアクセスできるようです。この'0.0.0.0'と設定すると「ホスト内の全てのIPアドレスで待受る」という意味になります。

const http = require("http");

- const hostname = "127.0.0.1";
+ const hostname = "0.0.0.0";
const port = 3000;

Docker Composeファイルは以下のようにしてみます。

version: "3"
services:
  app:
    image: node:lts # イメージを取得
    container_name: node # コンテナの名前を設定
    volumes: # ディレクトリをリンク
      - ./src:/app/src # [ホスト側]:[コンテナ内]
    ports: # 公開用ポート設定
      - 3001:3000 # [ホスト側]:[コンテナ内]
    command: node server.js # コンテナ起動時に実行するコマンド
    working_dir: /app/src # コマンドを実行するディレクトリ

コンテナの作成

では、コンテナをビルドしてみましょう。docker-compose.ymlの置いてあるディレクトリで以下を実行します。

$ docker-compose build

ビルドが終わったら、コンテナを起動してみましょう。

$ docker-compose up -d

コンテナの内部でserver.jsのプログラムが起動しているかログを確認してみましょう。

$ docker-compose logs

以下のようなログが表示されていればOKです。エラーが起きている場合はコードを見直しましょう。

Attaching to node
node   | Server running at http://0.0.0.0:3000/

ブラウザからhttp://localhost:3001にアクセスしてみましょう。

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

無事、「Hello World」が表示されたでしょうか?

「コンテナ内では3000ポートで起動していますが、docker-compose.ymlで公開用ポートを3001に設定したので、3001でアクセスしなければいけないことに注意しましょう。」

まとめ

今回はNode.jsのコンテナを作成してサンプルプログラムを実行してみました。

これを応用して、色々なフレームワークのコンテナを作成して動かしてみようと思います。

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

【Docker】MySQLのコンテナを作成する

パンジェン氏「東の森でシステムエンジニアをしております、パンジェンシーと申します。 最近ずっと家に籠もりっぱなしなので、お腹の脂肪が大変なことになっております。」

RDB環境を構築してみよう

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

学習用などに自由にイジれるデータベース環境が一つあると便利ですよね。Dockerを使えば、環境構築や廃棄が簡単にできそうなのでちょっと試してみました!

今回は、MySQLのコンテナを作成してみます。MySQL(まい・えすきゅーえる)は、オープンソースリレーショナルデータベース管理システムRDBMS)(Wikipediaより)の一つで、無料で使えて、世界中の多くのシステムで採用されているそうなので、これを使うことにします。

SQL(Structured Query Language)は、RDB(Relational Database)のデータを操作するための言語です。」

1. MySQLのコンテナを作成

Dockerを導入していない場合は、以下のエントリー⇩を参考に導入してみてください。

導入できたら、WSL2のターミナルに入りましょう。

今回は、Docker Composeというツールを使ってみましょう。このツールを使うと、イメージの作成方法やコンテナの設定などをファイルに残しておくことができます。今回はコンテナは1つですが、複数のコンテナを同時に管理する時にとても便利なのでぜひ使い方をマスターしておきましょう。

// 適当なディレクトリを作成
$ mkdir -p practice-mysql && cd practice-mysql

// 設定ファイルを作成
$ touch docker-compose.yml

mysqlというディレクトリにdocker-compose.ymlという設定ファイルを作成しました。今度は、エディターからこのファイルを開いて以下の内容を追加しましょう。

version: "3"
services:
  mysql: # サービス名
    image: mysql:latest # 基にするDockerイメージ
    container_name: db-mysql # 作成するDockerコンテナの名前
    volumes:
      - .:/home/pangency # 現在のパス'.'と、コンテナ内の'/home/pangency'をリンク
    environment:
      - MYSQL_ROOT_PASSWORD=root # rootパスワードを設定
// 上の設定は、下のコマンドとほぼ同様の意味になります。
$ docker run --name db-mysql \
    -e MYSQL_ROOT_PASSWORD=root \
    -v .:/home/pangency \
    -d mysql:latest

volumesというところに、.:/home/pangencyと記載していますが、これは、:の左側にホスト内のパス、右側にコンテナ内のパスを設定し、これらの場所をリンクする設定です。

今回の場合、.は現在のパスという意味なのでdocker-compose.ymlが置いてあるpractice-mysqlディレクトリ、右側がコンテナ内のパス/home/pangencyになり、これらをリンクするという設定になります。後で本当にリンクされているか確認してみましょう。

ファイルを保存したら、Dockerイメージを作成します。

// `docker-compose.yml`を保存したディレクトリで以下を実行します。
$ docker-compose build

// `skipping`などのメッセージが出た場合は、既に同じ内容のDockerイメージを持っているということなのでOKです。

イメージが作成できたか確認してみましょう。

// イメージの一覧を表示
$ docker-compose images
Container   Repository    Tag       Image Id       Size
---------------------------------------------------------
db-mysql    mysql        latest   6e447ce4863d   544.2 MB

// 上のような感じで作成できていればOKです!

次にコンテナを起動してみます。

// コンテナの起動
$ docker-compose up -d

// コンテナ一覧の表示
$ docker-compose ps
  Name               Command             State          Ports
--------------------------------------------------------------------
db-mysql   docker-entrypoint.sh mysqld   Up      3306/tcp, 33060/tcp

無事起動できました!

「Docker Composeで作成したコンテナを終了する場合は、docker-compose stop、コンテナを終了して削除する場合は、docker-compose downを実行しましょう。削除した場合は、データベースの内容も全て消えてしまうので注意してください!」

2. コンテナにログイン

コンテナにログインしてみましょう。

$ docker-compose exec mysql bash

コンテナ内でディレクトリを移動してみましょう。

# cd home/pangency
# ls

ここに、先程作成したdocker-compose.ymlがあるのではないかと思います。

volumes.:/home/pangencyと設定をしたことによって、ホスト側とコンテナ内のディレクトリをリンクできています。この機能を使えば、例えばホスト側で作成したsqlファイルを設置し、コンテナ内で実行することができます。

「コンテナ内からログアウトしてホストのターミナルに戻りたい場合は、exitコマンドを実行しましょう。」

3. データベースの作成

コンテナ内からデータベースを作成してみましょう。

コンテナ内でmysqlコマンドを実行してCUIツール「MySQLモニター」を起動します。

# mysql -u root -p
mysql>

以下のコマンドを売って、データベースpracticeを作成してみます。

mysql > create database practice;
mysql > show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| practice           |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

practiceという名前のデータベースが作成されました!

MySQLモニターを終了したい場合は、quitを実行しましょう。exitではないので注意です!」

4. テーブルの作成

無事、データベースが作成できたので、テーブルを作ってみましょう!ホスト側から以下のファイルを作成します。

// docker-compose.ymlのあるディレクトリにファイルを作成
$ touch create-table.sql

中身は何でもよいですが、今回は以下のような感じにします。エディターで編集しましょう。

-- テーブルが既にある場合は一旦削除
DROP TABLE IF EXISTS tasks;
-- テーブルの作成
CREATE TABLE tasks (
    id int primary key,
    title varchar(50),
    create_date datetime,
    create_person varchar(30)
);
-- データの挿入
INSERT INTO tasks (id, title, create_date, create_person) VALUES (1, 'read a book', sysdate(), 'pangency');
INSERT INTO tasks (id, title, create_date, create_person) VALUES (2, 'walk', sysdate(), 'pangency');
-- テーブルの表示
SELECT * FROM tasks;

コンテナにログインし、上記のsqlファイルを実行してみましょう。

// コンテナ内でディレクトリを移動
# cd home/pangency

// MySQLモニターの起動
# mysql -u root -p

// 使用するデータベースをpracticeに変更
mysql> use practice;

// sqlファイルの読み込み
mysql> source create-table.sql;
Query OK, 0 rows affected (0.05 sec)

Query OK, 0 rows affected (0.09 sec)

Query OK, 1 row affected (0.01 sec)

Query OK, 1 row affected (0.01 sec)

+----+-------------+---------------------+---------------+
| id | title       | create_date         | create_person |
+----+-------------+---------------------+---------------+
|  1 | read a book | 2020-07-20 04:44:34 | pangency      |
|  2 | walk        | 2020-07-20 04:44:34 | pangency      |
+----+-------------+---------------------+---------------+
2 rows in set (0.00 sec)

// テーブルの確認
mysql> show tables;
+--------------------+
| Tables_in_practice |
+--------------------+
| tasks              |
+--------------------+
1 row in set (0.00 sec)

無事、sqlファイルが読み込まれ、テーブルの作成とデータの挿入ができました!

「この環境なら、実行したいSQLファイルを作成してコマンドラインで即実行できるので色々試せますね!」

まとめ

今回は、Docker Composeを使って、MySQLのDockerコンテナの作成をしてみました。また、ホスト側とコンテナ内でのディレクトリのリンクも行ってみました。

Dockerがあれば、色々な環境を気軽に試せるのでとても便利ですね。

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

【WSL2】Windows 10 HomeでDocker Desktopを導入する

パンジェン氏「東の森でシステムエンジニアをしております、パンジェンシーと申します。 暑い日が続きますね。テレワークの方はちゃんとエアコンをつけて熱中症に気をつけましょうね!」

なぜ、Docker Desktopなのか

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

先日、WSL2のUbuntuにDockerをインストールしてみたのですが、WSL2ではsystemctlというコマンドが使えず、Dockerデーモンの自動起動設定を行うことができませんでした(使えるようにするスクリプトとか作っている人はいるみたいです)。

もう少し調べてみたら、Docker Desktop WSL2 backendというものを発見しました。Docker Desktop for Windowsは、Hyper-Vを使えないWindows 10 Homeでは動かないと思っていましたが、このWSL2 backendという機能を使えば動かせるようです。

これなら、Dockerデーモンの自動起動もできるし、WindowsからもWSL2からもDockerが使えるらしいので、こちらを使うことにしました。

「できるだけ開発絡みのものはWSL2の中に押し込めたかったのですが、自動起動のために複雑な手順が増えるより導入が容易なほうがよいと判断しました…。」

1. 導入済みのDockerを削除

pangency.hatenablog.com

既に過去のエントリーでWSL2内にDockerを導入していたので一旦削除します。やっていない人はこの手順は不要です。

せっかく導入しましたが、色んなバージョンのDockerが入っていると気持ち悪いのでとりあえずアンインストールします。手順は公式ドキュメントの通りです。

$ sudo apt-get purge docker-ce docker-ce-cli containerd.io
$ sudo rm -rf /var/lib/docker

2. WSL2を導入

逆に、WSL2の導入が済んでいない人は、以下のエントリー⇩を参考に導入してみてください。

pangency.hatenablog.com

3. Docker Desktopをインストール

https://hub.docker.com/editions/community/docker-ce-desktop-windows/

⇧からインストーラーをダウンロードしてインストールしましょう。「Get Stable」が安定版なのでとりあえずコチラにしましょう。

インストールが終わったら、Windows PowerShellからも、WSL2のターミナルからもdocker -vをしてみましょう。

まとめ

今回はDocker Desktopを導入してみました。Linux版からDocker Desktopに切り替えてよかったと思える日がいつかきっと多分来るでしょう…。

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