dockerでDynamoDB Localを構築する
DynamoDB LocalをDockerを利用して構築します。
ダウンロードして、展開して実行だけですね。
FROM centos:centos6 MAINTAINER oomatomo ooma0301@gmail.com RUN rpm -Uhv http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm RUN yum update -y # java RUN yum install -y wget tar java-1.8.0-openjdk java-1.8.0-openjdk-devel # dynamodb download RUN wget http://dynamodb-local.s3-website-us-west-2.amazonaws.com/dynamodb_local_latest.tar.gz ENV DYNAMODB_PATH /usr/local/dynamodb RUN mkdir -p $DYNAMODB_PATH RUN tar zxf dynamodb_local_latest.tar.gz -C $DYNAMODB_PATH WORKDIR /usr/local/dynamodb EXPOSE 8000 CMD ["java", "-Djava.library.path=.", "-jar", "DynamoDBLocal.jar", "-sharedDb"]
起動時のオプションの-sharedDb
は、リージョンごとにデータのファイルを作成されるのを防ぎます。
初めてDynamoDB Localを利用した時にリージョンごとにデータが作成されるのを知らなかったのではまりました。
docker-composeで開発用のredisとmysqlを構築する
今回は、docker-composeを使って開発用にredisとmysqlを使います。
最近は、docker-composeをサービスごとに作って利用しています。
docker-composeをインストール方法
brew caskでinstallできます。
brew install caskroom/cask/brew-cask brew cask install docker-compose
docker-composeの前にredisとmysqlのdockerfileの内容です。
Dockerfileの内容
とりあえず、自分が昔から使っているやつを貼っときます。 今は、docker公式のやつがあるのでそちらを使ってもいいかもしれません。
RedisのDockerfile
公式のやつでもいいです。 https://hub.docker.com/_/redis/
FROM centos:centos6 MAINTAINER oomatomo ooma0301@gmail.com # install package RUN rpm -Uhv http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm RUN yum update -y RUN yum install -y wget tar make gcc RUN cd /tmp && \ wget http://download.redis.io/redis-stable.tar.gz && \ tar xvzf redis-stable.tar.gz && \ cd redis-stable && \ make && \ make install && \ cp -f src/redis-sentinel /usr/local/bin && \ mkdir -p /etc/redis && \ cp -f *.conf /etc/redis # どこからもアクセスできるようにする RUN sed -e "s/# bind 127.0.0.1/bind 0.0.0.0/" -i /etc/redis/redis.conf EXPOSE 6379 CMD ["redis-server", "/etc/redis/redis.conf"]
mysqlのDockerfile
公式のやつでもいいです。 https://hub.docker.com/_/mysql/
FROM centos:centos6 MAINTAINER oomatomo ooma0301@gmail.com # install package RUN rpm -Uhv http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm RUN yum update -y RUN yum install -y wget tar # install mysql RUN wget http://dev.mysql.com/get/Downloads/MySQL-5.5/MySQL-5.5.46-1.el6.x86_64.rpm-bundle.tar RUN tar xvf MySQL-5.5.46-1.el6.x86_64.rpm-bundle.tar RUN yum localinstall -y MySQL-shared-compat-5.5.46-1.el6.x86_64.rpm RUN yum localinstall -y MySQL-shared-5.5.46-1.el6.x86_64.rpm RUN yum localinstall -y MySQL-server-5.5.46-1.el6.x86_64.rpm RUN yum localinstall -y MySQL-client-5.5.46-1.el6.x86_64.rpm RUN yum localinstall -y MySQL-devel-5.5.46-1.el6.x86_64.rpm # create mysql ADD privilege.development.sql /tmp/ RUN /etc/init.d/mysql start \ && mysql -u root < /tmp/privilege.development.sql EXPOSE 3306 CMD ["/usr/bin/mysqld_safe"]
privilege.development.sqlの内容
ユーザの作成を行っているだけです。
もしくは、サービスごとのSQLだったりします。
CREATE USER 'ooma'@'%' IDENTIFIED BY 'tomo'; GRANT ALL PRIVILEGES ON *.* TO 'ooma'@'%' WITH GRANT OPTION;
docker-composeの設定方法
docker-compose は、docker-compose.yml
というyml形式の設定ファイルを作成します。
とりあえず、最低限の設定の説明です。
[キー]: build: [dockerfileの場所] ports: - "[hostのポート]:[dockerのポート]"
実際の設定ファイル。
mysql: build: ./mysql ports: - "3306:3306" redis: build: ./redis ports: - "6379:6379"
docker-composeの使い方
docker build
# ビルド
docker-compose build
docker-compose build [キー] docker-compose build redis
# バックエンドでは、動かない
docker-compose up
redisのみ実行すると。。
$ docker-compose up redis Creating docker_redis_1... Attaching to docker_redis_1 redis_1 | _._ redis_1 | _.-``__ ''-._ redis_1 | _.-`` `. `_. ''-._ Redis 3.0.5 (00000000/0) 64 bit redis_1 | .-`` .-```. ```\/ _.,_ ''-._ redis_1 | ( ' , .-` | `, ) Running in standalone mode redis_1 | |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 redis_1 | | `-._ `._ / _.-' | PID: 1 redis_1 | `-._ `-._ `-./ _.-' _.-' redis_1 | |`-._`-._ `-.__.-' _.-'_.-'| redis_1 | | `-._`-._ _.-'_.-' | http://redis.io redis_1 | `-._ `-._`-.__.-'_.-' _.-' redis_1 | |`-._`-._ `-.__.-' _.-'_.-'| redis_1 | | `-._`-._ _.-'_.-' | redis_1 | `-._ `-._`-.__.-'_.-' _.-' redis_1 | `-._ `-.__.-' _.-' redis_1 | `-._ _.-' redis_1 | `-.__.-' redis_1 | redis_1 | 1:M 20 Oct 22:49:23.033 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. redis_1 | 1:M 20 Oct 22:49:23.033 # Server started, Redis version 3.0.5 redis_1 | 1:M 20 Oct 22:49:23.033 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. redis_1 | 1:M 20 Oct 22:49:23.033 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled. redis_1 | 1:M 20 Oct 22:49:23.034 * The server is now ready to accept connections on port 6379 ←ここでCtrl+Cをやる ^CGracefully stopping... (press Ctrl+C again to force) Stopping docker_redis_1... done
docker run
# 全体をデーモンで実行 docker-compose up -d # mysqlのみデーモンとして実行 docker-compose up -d mysql # redisのみデーモンとして実行 docker-compose up -d redis
あと各ポートにアクセスします。
今まで、毎回 docker run ..
でやっていたのが、簡単に調整出来るのがいいです。
Gitで削除したファイルを一括でgit rmする方法
Gitで削除済みのファイルを削除したよっていうコミットを作成する時
git rm ファイル名
をします。
毎回 git rm するのが嫌なので、一括で出来るようにする方法です。
git ls-files -d -z | xargs -0 git rm
git ls-files の説明
リポジトリ対象のファイルを見ることができます。
-d
で現在の作業ディレクトリで削除されたファイルの一覧を出します。
-z
で削除の終端文字が\0
になります。
デフォルトは、改行です。
xargs の説明
前のコマンドの出力結果を引数みたいな形で繋げることが出来ます。
よく使います。
-0
は\0
を区切り文字として扱ってそれぞれ引数になります。
あとは、引数として分割されたファイルをgit rm
していくだけです。
git はサブコマンドが面白いからいいですね。
docker-machineを使ってみる
Install for Mac
brew でサクッといけます。
brew install docker brew cask install docker-machine
docker-machine
https://docs.docker.com/machine/#osx-and-linux
dockerを利用する土台用の仮想環境を構築する。
(boot2dockerではじめに作成した環境と同じ)
boot2docker init
boot2docker ssh で接続した環境
今回は、virtualboxを使って環境の構築を行います。
メモリーやディスクの設定は、お好きにどうぞ。
docker-machine create -d virtualbox --virtualbox-disk-size "20000" --virtualbox-memory "2048" dev
dockerコマンドを利用するためには、eval "$(docker-machine env dev)"
が必要です。
eval "$(docker-machine env dev)" docker ps
簡単ですね。
dockerにアクセスする方法
# dockerを動かしているサーバにアクセス docker-machine ssh dev tce-load -wil util-linux # アクセスしたいコンテナIDを設定すればおk sudo nsenter --target $(docker inspect --format '{{.State.Pid}}' アクセスしたいコンテナID) --mount --uts --ipc --net --pid # 例 sudo nsenter --target $(docker inspect --format '{{.State.Pid}}' 2f1688b9fbe9) --mount --uts --ipc --net --pid
zshの設定
.zshrcなどにeval "$(docker-machine env dev)"を
記入しておく
docker-machineが起動してない場合でターミナルを開くと
dev is not running. Please start this with docker-machine start dev
という内容が出るので安心。
感想
今回はローカルのリソースを使ったので、boot2dockerとあまり変わらなかった。
PerlTidyでの一括整形コマンド
地味に面倒くさかったので、メモとして残します
初めにやろうとしたこと
find ../lib -name '*.pm' | xargs perltidy -pbp
失敗でした。ただ、整形後のコードが標準出力として表示されただけでした。
-pbpは以下の内容が含まれています。
上記のオプションでダメなところが 「 -st # Output to STDOUT 」 です。
-st なしでコマンドを実行すればいいのではないかと考えました。
find ../lib -name '*.pm' | xargs perltidy i=2 ....
これもダメでした。
理由としては、元のpmファイルはそのままで、整形されたファイルが *.pm.tdy として出力されていたためです。
これを解決するオプションが [ -b ] です。
-b backup original to .bak and modify file in-place
元のファイルを .bak ファイルとして置き換えてくれるオプションです。
これにより .pm ファイルが整形後のファイルになります。
そして、最後に .bakファイルを削除すれば全て置き換えてくれます。
最終的に以下のシェルスクリプトにまとまりました。
Catalystでリクエスト元IPアドレスをいじるテストについて
Catalystでリクエスト元のIPアドレス によって処理を分岐させるコードがあったのですが、
テストコードでのテストはしていませんでした。
存在しなかったので、テストコード書くことにしました。
やったこと
・ LWP::UserAgent local_address
・ Test::WWW::Mechanize::Catalystの環境変数の設定
・ Plack::Test test_psgi
・ Test::WWW::Mechanize::PSGI
LWP::UserAgent local_address
Test::WWW::Mechanize::Catalystの親クラスにLWP::UserAgentがいたので、local_addressが利用できるのではないかと感じ 以下のコードで試しました。
結果は失敗でした。まねしないでください。
出来ない理由は以下の通りです。
Test::WWW::Mechanize::Catalystの親クラスとして
Test::WWW::Mechanize
WWW::Mechanize
LWP::UserAgent
があります。
以下のコードはWWW::Mechanizeのgetメソッドです。
なるほど、SUPER::getしてますね。
LWP::UserAgentのgetでは、requestを呼んでいるため
LWP::UserAgent->get
LWP::UserAgent->request
と思ってました。
でも、実際は違いました。
LWP::UserAgent->get
WWW::Mechanize->request
でした。
ちゃんとコメントにも書いてありますね。
# but it in turn calls the request() method here in Mechanize
さらにWWW::Mechanize->requestで_make_requestを呼んでました。
以下のコードは、WWW::Mechanizeの_requestです。
整理すると Test:::WWW::Mechanize::Catalystでgetを使うと
WWW::Mechanize->get
LWP::UserAgent->get
WWW::Mechanize->request
Test::WWW::Mechanize::Catalyst->_make_request
こんな感じの流れになります。
そのため、LWP::UserAgent->requestが呼ばれていないためHTTPのリクエスト生成時にlocal_addressが使用されないだろうと思いました。
また、LWP::UserAgentのDocumentに local_addressはIO::Socket::INETにLocalAddrとして渡すと書いてありました。
Get/set the local interface to bind to for network connections. The interface can be specified as a hostname or an IP address. This value is passed as the LocalAddr argument to IO::Socket::INET.
これでは確かに無理ですね!!!
Test::WWW::Mechanize::Catalystの環境変数の設定
今度はTest::WWW::Mechanize::Catalystで環境変数であるREMOTE_ADDRを渡す方法を探りました。Test::WWW::Mechanize::Catalyst(Version 0.59 )は、_do_catalyst_requestでリクエストを処理しています。
上のコードを見てもらえる分かるのですが、CATALYST_SERVERの有無をチェックしています。
(有)_do_remote_requestでCATALYST_SERVERにリクエストを投げる
(無)Catalyst::Test::_local_requestにCatalystのオブジェクトのインスタンスを渡す
ということになっています。
Catalyst::Test::_local_requestでは_requestを呼び出していました。
%extra_envにREMOTE_ADDRを設定できれば、いけることが分かると思います。
しかし、Test::WWW::Mechanize::Catalystの_do_catalyst_requestの段階で引数として渡せないため
Test::WWW::Mechanize::Catalystで環境変数の設定はできないみたいです。
Catalyst::Test::_local_request($self->{catalyst_app}, $request)
Plack::Test test_psgi
次に行ったことが Plack::Testを使った方法です。こちらは以下のコードで成功しました。
test_psgiでappに渡す内容は Catalyst::Test::_requestをパクって・・参考にしています。
Test::WWW::Mechanize::PSGI
Test::WWW::Mechanize::CatalystがダメだったのでTest::WWW::Mechanize::PSGIにしてみました
今回はTest::WWW::Mechanize::PSGIを利用しています。
また、簡単に切り替えができるように以下のようなメソッドで使ってます。
テストコードを少しずつ書くようにして半年経ちますが、
テストコードを書かないと不安になるようになりました。
そしてテストコードを書くのは楽しいです。
一つ一つの分岐を網羅していくのは、ドラクエのダンジョンで隅々まで網羅していくのと
同じ感覚です。
(開発では、完全網羅は難しいですけど)