VirtualBox + Docker
環境で Node.js + Express
を動作させたときの手順メモ
検証環境
Windows10 Home Edition
VirtualBox 5.2.22
Docker version 18.05.0-ce, build f150324
docker-machine version 0.14.0, build 89b8332
docker-compose version 1.20.1, build 5d8c71b
パッケージインストールのためのイメージ作成
VirtualBox
の共有フォルダ内にパッケージをインストールしようとすると、シンボリックリンクが作成できずエラーになるため Docker
イメージ内にインストールする
node.Dockerfile
FROM node:8-alpine
MAINTAINER takaya030
ENV HOME=/home/node
RUN mkdir $HOME/app
RUN chown -R node:node $HOME/*
USER node
WORKDIR $HOME/app
RUN yarn add express && \
yarn add @types/express \
typescript ts-loader tslint tslint-loader tslint-config-airbnb \
webpack webpack-cli \
webpack-node-externals \
--dev
docker-compose.yml
version: "3"
services:
node:
build:
context: .
dockerfile: ./node.Dockerfile
image: takaya030/node:8-alpine
イメージのビルド
$ docker-compose build node
作成したイメージから package.json
と yarn.lock
を抽出
イメージからコンテナを作成し、 docker cp
でホストOS側にコピーする
$ docker run --name temp-node takaya030/node:8-alpine /bin/true
$ docker cp temp-node:/home/node/app/package.json ./package.json
$ docker cp temp-node:/home/node/app/yarn.lock ./yarn.lock
node.Dockerfile
の変更
インストールされるパッケージのバージョンを固定するため node.Dockerfile
を変更する
--- a/node.Dockerfile Sun Feb 10 18:26:36 2019
+++ b/node.Dockerfile Sun Feb 10 19:20:49 2019
@@ -4,14 +4,10 @@
ENV HOME=/home/node
RUN mkdir $HOME/app
+COPY package.json yarn.lock $HOME/app/
RUN chown -R node:node $HOME/*
USER node
WORKDIR $HOME/app
-RUN yarn add express && \
- yarn add @types/express \
- typescript ts-loader tslint tslint-loader tslint-config-airbnb \
- webpack webpack-cli \
- webpack-node-externals \
- --dev
+RUN yarn install
+
+ENV PATH=$PATH:./node_modules/.bin
変更後の node.Dockerfile
でイメージビルドできるか確認
$ docker-compose build node
各種設定ファイル
以下の各ファイルはこちらのサイトから引用させて頂きました
qiita.com
webpack.config.dev.js
const path = require('path');
const nodeExternals = require('webpack-node-externals');
module.exports = {
mode: 'development',
entry: './src/server.ts',
target: 'node',
externals: [nodeExternals()],
devtool: 'inline-source-map',
module: {
rules: [
{
enforce: 'pre',
loader: 'tslint-loader',
test: /\.ts$/,
exclude: [
/node_modules/
],
options: {
emitErrors: true
}
},
{
loader: 'ts-loader',
test: /\.ts$/,
exclude: [
/node_modules/
],
options: {
configFile: 'tsconfig.dev.json'
}
}
]
},
resolve: {
extensions: [ '.ts', '.js' ]
},
output: {
filename: 'server.js',
path: path.resolve(__dirname, 'dist')
}
};
webpack.config.prod.js
const path = require('path');
const nodeExternals = require('webpack-node-externals');
module.exports = {
mode: 'production',
entry: './src/server.ts',
target: 'node',
externals: [nodeExternals()],
module: {
rules: [
{
enforce: 'pre',
loader: 'tslint-loader',
test: /\.ts$/,
exclude: [
/node_modules/
],
options: {
emitErrors: true
}
},
{
loader: 'ts-loader',
test: /\.ts$/,
exclude: [
/node_modules/
],
options: {
configFile: 'tsconfig.dev.json'
}
}
]
},
resolve: {
extensions: [ '.ts', '.js' ]
},
output: {
filename: 'server.js',
path: path.resolve(__dirname, 'dist')
}
};
tsconfig.dev.json
{
"compilerOptions": {
"sourceMap": true,
"noImplicitAny": true,
"module": "es6",
"target": "es5",
"jsx": "react",
"lib": ["es2018", "dom"],
"moduleResolution": "node",
"removeComments": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": false,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"strictFunctionTypes": false
}
}
tsconfig.prod.json
{
"compilerOptions": {
"noImplicitAny": true,
"module": "es6",
"target": "es5",
"jsx": "react",
"lib": ["es2018", "dom"],
"moduleResolution": "node",
"removeComments": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": false,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"strictFunctionTypes": false
}
}
{
"extends": "tslint-config-airbnb",
"rules": {
"ter-indent": [true, 4]
}
}
src/server.ts
こちらはサンプルのソースコードになります
import * as Express from 'express';
const app = Express();
app.get(
'/',
(req: Express.Request, res: Express.Response) => {
return res.send('Hello world.');
});
app.listen(
3000,
() => {
console.log('Example app listening on port 3000!');
});
export default app;
ビルドと実行
docker-compose.yml
の変更
ビルドと実行のための設定を追加します
--- a/docker-compose.yml Mon Feb 11 11:43:19 2019
+++ b/docker-compose.yml Sun Feb 10 23:14:41 2019
@@ -5,3 +5,9 @@
context: .
dockerfile: ./node.Dockerfile
image: takaya030/node:8-alpine
+ volumes:
+ - .:/home/node/app
+ - /home/node/app/node_modules
+ ports:
+ - "3000:3000"
+ command: node dist/server.js
ビルド
$ docker-compose run --rm node webpack --config webpack.config.dev.js
実行
$ docker-compose up -d
web ブラウザで http://192.168.99.100:3000 を開いて "Hello World." が表示されれば成功です
参考サイト
postd.cc