How to Set Up an Ethereum Private Network Using Docker

·

Setting up an Ethereum private network is a powerful way to test smart contracts, decentralized applications (dApps), and blockchain interactions in a controlled environment. Docker simplifies this process by offering lightweight, reproducible containers that eliminate many system-level dependencies. This guide walks you through building a fully functional Ethereum private chain using Docker — ideal for developers, testers, and blockchain enthusiasts.

Whether you're preparing for a development sprint or learning the fundamentals of Ethereum node management, this step-by-step tutorial ensures clarity, consistency, and scalability.


Why Use Docker for Ethereum Development?

Docker has become the go-to tool for modern blockchain development due to its portability, isolation, and ease of configuration. Compared to traditional virtual machines, Docker containers boot faster, consume fewer resources, and can be version-controlled alongside your codebase.

By containerizing your Ethereum nodes:

Core keywords naturally integrated: Ethereum private network, Docker Ethereum setup, build Ethereum chain, private blockchain with Docker, Geth Docker configuration, Ethereum development environment.


Step 1: Install Docker on Ubuntu

We’ll use Ubuntu 18.04 LTS (Bionic) as the host OS. While newer versions are available, the principles apply universally.

👉 Learn how containerization boosts blockchain development efficiency.

Download and Install Docker .deb Packages

Instead of using APT repositories, we’ll install Docker via .deb packages for simplicity:

  1. Visit:
    https://download.docker.com/linux/ubuntu/dists/bionic/pool/stable/amd64/
  2. Download these three files:

    • containerd.io_1.2.4-1_amd64.deb
    • docker-ce-cli_18.09.3_3-0_ubuntu-bionic_amd64.deb
    • docker-ce_18.09.3_3-0_ubuntu-bionic_amd64.deb
  3. Install them in order:
sudo dpkg -i docker-ce-cli_18.09.3_3-0_ubuntu-bionic_amd64.deb
sudo dpkg -i containerd.io_1.2.4-1_amd64.deb
sudo dpkg -i docker-ce_18.09.3_3-0_ubuntu-bionic_amd64.deb

Verify Installation

Run the classic test:

sudo docker run hello-world

If successful, you’ll see a confirmation message indicating Docker is working correctly.

Note: To update Docker later, simply download new .deb packages and repeat the installation process.

Step 2: Pull the Geth Docker Image

The official Ethereum Go client (geth) is available on Docker Hub. Pull it with:

sudo docker pull ethereum/client-go

This fetches the latest version of geth. Confirm it’s downloaded:

sudo docker image ls

You should see:

REPOSITORY             TAG       IMAGE ID        CREATED        SIZE
ethereum/client-go     latest    f376688623dc    3 hours ago    42.7MB
hello-world            latest    fce289e99eb9    2 months ago   1.84kB

Try running an interactive shell inside the container:

sudo docker run -it --rm -v /workspace:/workspace --entrypoint /bin/sh ethereum/client-go

Exit with exit when done.


Step 3: Create a Custom Docker Network

For secure inter-container communication, create a dedicated bridge network:

sudo docker network create -d bridge --subnet=172.18.0.0/16 ethnet

Verify creation:

sudo docker network ls

Look for ethnet in the list. This isolated network allows containers to communicate via static IPs without exposing services to the host or external networks.


Step 4: Configure the Ethereum Private Chain

Now we’ll prepare the genesis block and accounts.

Prepare Directory Structure

On your host machine, create:

mkdir -p /workspace/dapp/{miner,data}
touch /workspace/dapp/genesis.json

Create Ethereum Accounts

Start a temporary container:

sudo docker run -it --rm --network ethnet --ip 172.18.0.50 -v /workspace:/workspace --entrypoint /bin/sh ethereum/client-go

Inside the container:

cd /workspace/dapp/miner
geth -datadir ./data account new

Enter a password twice to generate a new account (e.g., 0x79b4...df58). Repeat to create more if needed.

Record these addresses — they’ll receive initial funds in the genesis block.

Define the Genesis Block

Edit /workspace/dapp/genesis.json:

{
  "config": {
    "chainId": 88,
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0
  },
  "alloc": {
    "0x79b43b2196723fff1485999aba45fda3e8b4df58": { "balance": "100000000000000000000" },
    "0x1ae06a8afd157b97f072a97f5c62fa836f5ef597": { "balance": "1000000000000000000" },
    "0xa75b4db0c6bfa416d544e3316d47af0fb01eb828": { "balance": "1000000000000000000" },
    "0x1a037d8e8e16a4c88e17c3d5f29ee26a9f5b2c85": { "balance": "1000000000000000000" }
  },
  "coinbase": "0x0000000000000000000000000000000000000000",
  "difficulty": "0x400",
  "extraData": "",
  "gasLimit": "0x2fefd8",
  "nonce": "0x000000000000000",
  "mixhash": "0x0...",
  "parentHash": "0x...",
  "timestamp": "0x..."
}

Key fields:

  • chainId: Identifies your private chain (set to 88).
  • alloc: Pre-funds accounts at launch.
  • difficulty: Low value enables fast mining.
  • gasLimit: High limit avoids out-of-gas errors during testing.

Exit the container — files persist on the host due to volume mounting.


Step 5: Launch the Miner Node

We’ll now build a persistent mining node.

Create Initialization Scripts

/workspace/dapp/init.sh (initializes chain):

#!/bin/sh
geth -datadir ~/data/ init /workspace/dapp/genesis.json
if [ $# -lt 1 ]; then
  exec "/bin/sh"
else
  exec /bin/sh -c "$@"
fi

/workspace/dapp/mine.sh (starts mining):

#!/bin/sh
cp -r /workspace/dapp/miner/data/keystore/* ~/data/keystore/
geth -datadir ~/data/ \
  --networkid 88 \
  --rpc \
  --rpcaddr "172.18.0.51" \
  --rpcapi admin,eth,miner,web3,personal,net,txpool \
  --unlock "your-mining-address" \
  --etherbase "your-mining-address" \
  console

Replace your-mining-address with the primary account (e.g., first one created).

Make scripts executable:

sudo chmod +x /workspace/dapp/init.sh /workspace/dapp/mine.sh

Launch the miner container:

sudo docker run -it \
  --name=miner \
  --network ethnet \
  --ip 172.18.5.5 \
  --hostname node \
  -v /workspace:/workspace \
  --entrypoint /workspace/dapp/init.sh \
  ethereum/client-go \
  /workspace/dapp/mine.sh

This creates a long-running node initialized with your custom blockchain.

👉 Discover how blockchain testnets accelerate dApp deployment.


Step 6: Add Additional Nodes

Repeat similar steps for non-mining peers.

Create /workspace/dapp/node.sh:

#!/bin/sh
cp -r /workspace/dapp/miner/data/keystore/* ~/data/keystore/
geth -datadir ~/data/ --networkid 88 console

Run a new node:

sudo docker run -it \
  --name=node1 \
  --network ethnet \
  --ip 172.18.5.6 \
  --hostname node1 \
  -v /workspace:/workspace \
  --entrypoint /workspace/dapp/init.sh \
  ethereum/client-go \
  /workspace/dapp/node.sh

Step 7: Connect Nodes

In the miner console:

> admin.nodeInfo.enode
"enode://[email protected]:3...3"

Copy the full URL (replace 127.… with 172.…). In node1, run:

> admin.addPeer("enode://...")
true

Check connections:

> admin.peers.length
1

Your two-node private Ethereum network is now live!


Managing Containers

Use these commands for lifecycle control:


Frequently Asked Questions (FAQ)

Q: Can I run this on macOS or Windows?

Yes! Docker Desktop supports both platforms. The commands remain identical — only path mounts may differ slightly.

Q: What’s the purpose of the genesis.json file?

It defines the initial state of your blockchain, including chain ID, difficulty, gas limits, and pre-funded accounts. Without it, each node would start with default public chain settings.

Q: Why do we copy keystore files into ~/data?

Geth expects wallet keys in its data directory. Since /workspace is a mounted volume not managed by Linux filesystem permissions, copying ensures proper access and avoids runtime errors.

Q: How do I deploy a smart contract on this network?

Once mining starts, unlock your account and use personal.sendTransaction() or connect Remix IDE via HTTP RPC at http://172.18.5.5:8545.

Q: Is this suitable for production?

No. This setup is strictly for local development and testing. For production, consider permissioned consensus models like Proof-of-Authority (Clique) and hardened security practices.

Q: How can I automate multi-node deployment?

Use Docker Compose to define services, networks, and volumes in a single docker-compose.yml, enabling one-command cluster startup.


With your private Ethereum network running in Docker, you’re ready to explore smart contract development, wallet integration, and consensus mechanics — all in a safe, repeatable environment.