本記事で作ったdockerfileを整理したものをまとめた記事は⬇️
https://qiita.com/sho_U/items/52e221877a271146ce84
完成イメージ構成
nodoDocker(rootディレクトリ)
###Dockerfile:
アプリケーション用(node.js)コンテナを作るためのfile
###app.env:
mysqlとの接続設定を記載したファイル
###docker-compose.yml:
node.jsコンテナとmysqlコンテナを管理するyml
###src:
アプリケーション本体
##アプリケーション用のコンテナを作成する
まずはアプリケーション用の仮コンテナを作成し、アプリの雛形を作成する。そのアプリの雛形はホスト側にマウントしておき、その雛形を利用してdocker-composeを作成していく。
nodeDocker配下に
docker-compose.ymlを作成
version: '3'
services:
app:
# dockerimageのファイルを指定
build: .
# コンテナ名
container_name: node_docker_app
# 環境変数を設定
environment:
- DEBUG=app:*
tty: true
# ホスト側のポート:コンテナのポート
ports:
- '3000:3000'
# ソースコードを格納するフォルダをマウント
#(ホスト側の./srcをコンテナの/appにマウント)
volumes:
- ./src:/app
# 起動時のカレントフォルダを指定
working_dir: /app
# 起動後に実行するコマンドを指定(起動確認用)
command: npm start
node をプルする。
FROM node:12
#コンテナを一時的に起動(--rmで停止後削除する。コンテナ起動後、bashに入る)
docker-compose run --rm app /bin/bash
# express-generatorでアプリケーションのひな形を生成
npx express-generator
# 依存パッケージをインストール
npm install
#コンテナを抜ける(この仮コンテナは削除される)
exit
※この時、コンテナは削除されるが
volumes:
- ./src:/app
この記述により、.(docker-compose.ymlがあるディレクトリ。つまりnodoDockerディレクトリの配下のsrcディレクトリにマウントされているため、ホスト側のsrcディレクトリに作成した雛形は残っている。
コンテナを起動させる
docker-compose up
command: npm start
の記載により、コンテナ起動後、自動的にExpress.jsのアプリケーションが起動する。
http://localhost:3000/
で確認。
コンテナを停止
#再度コンテナを一時的に起動
docker-compose run --rm app /bin/bash
#ソースコードの変更を検知して必要な時にアプリケーションを再起動してくれる、「nodemon」というツールをインストール。
#変更のたびにコンテナの停止・再起動することしなくてよくする。
npm install -D nodemon
package.jsonを修正
"scripts": {
"dev": "nodemon ./bin/www",
"start": "node ./bin/www"
},
docker-compose.ymlファイルを編集
(変更前)
command: npm start
(変更後)
command: npm run dev
##MySQL用コンテナを追加
docker-compose.ymlにmysqlの設定を追加
version: '3'
services:
mysql:
image: mysql:5.7
env_file: ./mysql/mysql.env
#環境変数設定。タイムゾーンを日本時間に設定。
environment:
- TZ=Asia/Tokyo
ports:
- '3306:3306'
volumes:
#mysqlのデフォルト設定ファイルを上書き。:roでコンテナ側からは読み取り専用設定。
- ./mysql/conf:/etc/mysql/conf.d/:ro
#mysqldataにマウントすることで、コンテナを削除してもデーターは残るように設定。
- mysqldata:/var/lib/mysql
networks:
- backend
app:
image: node:12
env_file: ./app.env
#環境変数設定。タイムゾーンを日本時間に設定。
environment:
- TZ=Asia/Tokyo
- DEBUG=app:*
tty: true
ports:
- '3000:3000'
volumes:
- ./src:/app
working_dir: /app
command: npm run dev
networks:
- backend
#mysqlに依存しているので、mysqlコンテナ作成後、appコンテナが作られる。
depends_on:
- mysql
networks:
backend:
volumes:
mysqldata:
my.confを作成(コンテナ側の/etc/mysql/conf.d/に配置される。)
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqldump]
default-character-set=utf8mb4
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_bin
lower_case_table_names=1
# Enable access from the host machine.
bind-address=0.0.0.0
mysqlフォルダにmysql.envファイルを作成。(env_file: ./mysql/mysql.envの記載により、内容がコンテナ側のmysqlの環境変数に設定される)
MYSQL_ROOT_HOST=%
MYSQL_ROOT_PASSWORD=(ルートパスワード)
MYSQL_USER=(ユーザー名)
MYSQL_PASSWORD=(パスワード)
MYSQL_DATABASE=todo
app.envファイルを作成(アプリケーションコンテナの環境変数設定)
MYSQL_SERVER=mysql
MYSQL_USER=(ユーザー名)
MYSQL_PASSWORD=(パスワード)
MYSQL_DATABASE=todo
version: '3'
services:
mysql:
image: mysql:5.7
container_name: node_docker_db
env_file: ./mysql/mysql.env
environment:
- TZ=Asia/Tokyo
ports:
- '3306:3306'
volumes:
- ./mysql/conf:/etc/mysql/conf.d/:ro
- mysqldata:/var/lib/mysql
networks:
- backend
app:
image: node:12
container_name: node_docker_app
env_file: ./app.env
environment:
- TZ=Asia/Tokyo
- DEBUG=app:*
tty: true
ports:
- '3000:3000'
volumes:
- ./src:/app
working_dir: /app
command: npm run dev
networks:
- backend
depends_on:
- mysql
#使用するネットワークを作成。docker-composeの場合service以下の名前を使って名前解決されるため、appとmysqlが自動的に接続される。
networks:
backend:
volumes:
mysqldata:
mysqlにログイン
docker-compose exec mysql mysql -uroot -p
できない、、、
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
いろいろ試した結果
docker-compose down --volumes
volumeを削除したら、ログインできた。原因は不明。
ejsをテンプレートエンジンに使用するためインストールを記載したdockerfileをルート直下に配置。
#node.jsのイメージをプル。
FROM node:12
#作業ディレクトリをアプリケーションディレクトリにする。
WORKDIR /app
ejsをインストール。
RUN npm install ejs
アプリ件ーションコンテナはDockerfileでビルドするようにしたため(元々はnode:12イメージをプルしてた)修正
(変更前)
image: node:12
(変更後)
build: .
ひとまず完了。