4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Docker開発環境構築 - React(TypeScript)

Posted at

概要

最近React(Typescript)で環境構築する機会があり、ReactをDocker化する上で工夫したところをまとめました。

環境

$ node -v
v18.16.1
$ npm -v
9.5.1
$ docker -v
Docker version 24.0.2, build cb74dfc

事前準備

  1. Dockerをダウンロードして起動までしておきます。
  2. Reactのアプリケーションを作成しておきます。

フォルダ構成

create-react-appでの自動生成物の中から不必要なフォルダやファイルを削除した構成になります。

$ tree -I "node_modules"
.
├── node_modules (空を用意する。理由は後ほど説明します。)
├── Dockerfile
├── README.md
├── docker-compose.yml
├── package-lock.json
├── package.json
├── public
│   ├── index.html
│   ├── manifest.json
│   └── robots.txt
├── src
│   ├── App.tsx
│   └── index.tsx
└── tsconfig.json

Docker関係のファイルの内容

Dockerfile
FROM node:18-alpine
WORKDIR /usr/src/app
COPY --chown=node:node package*.json ./
RUN npm install
USER node
docker-compose.yml
version: '3.8'
services:
  node:
    build:
      context: .
    restart: always
    tty: true
    environment:
      NODE_ENV: development
    ports:
      - '3000:3000'
    volumes:
      - .:/usr/src/app
      - node_modules:/usr/src/app/node_modules
volumes:
  node_modules:
    driver: local
    driver_opts:
      type: none
      device: ${PWD}/node_modules
      o: bind

.dockerignore
.git
node_modules

実行するコマンド

$ docker-compose up -d

イメージとコンテナ生成。
imageサイズは500.76MBでした。

$ docker-compose exec node sh

コンテナの中に入ります。

$ npm start

localhost:3000でアプリケーションの立ち上がりを確認します。
Reactのロゴをブラウザで確認できれば成功です。

工夫したところ

軽量なベースイメージを使用する

-alpineがついたimageはコンテナで利用することを想定して設計されたOSのため、標準版よりも軽量化されているalpine版を採用しました。

参考:軽量なベースイメージを使用する

rootではないUSERを使用する

rootを使用するとセキュリティの低下や予期しない動作をする可能性があるため、ユーザを変更します。
nodeイメージにはnodeという名前のユーザとグループがデフォルトで存在しているのでnodeを使用しました。コンテナ内で確認するとユーザー名の変更が確認できます。

/usr/src/app $ whoami
node

参考:Dockerfile リファレンスの USER コマンド

.dockerignoreを作成して余計なビルドをなくす

ビルドに余計な時間がかかってしまわないようにdockerで無視するファイルを指定しました。
指定する際は必要なファイルのみ指定します。

参考:.dockerignore アンチパターン

NODE_ENVにdevelopmentを指定する

今回は開発環境の構築のためdevelopmentを指定しました。

docker-compose.yml
environment:
      NODE_ENV: development

参考:NODE_ENVにdevelopmentとproduction以外を入れると辛い

ビルドプロセスをスムーズにする

Dockerイメージ内でアプリケーションをビルドする際に必要な依存関係を事前に準備することで、ビルドにかかる時間を短縮させました。

Dockerfile
COPY --chown=node:node package*.json ./

参考

Dockerfileベストプラクティス - Node.jsアプリケーション編
Dockerイメージ alpine,slim,stretch,buster,jessie等の違いと使い分け
docker run --restart=alwaysがどれくらいrestartしてくれるか調べた
COPY とバインドマウントの使い分け

感想

普段Dockerを使用する際はただコンテナの生成と削除を行っていただけだったのですが、自分で構築するとなるとさまざまなことを考慮しなければならず、思った以上にボリュームがありました。
やはり手を動かすことが大事ですね。。
お疲れ様でした。

おまけ:空のnode_modulesを作成した理由

下記のvolumesで.:/usr/src/appと記述し、バインドマウントを設定していますが、ホスト側にnode_modulesが存在しない状態でdocker compose up -dするとホスト側の情報がそのまま反映され、コンテナ内のnode_modulesがなくなってしまいます。

docker-compose.yml
version: '3.8'
services:
  gururi-node:
    build:
      context: .
    restart: always
    tty: true
    environment:
      NODE_ENV: development
    ports:
      - '3000:3000'
    volumes:
      - .:/usr/src/app
      # 以下追記
      - node_modules:/usr/src/app/node_modules
# 以下追記    
volumes:
  node_modules:

バインドマウントとボリュームを同時に設定した際にボリュームの方が優先されるため、node_modulesはホスト側の影響を受けることがなくなり、node_modulesは削除されなくなります。しかし、node_modulesはバインドマウントから除かれているため、ホスト側のnode_modulesが空になってしまいます。

ホスト側でyarn installすることで解決するのですが、そんなことをしたらせっかくDockerで開発環境を整えた意味がなくなります。そのため下記のような追記をすることでボリュームで管理されているnode_modulesの内容をホスト側にも表示できるようになります。

docker-compose.yml
volumes:
  node_modules:
    # 以下追記   
    driver: local
    driver_opts:
      type: none
      device: ${PWD}/node_modules
      o: bind

参考:
【Docker】コンテナ内のnode_modulesが消える問題を改善する
【Docker】ホスト側のnode_modulesが空になる問題を改善する

4
1
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
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?