初めに
Docker Composeを使用して、Node.jsとMySQLのコンテナを作成し、Sequelzieを使用してDBにアクセスするところまでを記載する。
また、Node.jsのコンテナ上でExpressのプロジェクトを1から作成する記事は多く見かけたが、既にあるGitHubのリポジトリ(ExpressとSequelizeを含む)をcloneしてそこから環境を構築していく記事はあまり見受けられなかったので、今回はそちらの手順で行う。(実際に現場で開発する際は、既にGitHubが作成されている場合もあると思われるため)
今回やりたいことの図
環境
■ 使用PC
MacOS Big Sur:バージョン11.6
※既に使用PCにはgitを導入状態。
Node.js、MySQLは入っていない。
Docker Composeとは
Docker Composeとは、複数(単数でも可)のコンテナを定義して実行するツールである。
定義ファイルはYAML形式
で記載する。
また、Dockerのデスクトップアプリをインストールして入れば一緒にDocker Composeもインストールされている。
Dockerfile、Kubernetesとの違い
Dockerfile・・・イメージを作る。
Docker Compose・・・コンテナ、ネットワーク、ボリュームを作る。
Kubernetes・・・コンテナを管理する。
使い方
ファイルの名前は以下で固定であり、1つのディレクトリにつき1つまで配置可能。
docker-compose.yml
よく使いそうなコマンド
設定ファイルがカレントディレクトリにあれば -f とパスは不要。
// コンテナの作成・起動
docker-compose -f ymlファイルのパス up
// コンテナの実行
docker-compose -f ymlファイルのパス up
// 削除
docker-compose -f ymlファイルのパス down
//停止
docker-compose -f ymlファイルのパス stop
実際にやってみる
ホストでの作業は[ホスト]コンテナでの作業は[コンテナ]と記載する。
ファイル作成等の事前準備
[ホスト]
テスト用のディレクトリを作成し、その配下にDocker Composeの設定ファイルを作成。
現在のディレクトリの構造
[ホスト]
% ls
docker-compose.yml
設定ファイルの内部
% cat docker-compose.yml
version: '3'
services:
db:
image: mysql:5.7
environment:
MYSQL_DATABASE: [接続したいスキーマの名前]
MYSQL_USER: [任意の値]
MYSQL_PASSWORD: [任意の値]
MYSQL_ROOT_PASSWORD: [任意の値]
TZ: 'Asia/Tokyo'
ports:
- '3306:3306'
volumes:
- ./data:/var/lib/mysql
- ./logs:/var/log/mysql
app:
image: node:11
environment:
- DEBUG=app:*
tty: true
ports:
- '3000:3000'
# - '3001:3001'
volumes:
- ./src:/app
# working_dir: /app/[GitHubからcloneするフォルダ(npm startを実行するフォルダ]
# command: npm run start
設定ファイルの説明
services
services以下にコンテナに関する情報を記載。
db、app
db、appという名称は任意だが、Sequelizeを初期化した際に生成されるconfig.jsonファイルのhostキーの値がこの内容となる。(今回だとdb
という名称がそれにあたる)
image
どのイメージを使用するかを記載。
今回は、mysql:5.7とnode:11を使用。
environment
MySQLで使用する環境変数を設定。
ports
左側がホストのポート番号、右側がコンテナのポート番号
ホストのポート番号は任意だが、仮にDockerを導入しているOSにて3000番と3006番ポートを使用している場合は重複しないように変更が必要。
複数使用したい場合はコメントアウトしてあるコードを外すと使用可能である。
volumes
左側にホストの情報、右側にコンテナの情報を記載。
今回は「data」「logs」「src」というディレクトリをローカルに作成。
また、コンテナ側の/app
配下にコードを記載していくようになる。
working_dir
起動時のディレクトリを指定。
GItHubからcloneしてきたリポジトリに移動するように設定するため、最初はコメントアウトしている。
command
起動時のコマンドを指定。
最初にコンテナを起動する際は、まだGitHubからリポジトリをcloneしていないので、コメントアウトしている。
コンテナ起動
MySQLのコンテナを起動
[ホスト]
% docker-compose run db
// これが出たら成功
Version: '5.7.37' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)
Nodeのコンテナを起動
[ホスト]
% docker-compose run app
コンテナの一覧を確認
[ホスト]
nodeとmysqlのコンテナが起動していたら成功。
% docker ps
4cb5cc823848 node:11 "docker-entrypoint.s…" 2 minutes ago Up 7 seconds docker_app_run_5cea1c0c5428
e8226de1f749 mysql:5.7 "docker-entrypoint.s…" 7 minutes ago Up 5 minutes 3306/tcp, 33060/tcp docker_db_run_77072701880a
ディレクトリ構造を再確認
[ホスト]
新しく「data」「logs」「src」というディレクトリが作成されている。
% ls
docker-compose.yml data logs src
GitHubのリポジトリを使用して環境構築
Git Hubからclone
[ホスト]
srcディレクトリに移動し、任意のGitHubのリポジトリからclone。
src % git [任意のGitHubのリポジトリ]
[コンテナ]
nodeコンテナにアクセス
ホストのsrcディレクトリとコンテナのappディレクトリは同じ構造である。
docker exec -it 4cb5cc823848 bash
root@4cb5cc823848:/#
cloneしてきたGitHubのリポジトリに移動してnpm install
を行う。
今回は、ここでExpress/Sequelizeが既にある状態。
[コンテナ]
# npm install
インストールが成功したら、一旦コンテナから抜ける。
[コンテナ]
exit
docker-compose.yml
ファイルの設定を変更
[ホスト]
ここで、docker-compose.yml
ファイルの設定を変更を、Node.jsコンテナに反映するためにコンテナを一旦停止する。
% docker stop 4cb5cc823848
4cb5cc823848
docker-compose.yml
ファイルのコメントアウトを外す。
[ホスト]
working_dir: /app/[GitHubからcloneするフォルダ(npm startを実行するフォルダ]
command: npm run start
コンテナを起動
[ホスト]
起動時のコマンドを打つためにコンテナを起動。
% docker-compose up
以下にアクセスしてExpressの初期画面が表示されれば成功。
http://localhost:3000/
DBのスキーマをコンテナ内に作成
[ホスト]
スキーマを作成する前に.env
ファイルをdocker-compose.yml
ファイルと同じ階層に作成。
DB_ROOT_HOST=%
DB_USER=[DBユーザーの名前]
DB_PASS=[DBユーザーのパスワード]
TZ=Asia/Tokyo
別サーバーのMySQLをローカルにコピーする方法は以下の記事で記載。
※スキーマは必ず別サーバーから持ってくる必要はなく、状況に合わせて設定する必要がある。
https://qiita.com/shintaro_secual/private/d3aeb2e30a39d07fa399
Node.jsコンテナとMySQLコンテナをSequelizeを使用して接続
[コンテナ]
Sequelizeをインストールして、初期化
npm install sequelize sequelize-cli mysql2
npx sequelize-cli init
初期化したことにより、config.jsonファイルが生成されるので、値を変更する。
"development": {
"username": [docker-compose.ymlファイルの環境変数で設定したMYSQL_USERの値を記載],
"password": [docker-compose.ymlファイルの環境変数で設定したMYSQL_PASSWORDの値を記載],
"database": [MySQLのスキーマ名を記載],
"host": "db", // docker-compose.ymlファイルのservicesの名称
"dialect": "mysql"
}
Node.jsコンテナを再起動すると、DBに接続されている。
Nodemon
nodeonを導入する方法を記載する。
[コンテナ]
nodemonをインストールする。
npm install nodemon
package.jsonに以下を追加する。
"scripts": {
"dev": "nodemon ./bin/www",
"start": "node ./bin/www"
}
docker-compose.yml
ファイルのnodeコンテナの情報欄のenvironment
に以下を追加
CHOKIDAR_USEPOLLING=1
今回だと以下のようになる。
app:
image: node:11
environment:
- DEBUG=app:*
# 新規追加
- CHOKIDAR_USEPOLLING=1
tty: true
ports:
- '3000:3000'
volumes:
- ./src:/app
working_dir: /app/[GitHubからcloneするフォルダ(npm startを実行するフォルダ]
# npm startから変更
command: npm run dev
上記設定でコンテナを再起動すると、nodemonが起動する。
ローカルサーバー立ち上げの速度向上
nodeのパッケージの使用数が多いと、ローカルサーバー立ち上げに時間がかかる可能性がある。
docker-compose.yml
ファイルに以下の記述を行うと解決可能である。
services:
app:
volumes:
- ./src:/app
# 追加 ↓
- node_modules_volume:/app/[コンテナ側のnode_modelesまでのパス]/node_modules
# 追加 ↓
volumes:
node_modules_volume:
再度コンテナでnodeのパッケージをインストールし、Docker Composeを再起動すると反映される。
筆者は、約10秒ほどローカルサーバーの立ち上げに時間がかかっていたが、約2秒ほどに改善された。