Edited at

lambda + RDB なシステムのローカル開発環境をdockerで

More than 1 year has passed since last update.

いつか誰かのあら^〜便利になることを祈ってます。僕です。

あら便利カレンダー2018


概要

serverless framework(併せてserverless offline)を用いたlambdaの開発を行うにあたり、ローカル開発環境の準備が必要だった。

DBはmariadb(mysql)。

そんなローカル開発環境をdockerコンテナで用意してみた。


構成

以下のモジュールを突っ込んだコンテナをdocker composeで構築する。


  • nodeコンテナ


    • typescript

    • serverless framework

    • serverless offline

    • ts-loader

    • serverless webpack

    • mysql

    • その他諸々



  • mariadbコンテナ


    • こっちは特にない




諸々のバージョン

大事そうなとこだけ抜粋。


  • node: 8.11.3

  • mariadb: 10.2.16

  • typescript: 2.9.2

  • webpack: 4.16.0

  • serverless webpack: 5.2.0


コンテナにするメリット


  • dockerさえあれば開発もデプロイもできる


    • いつまでもあのころのmacのまま、環境汚染しない

    • デプロイ等でslsなコマンドを叩く時もコンテナ内で(コンテナ経由で)実行する



  • コンテナ使うと環境の共有も楽

  • VM重すぎるよぉ😫みたいなつらみもない

引き続き頑張ってdockerおじさん目指したい次第。


ディレクトリ構造

sample_project/

 ├ app/

 │ └ tsのいろいろ

 ├ Dockerfile

 ├ docker-compose.yml

 ├ package.json

 ├ webpack.config.js

 ├ tsconfig.json

 └ serverless.yml

みたいな感じ。


Dockerfile

アプリを載せるnodeのコンテナイメージを作るのに用意した。

railsとかだと依存物が結構あるので、apk add でパッケージの追加が必要だった。

みんな大好きnokogiriとかあのへんの兼ね合いだったかな

でも、nodeだとdocker hubにあるイメージのままほとんど手を加えてない。楽。


Dockerfile

FROM node:8-alpine

RUN mkdir /application

WORKDIR /application

COPY package.json ./

RUN \
set -x \
&& npm install



docker-compose.yml


docker-compose.yml

version: '3'

services:
slsdb:
image: mariadb:10.2
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --skip-character-set-client-handshake
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD
- MYSQL_DATABASE
slsapp:
build: .
command: npx serverless offline --host 0.0.0.0 --port 3000
volumes:
- .:/application
- /application/node_modules
ports:
- "3000:3000"
depends_on:
- slsdb

コンテナ立ち上げ時にserverless offlineが動く。


ここがポイント

slsappvolumesに注目。


volumes:

- .:/application

- /application/node_modules


.:/applicationは、"ホストのdocker-compose.ymlと同じ場所のものをコンテナの/applicationにマウントする" 、というよくある感じの記述です。

/application/node_modulesはというと、この記述があることで以下のような挙動をする。


  • Dockerfileを元にビルド

  • コンテナにはnode_modulesが作成される

  • compose時にカレントディレクトリをマウント

  • コンテナ内に存在したnode_modulesを寄せておいて、マウント後に寄せておいたnode_modulesを置き直す

つまり、ビルド時にコンテナ内できるnode_modulesを生かしたまま、ホストのファイル群をマウントできる感じ。

こうすることで、完全にlinux用のnode_modulesが作られる。

もしOS依存のモジュールがあった場合、macで作られたnode_modulesがalpineに入っていて動かないなんてことがあるかもしれない。

それを防げる。

こちらのサイト大変勉強になりました。

https://shotat.hateblo.jp/entry/2016/12/01/221631


補足:ライブリロード

ローカルでファイル編集するたび、tsのコンパイルがされ、ログ出力がされる状態にしたかった。

以下のような感じで設定すれば大丈夫そう。


tsconfig.json

"noEmitOnError": false


参考までにwebpackの設定も載せておく。


webpack.config.js

const path = require("path");

const slsw = require("serverless-webpack");
const nodeExternals = require("webpack-node-externals");

module.exports = {
mode: "none",
entry: slsw.lib.entries,
target: "node",
devtool: "source-map",
externals: [nodeExternals()],

module: {
rules: [
{
test: /\.tsx?$/,
loader: "ts-loader"
}
]
},

resolve: {
extensions: [".ts", ".js", ".tsx", ".jsx"]
},

output: {
libraryTarget: "commonjs",
path: path.join(__dirname, "dist", "lambda"),
filename: "[name].js"
}
};


変更を保存するたびに、エラーがあろうがなかろうがコンパイルしてログ吐くって感じになります。

ただ、WebStormでの挙動がちょっと怪しい雰囲気。

webpackの "Saving in WebStorm" がちょっと気になる。

そのほか自動保存のスパンを1secとかにしてみたりして、調査中。


コンテナ経由でserverlessコマンド

例としてserverless infoを実行するときのコマンドがこんな感じ。

$ docker-compose run --no-deps --rm slsapp npx serverless info

docker runとかで実行しちゃうと、docker-compose.ymlslsappに環境変数を設定した場合なんかはそれが適用されないので注意。

デプロイ等もこんな感じのコマンドで実行できる。