アルゴリズムとかオーダーとか

仕事で勉強したことなどをまとめてます

dockerでコンテナ実行時のユーザー権限で動く開発環境の構築

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が動く環境は構築できたので当初の目的は達成できたかな。
他にいい書き方とかあればぜひ教えてください。