進捗はありません

備忘録や研究メモ、日々の雑談や意見も

オレ的開発環境管理(Docker)

個人のPCの開発環境の管理ってどうしてますか?

Dockerを利用して複数人の開発環境を統一できたり、簡単に環境を再構築したりWebアプリのテストができたりと、Dockerの開発環境の恩恵を大いに受けています。
個人での開発や分析でも特にこの恩恵は強く、どのマシンでも、例えばPythonやRの分析環境を持ち歩いたり、jupyterのextensionも含めてimageにしてしまえば本当に分析環境をまるっと持ち出せるのが便利でずっとDocker使ってますが、しばしばこんな問題にあたりませんか?

MacWindowsのvolume周りのコマンドが違ってつらい

例えば、Docker for Macでは、

docker run -v ./:/home/user/ <image>

のような指定で簡単にカレントディレクトリとコンテナのデータ共有ができると思いますが、Docker for windowsだとどうでしょうか。ご存知の方も多いでしょうが、これでは動きません。Windows(cmd)でカレントディレクトリの共有をしようとすると、基本的にフルパスを指定します(C:hogehogeみたいな感じで)
これ、めちゃくちゃ不便ですよね。私は家だとWindowsがメインで、研究室だとMacなので、同じDockerfileやdocker-composeでも、volume周りだけどうしても環境の統一ができない状態でした。

現在の開発/分析環境の管理方法

簡単にいうと、Makefileを使ってMacでもWindowsでも動くコマンドを管理して、make経由でコマンドを実行するようにしています。

分析環境の管理例(python)

ディレクトリ構成

workspace/
      ├Dockerfile
      ├dev.mk

まずはDockerfile。個人の設定そのまま入れているので、 パッケージ群とjupyterのextension設定を反映している。 パッケージとして注意していることは、tensorflowが入っていることでこれはインストール順でnumpy等の依存関係が上書きされるため、tensorflowだけ最後にインストールするようにしている。 個人の開発環境なのでrootで使っているが、外部サーバーに置く場合などはuserやセキュリティ設定は変えてます。

FROM python:3.6

MAINTAINER kyo-bad

RUN apt-get update \
    && apt-get install -y screen vim \
    && pip3 install --upgrade pip \
    && pip3 install --upgrade jupyter pandas matplotlib seaborn scikit-learn jupyter_nbextensions_configurator jupyterthemes \
    && pip3 install --upgrade tensorflow \
    && jupyter nbextensions_configurator enable --user \
    && git clone https://github.com/lambdalisue/jupyter-vim-binding $(jupyter --data-dir)/nbextensions/vim_binding \
    && jt -t monokai -T -N -altmd -vim

WORKDIR /root/workspace

続いて、dev.mkというmakefileを作成する。中身はこんな感じ

.PHONY: build run docker/*

WORK_DIR := $(CURDIR)
LOG_DIR := $(CURDIR)

BUILDER_IMAGE := python:myenv
BUILDER_WORK_DIR := /root/workspace
BUILDER_CMD := docker run --rm -it -v $(WORK_DIR):$(BUILDER_WORK_DIR) -w $(BUILDER_WORK_DIR) -p 6006:6006 -p 8888:8888 $(BUILDER_IMAGE)

setup:
  docker build -t $(BUILDER_IMAGE) .

rebuild-image:
  docker rmi $(BUILDER_IMAGE)
  docker build -t $(BUILDER_IMAGE) .

attach:
  $(BUILDER_CMD) bash

jupyter:
  $(BUILDER_CMD) jupyter notebook --ip 0.0.0.0 --no-browser --port 8888 --allow-root

tensorboard:
  $(BUILDER_CMD) tensorboard --logdir=$(LOGDIR)

Makefileで管理することのメリット

WIndowsでもMacでも同じコマンドで動く

これが一番大きいです。カレントディレクトリを共有する場合のコマンドの違いを、makeのCURDIRで隠蔽することで参照方法を統一している。 注意点としては、WORK_DIRをユーザのホームディレクトリにしてはいけないこと。これは、volume共有によってbashのログとかドットファイル類がホストにも共有されてしまうため。

長ったらしいコマンドを打たなくていい。

例えば、イメージのビルドだったら、

make -f dev.mk setup

これでいいし、jupyterの起動だったら

make -f dev.mk jupyter

でホストにサーバが立ち上がる。

angularでも似たような管理をしているので参考までに

Dockerfile(dev)

FROM node:8-alpine

MAINTAINER kyo-bad

RUN apk update \
    && apk add --no-cache --update alpine-sdk build-base python yarn \
    && yarn cache clean \
    && yarn global add @angular/cli@1.6.6 \
    && ng set --global packageManager=yarn \
    && apk del alpine-sdk \
    && rm -rf /tmp/* *.tar.gz ~/.npm \
    && yarn cache clean \
    && adduser -D appuser

COPY --chown=appuser:appuser project /home/appuser/app
ENV HOME=/home/appuser
USER appuser
WORKDIR ${HOME}/app
CMD [ "yarn && ng serve --host 0.0.0.0" ]

Makefileは以下

.PHONY: build run new yarn serve docker/* 

BUILDER_IMAGE := angular-yarn-alpine:myenv
BUILDER_WORK_DIR := /home/appuser/app
BUILDER_APP_NAME := app
BUILDER_CMD := docker run --rm -it -v $(CURDIR)/$(BUILDER_APP_NAME)/$(BUILDER_APP):$(BUILDER_WORK_DIR) -w $(BUILDER_WORK_DIR) -p 4200:4200 $(BUILDER_IMAGE)

setup:
  docker build -t $(BUILDER_IMAGE) .

rebuild-image:
  docker rmi $(BUILDER_IMAGE)
  docker build -t $(BUILDER_IMAGE) .

new:
  docker run --rm -v $(CURDIR):$(BUILDER_WORK_DIR) -w $(BUILDER_WORK_DIR) $(BUILDER_IMAGE) ng new $(BUILDER_APP_NAME) --routing

yarn:
  $(BUILDER_CMD) yarn

serve:
  $(BUILDER_CMD) ng serve --host 0.0.0.0 --poll 2000

attach:
  $(BUILDER_CMD) sh