LoginSignup
4

More than 5 years have passed since last update.

docker-composeを使って、プライベートでstandaloneなgethを立ち上げて永続化する方法【解決編】

Posted at

失敗編からの続きです。

前提

こんな人には役に立つかもしれない

  • Ethreumを使ってガシガシ開発したいから、開発に使えるEthreumノードが必要。
  • どこかのVPSにノードを立ち上げたりInfura.ioのtestnetを使えばよいのだけど、立ち上げは手軽じゃないし、まだ開発中だからtestnetじゃなくてやプライベートでやりたい、そして、Wifiがなくても開発機内で完結したい、という欲求がある。
  • docker-composeを使いたい。
  • コンテナを終了してもチェーンDATAは残したい(永続化したい)。次にコンテナを立ち上げたときには次のブロックからマイニングが始まるようにしたい。

そんな需要があったので頑張ってやってみました。

当初戦略

  1. gethは公式のDockerイメージを使う。
  2. Dockerfile内でgethのinitやテストアカウントのimportをする。
  3. chain_dataはホスト内に保存されるようにマウントする。
  4. コンテナを立ち上げるときにプライベートネットのnetworkIdを引数で渡す

困ったこと

  • マウント無しでDockerfile, docker-compose.ymlを以下のようにするとすんなりとプライベートネットが立ち上がるが、永続化されていないので、一旦コンテナを削除すると、ジェネシスブロックからの作り直しになってしまう。
  • data_dirをマウントして立ち上げると、今度はnetworkIdが1(つまりmainnet)になってしまう。

マウントするとmainnetになってしまう原因

  • buildのイメージ内にプライベートネットのジェネシスブロックが生成されていても、ホストのディレクトリをマウントした時点で消えてしまう
  • そうするとコンテナ立ち上げのときにgethの引数でdatadirとnetworkIdを指定しても、ジェネシスブロックが存在しないので、デフォルトでmainnetとなるようになっている。

解決手順

マウント=>ジェネシスブロック生成(geth init)=>geth立ち上げ という順序にすることは不可能なので以下のような手順をふむようにした。

  1. まずは、ジェネシスブロック生成用のコンテナを立ち上げる(geth_initコンテナ)
  2. ホストの./geth_dataにgeth_initコンテナの/tmp(空)をマウントする
  3. geth_initコンテナに生成されたdatadirを/tmpに同期するとホストの./geth_dataにチェーンデータができる。
  4. geth_initコンテナを終了してもホストにはプライベートネットのチェーンデータが残る
    Qiita用イメージ図-2.png

  5. マイニング用のgethコンテナを先程の./geth_dataをマウントして立ち上げる。

  6. プライベートネットのnetworkIdとマウントされたディレクトリをdatadireとして引数を与えてれば、gethコンテナのgethはそこを参照して、プライベートネットが立ち上がる。

  7. DAG生成後、マイニングが始まり、続くブロックが生成される。
    Qiita用イメージ図2-2.png

  8. gethコンテナを終了しても、生成されたブロックはホストの./geth_dataに残っている。

  9. 再びgethコンテナを立ち上げると、既存のチェーンデータが参照され、続きからマイニングされる。

コマンド

$ git clone https://github.com/imaichel/ethereum-docker.git
$ cd ethereum-docker/standalone/
$ docker build -f geth/Dockerfile_gethinit -t gethinit:1.0.0 geth
~略~
Successfully built f524701f5b3a
Successfully tagged gethinit:1.0.0
$ docker images
REPOSITORY           TAG                 IMAGE ID            CREATED              SIZE
gethinit             1.0.0               f524701f5b3a        About a minute ago   48.1MB

$ mkdir volume
$ docker run -d -v $PWD/volume:/tmp --name gethinit gethinit:1.0.0 --networkid 1234 --datadir=/root/.ethereum
$ docker exec -it gethinit /bin/bash
# rsync -av /root/.ethereum /tmp/
# exit
$ docker-compose up -d --build
$ docker-compose logs -f

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4