ethereumの勉強をやってるととにかくnpmでいろいろ入れたり消したりするんだけど、npmでローカルインストールした時に自分の意図しないプロジェクトにまで影響出ることがあって、なんだかめんどくさくなったので今更ながらにdockerで開発環境を分ける事にした。
dockerを使うのは初めてなのでいろいろ調べてたら、どうやらdocker実行時はデフォルトでroot権限で動くらしい。
ソースコードはIDEからいじりたいので、ファイルはホストと共有するのでroot権限のまま作られると扱いが困る。
なのでdockerを起動したユーザーと同じ名前のユーザーをdockerコンテナ内でも作成してファイルの共有がスムーズになるような設定を四苦八苦して作ったので完成した設定ファイルを載せておきます。
container起動時の権限ユーザの指定とかdocker container上でユーザーを作成とかはバラバラに情報があったけど、やりたい事は
docker-compose.ymlなどの設定ファイルをいじらずに指定したユーザー名で動くcontainerの作成とその設定の仕方
なんだけどこれについてそのものずばりをまとめてくれているブログは見つからなかった。
で、いろいろ調べて作った設定ファイルがこれ。
Dockerfile
FROM node:8.7.0 ARG USER_NAME RUN apt-get update && apt-get install -y sudo && npm install -g truffle && npm install zeppelin-solidity RUN useradd --user-group --create-home --shell /bin/false ${USER_NAME} &&\ echo "${USER_NAME} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/${USER_NAME} ENV HOME=/home/${USER_NAME} RUN mkdir /opt/work RUN chown ${USER_NAME}:${USER_NAME} /opt/work USER ${USER_NAME} RUN ln -s /opt/work $HOME/solidity-proxy WORKDIR $HOME/solidity-proxy/
docker-compose.yml
version: "3" services: solidity-proxy: build: context: . args: USER_NAME: app volumes: - .:/opt/work
truffleのproject root上でコンテナ起動する前提で書いた。ユーザー名はimageをbuildする時に渡す。
containerのbuildと実行コマンドは次の通り
docker-compose build --build-arg USER_NAME=nakajo solidity-proxy docker-compose run --rm solidity-proxy /bin/bash
起動直後はなぜか/opt/workにいる。container上でcdしたら/home/$USER_NAME/solidity-proxyにいけるんだけどなんでだろ。。。
まぁ/opt/workで作業しても問題はないのでとりあえずこのまま使ってみよう。
一応、肝となるのはdocker-compose.ymlのbuild->argsでユーザー名のデフォルトを指定してるのとそれをDockerfileのARG USER_NAMEでロードしているところ。
あとはimageのbuildの時に必要であれば--build-argオプションで適宜書き換えればOK。
本当はvolumesでbindされるディレクトリも/home/${USER_NAME/solidity-proxyのように動的に指定したかったんだけど、どうやらdocker-compose.ymlの中では変数は展開されないようで、bindできなかった。苦肉の策でシンボリックリンクに逃げたけど思った通りの結果にはならなかった。。
とはいえ、一応最低限truffle testが動く環境は構築できたので当初の目的は達成できたかな。
他にいい書き方とかあればぜひ教えてください。