[Windows] Dockerを使用してホスト環境を汚さずにAngularの開発環境を構築する

### TL;DR
- Node.jsの開発環境をDockerをまとめたかった
- ローカル環境にはDocker Desktopとvisual studio codeのみインストール
- Angularでng newから書いている記事がなかったので書いた。これをベースに開発環境を育てていってほしい

### 環境
- Windows10
- Docker Desktop 2.2.0.3
- docker-composeはDocker Desktopに同梱
- visual studio code 1.42.1[拡張機能Remote - Containers使用]

### 完成したリポジトリ
https://github.com/MegaBlackLabel/angular-docker-sample

### ファイル
```
\---node-angular-sample
│  .gitignore
│  docker-compose.yml
│  docker-entrypoint.sh
│  Dockerfile
```

```Dockerfile:Dockerfile
FROM node:lts

COPY docker-entrypoint.sh ./
COPY ./frontend ./

# fix https://github.com/docker/compose/issues/3270#issuecomment-363478501
USER root
RUN mkdir /frontend
RUN mkdir /frontend/node_modules
RUN chown node:node /frontend/node_modules
USER $USER_UID

RUN npm install -g @angular/cli

WORKDIR /frontend

EXPOSE 4200

ENTRYPOINT ["/docker-entrypoint.sh"]
```


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

services:
  node:
    build: .
    environment:
        NG_CLI_ANALYTICS: "ci"
    ports:
        - "4200:4200"
    volumes:
        - "./frontend:/frontend"
        - nodemodules:/frontend/node_modules
    tty: true

volumes:
    nodemodules:
        driver: "local"
```
- マウントしているfrontendについては初回起動時に作成する
- NG_CLI_ANALYTICS、NG_CLI_ANALYTICSはnpm ci実行時に途中で確認メッセージが出て止まらないようにするために設定

```shell:docker-entrypoint.sh
#start SQL Server, start the script to create/setup the DB
#!/bin/bash
 
FILE="/frontend/package.json"
if [ -e $FILE ]; then
  npm ci
fi

/bin/bash
```
- package.jsonがあるときはnpm ciを実行する
- /bin/bashを実行してコンテナが停止しないようにする

### マウントするフォルダの作成
```shell:docker-composeに記載しているホストのマウント先のフォルダを作成(無いとdocker-compose起動時にエラー発生)
mkdir frontend\node_modules
```

### docker-composeビルド
```shell:コンテナのビルドを実施
docker-compose build
```

### docker-compose起動
```shell:ビルドしたコンテナをバックグラウンドで起動
docker-compose up -d
```

### リモートコンテナ接続
- vs codeのコマンドパレットを開いて以下を入力
- Remote-containers: Reopen in Container

### Angularのプロジェクト作成
```shell:起動しているコンテナにアタッチしてコマンド実行
cd ..
ng new frontend --skipGit=true
```
※、これでfrontendフォルダにAngularプロジェクトが作成されます

## Angular起動
```shell:外部から見えるようにhostを設定します
# attach shell
ng serve --host=0.0.0.0
```

### docker-compose終了
```shell:コンテナを初期化して終了
docker-compose down -v
```

### Angularプロジェクト作成後のフォルダ構成(.git内は省略)
```
\---node-angular-sample
│  .gitignore
│  docker-compose.yml
│  docker-entrypoint.sh
│  Dockerfile
│
└─frontend
    │  .editorconfig
    │  .gitignore
    │  angular.json
    │  browserslist
    │  karma.conf.js
    │  package-lock.json
    │  package.json
    │  README.md
    │  tsconfig.app.json
    │  tsconfig.json
    │  tsconfig.spec.json
    │  tslint.json
    │
    ├─e2e
    │  │  protractor.conf.js
    │  │  tsconfig.json
    │  │  
    │  └─src
    │          app.e2e-spec.ts
    │          app.po.ts
    │
    ├─node_modules
    └─src
        │  favicon.ico
        │  index.html
        │  main.ts
        │  polyfills.ts
        │  styles.scss
        │  test.ts
        │
        ├─app
        │      app.component.html
        │      app.component.scss
        │      app.component.spec.ts
        │      app.component.ts
        │      app.module.ts
        │
        ├─assets
        │      .gitkeep
        │
        └─environments
                environment.prod.ts
                environment.ts
```

### git cloneして使う場合
```shell:初回時にマウント先のフォルダを作成
mkdir frontend\node_modules
docker-compose build
```

### まとめ
この構成だとホストにNode.jsをインストールしないで初めからDockerの開発環境で進められる。
ただし、作成済みのプロジェクトをgit cloneして使う際にはnode_modulesを作成する必要があるので注意。

以上