Using a Docker container to run Bitcoin in regtest mode

One of the early activities when getting started with Bitcoin programming is configuring the development environment with a test blockchain. This article will step through the basics of using a Docker container in Ubuntu to run Bitcoin’s bitcoind in regtest mode.

  • Bitcoin’s Regtest mode is summarised nicely in the Bitcoin documentation Developer Examples:

    "Bitcoin Core’s regression test mode (regtest mode) lets you instantly create a brand-new private block chain with the same basic rules as testnet — but one major difference: you choose when to create new blocks, so you have complete control over the environment."

  • Docker is a software container technology. Find out more at the official site: What is Docker

The configuration described in this article is a simplified example based on the excellent bitcoin-testnet-box by Sean Lavine. My environment for these steps is Ubuntu 16 running on VirtualBox in Windows 10 x64.

Install Docker

There are a couple of different versions of Docker. I’ll be using Docker CE for these steps.

Follow the steps in the Docker docs Get Docker CE for Ubuntu to install from the repository. The basic commands are shown here, but I encourage you to read and follow the documentation.

sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

I’m running 64 bit architecture - for this next command, make sure to refer to the Docker docs if your architecture differs:

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable

Lastly, install Docker CE:

sudo apt-get update
sudo apt-get install docker-ce

Again, I’ll urge you to refer to the official Docker installation guide. There are additional steps to help verify that Docker is installed correctly.

Create the bitcoin.conf file

Next, define the bitcoin.conf file to be used by bitcoind which will run in the Docker container.

  1. First create a new directory and cd into it. I’ve named my directory docker-bitcoind

    mkdir docker-bitcoind
    cd docker-bitcoind
    
  2. Create a new directory to store the Bitcoin node configuration and cd into it:

    mkdir node
    cd node
    
  3. Create a new file bitcoin.conf and open for editing:

    vi bitcoin.conf
    
  4. Paste the below, or define your own configuration.

    regtest=1
    dnsseed=0
    upnp=0
    
    port=12000
    rpcport=12001
    
    server=1
    
    rpcallowip=0.0.0.0/0
    
    rpcuser=someuser
    rpcpassword=somepass
    

    To learn more about the bitcoin.conf file refer to the Bitcoin Developer Examples: Regtest mode. The Bitcoin Wiki also has a reference for the various commands available on its Running Bitcoin page.

  5. Save the changes to bitcoin.conf

Build a Docker container

Now we’re ready to build a Docker container, which is where bitcoind will run. The first step is to define the Dockerfile which instructs how the Docker image should be built. Refer to the official Dockerfile reference for help with this part.

  1. In the terminal window cd .. back into the top directory created earlier (for me it is docker-bitcoind).

  2. Create a new file Dockerfile and open for editing:

    vi Dockerfile
    

    We’ll enter the contents of Dockerfile over the next few steps. I’ve added some comments (lines starting with “#”) to help make it clear what each instruction does, but again I encourage you to refer to the official Dockerfile reference.

  3. The first instruction is usually the FROM instruction:

    # Dockerfile must start with a FROM instruction
    # FROM instruction specifies the Base Image from which you are building
    # FROM <image>[:<tag>]
    FROM ubuntu:16.04
    
  4. Next, the RUN instruction is used to include Bitcoin on top of the base Ubuntu image. These commands (minus the RUN) are from the Bitcoin installation documentation Running A Full Node.

    Paste the below into the Dockerfile after the FROM instruction:

    # Install bitcoind from PPA
    RUN apt-get update
    RUN apt-get install --yes software-properties-common
    RUN add-apt-repository --yes ppa:bitcoin/bitcoin
    RUN apt-get update
    
    # install bitcoind (from PPA) and make
    RUN apt-get install --yes bitcoind
    
  5. Next the ADD instruction will copy the bitcoin.conf file to container directory /home/bitcoind-testnet. We’ll also set this location as the current working directory:

    # copy bitcoin.conf
    ADD . /home/bitcoind-testnet
        
    # WORKDIR sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow
    WORKDIR /home/bitcoind-testnet
    
  6. Next, expose the bitcoind rpc port so it can be connected to from outside the Docker container. Make sure to specify the same port as you used above in the bitcoin.conf parameter rpcport. I’m using port 12001:

    # EXPOSE rpc port for the node to allow outside container access
    EXPOSE 12001
    
  7. Finally, use CMD to start a bash shell

    # There can only be one CMD instruction in a Dockerfile
    # CMD provides defaults for an executing container
    # Drop user into bash shell by default
    CMD ["/bin/bash"]
    
  8. Save the changes to Dockerfile

Checkpoint

At this point you should have the following:

  • Docker installed in Ubuntu
  • a new directory created (e.g /docker-bitcoind) containing the following
    • Dockerfile
    • /node/bitcoin.conf

Build the Docker image and run the container

This section outlines how to build the image and run the container. I won’t try to explain how to use Docker; mainly because I’m not an expert, but also because the Docker docs are an excellent resource. Check out the Docker doc Get Started.

Note: You’ll need to use sudo ahead of these Docker commands, unless you’ve completed these Post-installation steps for Linux.

  1. Make sure you are working in the directory containing the Dockerfile. For me it is the /docker-bitcoind directory.

  2. Use Docker’s build command to build the image.

    • The -t flag sets a name for the image.
    • The . tells Docker to looker for Dockerfile in the current directory
    docker build -t bitcoind-test .
    

    The first time you build the image may be slow, especially if the Ubuntu image needs to be downloaded. Subsequent builds of this image should be a lot faster (the image needs to be built after any change to the Dockerfile, but Docker’s build caching will only re-build instructions occurring after an ADD instruction. See this StackOverflow question: Docker updating image along when dockerfile changes ).

  3. When the build is finished you can list the built images:

    docker images
    
  4. And run the image in a container:

    • -it is required for interactive processes (like a bash shell)
    • -p maps Ubuntu port 5000 to the container’s exposed port 12001, which is where Bitcoin rpc will be listening

    Refer to the Docker Docs run reference for all the details.

    docker run -it -p 5000:12001 bitcoind-test
    

    Note that docker run creates a new container each time. To have Docker clean up the container when it exits, use the --rm flag. For example:

    docker run -it -p --rm 5000:12001 bitcoind-test
    

    Read more about the Clean up command in the Docker Docs: .

  5. If everything has worked Docker should present a bash shell working within the /home/bitcoind-testnet directory that looks similar to this:

    root@326269a2a723:/home/bitcoind-testnet#

  6. Start Bitcoin in headless mode, specifying the datadir as the node directory (which contains the bitcoin.conf created earlier). Both the node directory and the bitcoin.conf file were copied to the container by the ADD instruction in the Dockerfile, so they will be present in the current working directory:

    bitcoind -datadir=node -daemon
    

    You should see the output Bitcoin server starting before being returned to the prompt.

  7. Check the Bitcoin node details with getinfo:

    bitcoin-cli -datadir=node getinfo
    
  8. If you want to do anything useful with this node, you’ll need to generate at least the first 101 blocks (read why here). We won’t be doing anything too useful with the node for now, so I won’t go into that detail, however you can check the link for the answers, or run this command:

    bitcoin-cli -datadir=node generate 101
    

Connect to Bitcoin from outside Docker

From outside the Docker container we can use curl to confirm connectivity to the Bitcoin node. When the container was started using docker run... we used the -p flag to map our port 5000 to the container port 12001, which is where bitcoind rcp is listening. So now curl should be able to connect to bitcoind on Ubuntu’s local port 5000 and issue the getinfo command.

  1. Leave open the terminal window with the Docker container and the bitcoind daemon running.

  2. Open a second terminal window and enter the following:

    curl --user someuser:somepass --data '{"method": "getinfo"}' http://127.0.0.1:5000
    

    This should return the same result as the getinfo command issued earlier within the Docker container.

    Also refer to this StackExchange question: Can I use curl to call getInfo from a the Bitcoin server?.

  3. When you’re finished, bitcoind can be stopped by typing the below command into the first terminal window (the one running the Docker container):

    bitcoin-cli -datadir=node stop
    
  4. And exit the Docker container:

    exit
    

Wrapping up

I hope this article has served as an initial introduction to running Bitcoin in regtest mode within a Docker container. For a more advanced example please have a look at the excellent bitcoin-testnet-box available on GitHub. A good place to start for beginners is the Dockerfile, the bitcoin.conf files, and the Makefile.