Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8873

Node.js WebアプリケーションのDocker環境構築まとめ

$
0
0

1.この記事の内容

ブラウザ経由で操作するWebアプリの実装が必要となり,Node.jsをDocker環境で動かすサンプルを実装しましたので紹介します.
Webページ上のフォームに入力されたデータをサーバ上にjsonファイルとして保存するプログラムです.

1-1.使用環境

  • Windows Subsystem for Linux上のUbuntu 20.04
  • Docker Imageはnode:12

1-2.ソースコード

本記事の内容は下記リポジトリの「01_docker_nodejs」~「03_file_access」までです.
本記事には概要のみを記載します.詳細はgithub内のソースコードを参照ください.

2.実装概要

2-1.Dockerfile

今回実装したサンプルはlocalhostアクセスを前提としていて,かつ,WSL2上に構築したDockerコンテナからアクセスするため,0.0.0.0でLISTENし,ポートは8080を使用します.
サーバの起動はnpmを使用しますが,サーバ上のファイルを保存するため,bashでコンテナを起動し「node server.js」または「npm start」を実行してサーバを起動します.

サーバ起動後はブラウザで「http://localhost:8080」へアクセスする.
なお,Dockerfile内の「CMD [ "/bin/bash" ]」を「CMD [ "npm", "start" ]」とすると「docker run」でサーバを起動することができます.

FROM node:12# アプリケーションディレクトリを作成するWORKDIR /usr/src/app# アプリケーションの依存関係をインストールする# ワイルドカードを使用して、package.json と package-lock.json の両方が確実にコピーされるようにします。# 可能であれば (npm@5+)COPY package*.json ./RUN npm install express axios --save# 本番用にコードを作成している場合# RUN npm install express axios --only=production# アプリケーションのソースをバンドルするCOPY . .EXPOSE 8080CMD [ "/bin/bash" ]

2-2.Webページのフォーム

index.htmlに自由記述のテキストボックスとSubmitボタンを配置し,Submitボタンがクリックされたらテキストボックスに入力されたデータがPOST送信される仕組みです.

<!doctype html><html><head><metacharset="utf-8"><title>POST sample</title><style>body{font-family:sans-serif;}input{padding:5px;font-size:1rem;}button{padding:5px;width:70px;font-size:1rem;}</style></head><body><formaction='/'method='POST'><table><tr><td>Name:</td><td><inputtype='text'name='name'value=''placeholder='Input your name'></td></tr><tr><td>Age:</td><td><inputtype='text'name='age'value=''placeholder='Input your age'></td></tr><tr><td>Phone:</td><td><inputtype='text'name='phone'value=''placeholder='Input your phone number'></td></tr><tr><td></td><td><buttontype='submit'>Submit</button></td></tr></table></form></body></html>

2-3.POST送信データの保存

Webフォームから入力されたnameフィールド名でjson保存先のディレクトリを生成し,Webフォームに入力されたname,age,phoneフィールドの内容をjson形式で保存します.

mkdir実行後,ファイルシステム上にディレクトリが生成される前にjsonファイル作成処理が実行される状況が生じたため,mkdir実行後にディレクトリ生成確認を行うようにしました.setIntervalを用いて1ms間隔でチェックし,100回チェックしてなお,ディレクトリ未生成状態が続けばタイムアウトする仕様で実装しました.

jsonファイル保存後はトップページに戻る仕様とし,GETリクエストを発行してページを取得し,ブラウザへ送信する.
以前はrequestモジュールが使用できたが,deprecatedだったので,代替手段のディスカッションの中で多そうだったaxiosモジュールを使用することとしました.

// App: Postapp.use(bodyParser.urlencoded({extended:true}));app.use(bodyParser.json());app.post('/',(req,res)=>{console.log(req.body);varuser_dir=path.join(user_dir_root,req.body.name);varuser_info_file=path.join(__dirname,user_dir,user_info);// create user directoryconsole.log(user_dir);console.log(user_info_file);console.log(__dirname);fs.mkdir(user_dir,{recursive:true},(err)=>{if(err)throwerr;});// create user information file after user directory is createdvarms=1;varcount=0;varcount_th=100;// timeout threshold: 100msvarinterval_id=setInterval(function(){if(fs.existsSync(user_dir)){clearInterval(interval_id);fs.writeFile(user_info_file,JSON.stringify(req.body,null,'\t'),(err)=>{if(err)throwerr;});console.log('[INFO] save user_info done');// back to top page after submitconstoptions={method:'GET',url:`http://${HOST}:${PORT}`,};axios.get(`http://${HOST}:${PORT}`).then(function(response){//                  console.log(response.data); // for debugres.send(response.data);});}else{count++;if(count>count_th){// timeoutconsole.log('[ERROR] Create directory failed: '+user_dir);throwError('[ERROR] Timeout');}}},ms);});

3.さいごに

環境立ち上げとしてjsonファイルの保存までを記事にしました.内容は基礎的な部分のみだと思いますが,どなたかの参考になりそうな情報が含められていれば幸いです.

4.関連リンク


Viewing all articles
Browse latest Browse all 8873

Trending Articles