Proxy環境下でNode.jsアプリのイメージを作るDockerFileを書いた

node.jsのアプリケーションをプロキシ環境下で自前のDockerFileでbuildするのがちょいと面倒だった。

[DevHub](https://github.com/volpe28v/DevHub)というアプリケーションを使うためのDockerFileについての記事だが、他の同様なnode.js系、MongoDBクライアントを使う系アプリケーションについても通ずるものがありそうなのでここに示す。

# DevHubとは

https://github.com/volpe28v/DevHub

プログラマの為の開発支援コミュニケーションツール。数十人の開発チームにちょうどいい、便利なMDメモ＋チャットツール。

node.jsとMongoDBのクライアントを必要とする。別にMongoDBサーバが立っている必要がある。

既にいくつかDockerHubにリポジトリがあるが、機能を省いていたりDBとの接続方法に不満があったりだったので自前することにした。

# なんで面倒か

* docker-composeで与える環境変数`environment`は、image上で使われるものであって、ビルド時には使えない。引数`--build-arg`として与えるべき。
* npm, apt-key は環境変数`http_proxy`,`https_proxy`ではプロキシ経由してくれない。引数に与えなくては。

# DockerFile

```DockerFile:DockerFile
FROM node:latest

# NEED: --build-arg でhttp_proxy、https_proxyを指定
# proxy
ENV http_proxy $http_proxy
ENV https_proxy $https_proxy
RUN npm -g config set proxy $http_proxy
RUN npm -g config set https-proxy $https_proxy
RUN npm -g config set registry "http://registry.npmjs.org/"

# timezone
RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

WORKDIR /
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --keyserver-option http-proxy=$http_proxy --recv 9DA31620334BD75D9DCB49F368818C72E52529D4
RUN echo "deb http://repo.mongodb.org/apt/debian stretch/mongodb-org/4.0 main" | tee /etc/apt/sources.list.d/mongodb-org-4.0.list
RUN apt update
# install mongo cliant only
RUN apt install -y mongodb-org-shell
RUN git clone https://github.com/volpe28v/DevHub.git

WORKDIR /DevHub

# delete bots
RUN rm -f lib/bots/* 

RUN npm config set strict-ssl false
RUN npm install --unsafe-perm
RUN npm config set strict-ssl true

RUN echo -n "#!/bin/bash \n node app.js" > ./entrypoint.sh
RUN chmod +x ./entrypoint.sh

ENTRYPOINT ["/DevHub/entrypoint.sh"]
```

## FROM
[node](https://hub.docker.com/_/node):latest を使う。node.jsが入ったDebianのイメージ。

## プロキシ設定
nodeはFROMするとして、DockerFile内で（つまりDevHubをクローンしてセットアップするのに）必要なプロキシ設定は以下の2つ

* npm
* apt-key（Mongoのクライアントインストールに必要）

単純に環境変数に与えるだけでは問題があったので、DockerFileに引数として与え、buildにもろもろ引数として使う形式にした。

## その他の設定

* タイムゾーン：東京固定
* bots：邪魔だったので消してしまう


# 使い方
上記のDockerFileでコンテナを作る。

## 前準備
MongoDBは予め立てておく。
DevHubは環境変数`MONGODB_URI`を通して接続するので控えておく。

MongoDB URI フォーマット : `mongodb://ID:PASS@SERVER_IP:PORT/DB_NAME`
※AUTHを設定をしていなければ`ID:PASS@`は不要

## docker-compose.yml

```yml:docker-compose.yml
version: '3'

services:
  devhub:
    # ======== build ========
    build:
      context: ./
      dockerfile: Dockerfile
      args:
        - http_proxy=http://PROXY_IP:PORT/
        - https_proxy=http://PROXY_IP:PORT/

    # ======== run ========
    container_name: devhub
    restart: always
    ports:
      - '3000:3000'
    volumes:
      # アップロードされたファイルを保存するディレクトリ
      - \path\to\uploads:/DevHub/static/uploads
      # メニューバーに置かれるリンクを記述したjsonファイル
      - \path\to\menu_links.json:/DevHub/lib/menu_links.json
    environment:
      # MongoDB URI 
      - MONGODB_URI=mongodb://ID:PASS@SERVER_IP:PORT/DB_NAME
      
    # オプション `-t` は、メニューバーの ”DevHub for XXX” に入るタイトル
    entrypoint: "node /DevHub/app.js -t TITLE"
```

※`\path\to\uploads`、`\path\to\menu_links.json`は予め作っておく

## build
`--build-arg`に以下の2つを与える

* http_proxy=http://PROXY_IP:PORT/
* https_proxy=http://PROXY_IP:PORT/

## run

* 環境変数に`MONGODB_URI`を与える
* ポート3000をバインド
* アップロードされたファイルをvolumes（`/DevHub/static/uploads`）
* メニューバーに置かれるLINKリストはホスト側で編集できるようにvolumes（`/DevHub/lib/menu_links.json`）
* 実行コマンド`node app.js`に与えるオプション`-t`でDevHubのタイトルを設定

# Docker Hub から
このイメージはDocker Hubにプッシュしました。
MongoDBサーバさえあれば簡単に使えるので試してみてください。

https://hub.docker.com/r/koyayashi/devhub

```yml:docker-compose.yml
version: '3'
services:
  devhub:
    # ======== run ========
    image: koyayashi/devhub
    container_name: devhub
    restart: always
    ports:
      - '3000:3000'
    volumes:
      # アップロードされたファイルを保存するディレクトリ
      - \path\to\uploads:/DevHub/static/uploads
      # メニューバーに置かれるリンクを記述したjsonファイル
      - \path\to\menu_links.json:/DevHub/lib/menu_links.json
    environment:
      # MongoDB URI 
      - MONGODB_URI=mongodb://ID:PASS@SERVER_IP:PORT/DB_NAME
      
    # オプション `-t` は、メニューバーの ”DevHub for XXX” に入るタイトル
    entrypoint: "node /DevHub/app.js -t TITLE"
```