13

I would like to create a Docker image for a test network that has everything ready to go - pre-created accounts with ether already allocated.

The problem is there doesn't seem to be a way to do this the Docker Way(tm). In order to create ether out of thin air, I have to put addresses in the genesis.json 'alloc' section. In order to get the addresses, I have to create accounts with multiple invocations of geth and then manually edit genesis.json. Manual steps are not the Docker Way(tm), you are supposed to create a Docker file that does all these steps automatically.

My current best bet seems to be to to create a script that creates the accounts I need and the gets the account addresses from the geth command line option for that and then edits genesis.json on the fly. That seems... rather crude, and adds more tools to the docker image to do this (at least something that can parse JSON). Creation of accounts is not idempotent, so I can't just run the same script every time I start the container.

I'm sure the geth community has solved this problem for their own automated testing. Please share :-)

I've read everything on the first page of this Google Search. They all have manual steps, which doesn't work for automation that Docker and automated test systems demand.

  • Do you mind if the docker image always uses the same addresses? You could allocate the Ether, and just either have the private key files already in the keystore, or programmatically add them with a plaintext private key. – Tjaden Hess Feb 21 '16 at 2:04
  • Same addresses is fine. I just use indexes in my web3.js code. However if you note in the geth documentation, creation and importation of accounts mucks with the indexes. – Paul S Feb 21 '16 at 2:38
  • btw unless you snapshot the ENTIRE state of geth, you lose your ether. genesis.json and keystore are not enough. IMHO that's a bug, because it's impossible to init geth with pre-allocated accounts. What I'm finding is you have to fire up geth, manually add the accounts, and then snapshot off (aka tarball) the entire state of geth. Then push that state into your docker container. I keep getting the feeling that automated integration testing is an unhappy stepchild in the ethereum world, I keep struggling with automation. Apologize for the gripe but I had to get that out. – Paul S Feb 21 '16 at 2:41
9

Here's the steps I used to create a Docker image that recreates a consistent test environment:

  1. Create a Docker file (see listing below) with empty geth data directory and files as noted in the Docker file. Also set up directory structure as noted in Docker file below.
  2. user docker build -t ethereum/client-go:test . to build an image
  3. start a container, login by overriding entrypoint with bash: docker run -i -t --entrypoint "/bin/bash" ethereum/client-go:test
  4. Start geth using the script noted in the dockerfile
  5. create required accounts for your testing environment (e.g. via console)
  6. edit genesis.json so that those accounts are pre-allocated with ether
  7. verify via geth console that the accounts are there, with ether allocated
  8. stop geth.
  9. user docker cp to copy off the entire contents of /root/.ethereum to your host to the directory noted in the Dockerfile below.
  10. stop and remove your container.
  11. run docker build to create a new image. The new image now has the saved off starting state that can be reproduced as needed for your test environment.
  12. I suggest using a volume for /root/.ethereum so that you don't lose data if geth restarts for some reason. See Docker documentation

The Dockerfile:

FROM ethereum/client-go

# our own custom bult geth that mines really fast
COPY geth /usr/bin/geth

# script that invokes with all those
# command line options
COPY rungeth.docker /usr/bin/rungeth

# these two files and directory of geth state belong together and must be 
# kept in sync if changes  are ever made
# Note we are taking advantage of Docker's copy-on-mount feature
COPY geth.password /root/geth.password
COPY genesis.json  /root/genesis.json
COPY ethereum /root/.ethereum

ENTRYPOINT []
ENTRYPOINT [/usr/bin/rungeth]

# use non-standard ports so don't accidently connect to real servers
# XXX Docker inheritance doesn't override, it extends the port      list...
EXPOSE 8110
EXPOSE 30310
EXPOSE 6110

I will attempt at some point to put an image on dockerhub so you don't have to do the above save run it.

Here's the script I use to build a docker container:

#!/bin/bash
docker build -t ethereum/client-go:test .

Here's the script I use to run a docker container instance.

#!/bin/bash
docker run --name geth -d -p 8110:8110  --entrypoint "usr/bin/rungeth" --volumes-from gethdb  ethereum/client-go:test

and the script that runs geth in the container:

#!/bin/bash
/usr/bin/geth --datadir /root/.ethereum --password /root/geth.password --unlock "0 1 2 3 4 5" --port 30310 --rpc --rpcaddr "0.0.0.0" --rpcport 8110 --networkid 4567890 --dev --lightkdf --nodiscover --maxpeers 0 --vmdebug --verbosity 6 --pprof --genesis /root/genesis.json --gpomin "50" --gpomax "50" --pprofport 6110 --mine --minerthreads 1 2> /tmp/geth.log
  • note the gasCost of 50 is really silly, but it's something I'm stuck with for now in my environment. I suggest not repeating my mistake. You have enough ether to keep the default gas cost in place... – Paul S Feb 23 '16 at 18:23
3

I followed the steps described in an extremely helpful answer of @Paul S. The result can be found as a docker module under https://github.com/pragmaticcoders/docker-geth-dev

Comparing to the original answer, there are some tiny changes in the command to run geth to account for the version difference (--genesis parameter removed).

I hope this will save someone time...

  • I tried this very recently and it didn't work. I've kind of given up using ethereum as a test platform. I'm using ethereum-js test-rpc. Their docker container and tests currently work. – Paul S Apr 20 '17 at 16:34
0

Eris has a geth Dockerfile with some custom scripts here:

https://github.com/eris-ltd/common/tree/master/docker/geth

It's somewhat out of date though updates are in the pipeline over the next month. The image for that Dockerfile is quay.io/eris/geth and can be run with eris services start geth if eris-cli is installed.

Subscribe to this issue to track progress.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.