LoginSignup
16
13

More than 5 years have passed since last update.

dockerとdocker-composeを使ってnode.jsのHello Worldを動かす

Posted at

はじめに

Hello Worldを表示するnode.js(ただのJavascriptですが)のプログラムを作成し、それをdocker + docker-composeで立ち上げるまでの手順を説明します。諸々考え方が間違っているところも多いかと思いますがご容赦ください。
以下のような方を対象としています。

  • 今さらdockerとかdocker-composeなんて人に聞けねーよ、という方
  • 今さらnode.jsなんて人に聞けねーよ、という方

一式githubに上げました。

話の流れ

  1. dockerの概要説明
  2. docker-composeの概要、サンプル説明
  3. node.jsのhello-world説明
  4. コンテナとして起動する部分の説明

環境

  • 開発環境はWindows10
  • Hyper-VでDebian9を立ち上げ、dockerホストとして使用(こちら参照)
  • IDEはVisualStudioCodeを使用

フォルダ構成

node-docker-helloworld
│  docker-compose.yml
└─src
        index.js
        package.json

docker

dockerとは仮想環境の一種で、アプリケーションをコンテナ化して起動できます。
アプリケーションを直接サーバーにインストールする場合と比較して以下のような利点があります。

  • バージョン違いや、他のアプリケーションと競合しない
  • 別のサーバーに配置するときなど、毎回アプリケーションのインストールを行う必要がない

例えばPHPのWebアプリをApacheを使って動かすときなど、

  • Apacheがうまくインストールできない
  • 既にApacheで別のWebアプリが動いてるから別エイリアスにしたいけど設定がわからん
  • 他バージョンのPHPが入ってて困る

みたいなことに毎回悩まされませんか?dockerは1つ1つのアプリがコンテナとして独立しているので、上記のような心配事が緩和されます!
ぶっちゃけ、とりあえず最初は「超軽い仮想マシン」くらいの認識でも大丈夫です。

用語について

コンテナ

dockerを使って起動した仮想環境を指します。

イメージ

コンテナの元となるものです。
コンテナがクッキーならイメージが金型みたいな感じ?どこかで聞いたような…
dockerhubから持って来たり、後述するDockerfileを元に作成したりします。今回は前者を使います。

なお、Dockerfileを使う場合でも元となるイメージをdockerhubから取得する必要があります。つまり、コンテナを初回起動するタイミング(イメージを初回作成するタイミング)では、ホストがインターネットに接続されている必要があります。

Dockerfile

簡単に言うと「イメージを作成するための手順書」みたいなもんです。
元となるイメージと、そこからapt-getでなんか入れたりファイルコピーしたりコマンド実行したりして新しいイメージを作成するための手順が記載されています。例えば、公式のphpイメージにもろもろ追加モジュールを入れたPHPイメージを作成するためのDockerfileは以下のようになります。

FROM php:apache
COPY php.ini /usr/local/etc/php/
RUN apt-get update \
  && apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev libmcrypt-dev \
  && docker-php-ext-install pdo_mysql mysqli mbstring gd iconv \
  && pecl install mcrypt-1.0.1 \
  && docker-php-ext-enable mcrypt
  1. 1行目で元となるイメージを決めています。ここに書いたものを、初回起動時にdockerhubから引っ張ってきます。今回の例だとここ
  2. 2行目では、COPYコマンドでphp.iniをコピーしています。php.iniをDockerfileと同じ場所に置いておいて、それをイメージ内の/usr/local/etc/php/にコピーする、という意味です。
  3. 3行目で諸々のモジュールを入れてます。RUNコマンドで、Linuxコマンドを実行することができます。

いうて今回やりたいことは公式イメージで十分そうなので、Dockerfileは使いません :P

docker-compose

複数のdockerコンテナをまとめて起動したり停止したり、起動時の設定とかを記載できる仕組みです。

docker-compose.yml

docker-composeの設定を記載するファイルです。今回の例を使い手っ取り早く説明します。

docker-compose.yml
version: '2'
services:
  node:
    image: library/node
    container_name: node-helloworld
    volumes:
      - ./src:/src
    working_dir: "/src"
    command: "node index.js"
  1. 1行目はおまじないです。
  2. 2行目にservicesという記載があります。ここに複数のサービス(コンテナ起動設定)を記載することが出来ます。
  3. 3行目のnodeが実際に起動させるコンテナの設定です。
  4. 4行目でコンテナの金型となるイメージを決めています。今回はdockerhubから持ってきていますが、Dockerfileを基にする場合はimageではなくbuildとなります。
  5. 5行目でコンテナの名前を指定してます。省略可。
  6. 6~7行目のvolumesで、ホストのフォルダとコンテナのフォルダをマッピングしています。この例で行くと、「ホストの./srcってフォルダが、あたかもコンテナ内の/srcにあるように見せかけてコンテナ起動するよ」という意味です。
  7. 8行目で作業フォルダを指定しています。
  8. 9行目で「コンテナ起動時に実行するコマンド」を指定しています。

そいじゃ、次はsrcフォルダの中に置くhelloworldについて説明します。

node.js

インストール

とにかくインストールが必要です。node.jsの公式ページからインストーラーを落とすか、nodist等のバージョン管理ツールでインストールしましょう。インストール確認をお忘れなく。

> node -v
v8.4.0

OKそうなら次に進みます。

最近はもはや、インストールしたプログラムの実態がどこにあるかとか気にしないのが普通なようですね。慣れるまで非常に気持ち悪かったですが、慣れると「俺の端末のどこかにnodeとかいうプログラムがインストールされて、パスが通ってるっぽい」以上のことは何も考えなくなりました。

フォルダの初期化

node.jsは、フォルダ自体がプロジェクトになるんですよねー。普通にコマンドプロンプトを開いてフォルダに行き、npm initコマンドを叩きます。

> cd src
src> npm init

npmはnodeと一緒にインストールされる、nodeのパッケージ管理ツールです。initコマンドを叩くと、nodeのプロジェクト設定ファイルとも言えるpackage.jsonが作成されます。
対話側でいろいろ聞かれますが適当に入れちゃってください。Enter連打でも多分いけます。私の場合は以下のようなファイルが出来ました。

package.json
{
  "name": "node-helloworld",
  "version": "1.0.0",
  "description": "node.jsのプログラムをdocker-composeで起動する用のサンプル",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

index.jsの作成

ではプログラムの実態となるindex.jsを作成します。

index.js
console.log("hello.world");

だってhello-worldだもん…
ちなみに、vscodeで開いてF5押せばデバッグが可能です。nodeが入ってるからかしら?単純なjavascriptのテストをしたいだけなら、これだけで十分そうですね。
image.png

サーバーに配置

これで一通りのファイルが出来たので、仕上げです。dockerのホストにファイルをコピーし、コンテナを起動してみましょう。

ホストへのインストール

docker

こちらにも記載しましたが改めて。公式のコピペです。

$ sudo apt-get update
$ sudo apt-get install \
     apt-transport-https \
     ca-certificates \
     curl \
     gnupg2 \
     software-properties-common
$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/debian \
   $(lsb_release -cs) \
   stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce

docker-compose

こちらも公式のコピペです。

$ sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

コンテナの実行

ファイルの配置

WinSCPを使い、/home/amama/docker-compose/node-docker-helloworldにファイルを配置。
image.png

実行

ターミナルで接続し、docker-compose upコマンドを実行しコンテナを起動します。
最初はイメージの作成から始まり、それが終わるとコンテナが起動し、HelloWorldを出力して終了します。

amama@debian:~/docker-compose/node-docker-helloworld$ sudo docker-compose up -d
Creating network "node-docker-helloworld_default" with the default driver
Pulling node (library/node:)...
latest: Pulling from library/node
1c7fe136a31e: Pull complete
...
Creating node-helloworld ... done
Attaching to node-helloworld
node-helloworld | hello.world
node-helloworld exited with code 0

出来ました。

最後に

ミニマムコードで試したつもりですがずいぶんと長くなってしまいました。
次回は、まずはnode.jsでやりたいことがあるのでそちらを詰めます。dockerやdocker-composeの掘り下げはまた別の機会に。

16
13
0

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
16
13