Creating a Hyperledger Fabric network from scratch( v 1.4)

0
23

As there are not many tutorials available on the internet on hyperledger fabric network setup and almost all of them explain the first network or take that as a reference, so in this tutorial, I will be showing you all how to create a hyperledger fabric network from scratch! Please follow this tutorial only if you know the architecture of hyperledger fabric.

Note: This is my first article ever, so any suggestions or corrections are welcome.

Prerequisites:-

  1. basic knowledge of hyperledger fabric architecture
  2. knowledge of docker-compose
  3. docker. For installation, follow this.
  4. docker-compose. For installation, follow this.
  5. OpenSSL. It is preinstalled on most of the Linux distribution, Windows users follow this
  6. Hyperledger Fabric binaries:-
$ curl -L -o bin.tar.gz  "https://www.dropbox.com/s/1o8xwur74z176ci/bin.tar.gz?dl=1"
$ tar -xvf bin.tar.gz
$ sudo mv bin/configtxgen /usr/local/bin
$ sudo mv bin/fabric-ca-client /usr/local/bin
$ sudo rm -rf bin/

Network Overview

I will keep it as simple as possible as the main aim is to teach you the basics and starting a network from full scratch which then can be extended to create more complex networks.

The network will consist of:-

  1. 1 ca server for generating certificates by all MSP.
  2. 1 tls ca server for generating certificates used by all nodes and client for tls communication.

3. 3 raft orderers under the same organisation name “org0”.

4. 1 peer of “org1”.

5. 1 cli node to create a channel for org1.

Note: we can use the same ca server to generate both kinds of certificate but it is not a good practice

What is an MSP?

According to hyperledger fabric docs:-

Membership Service Provider (MSP) is a Hyperledger Fabric component that offers an abstraction of membership operations.
In particular, an MSP abstracts away all cryptographic mechanisms and protocols behind issuing certificates, validating certificates, and user authentication. An MSP may define its own notion of identity, and the rules by which those identities are governed (identity validation) and authenticated (signature generation and verification).

I will explain it in a more basic way. Suppose, a fabric network is running and you want to join a new peer to the network. How will the network know if the peer can join it or not?
Ans. It knows it because we passed that information during network setup in the genesis block (we can change that at runtime of course ). In the byfn tutorial, the configtx.yaml contains the organisation section:-

We define Org1 MSP here along with other organisations, basically, the main thing is MSPDir, this directory contains:- admincerts, cacerts, tlscacerts. So, if a peer wants to join the network inside Org1MSP, its certificate’s root certificate should be inside the cacerts folder of this MSPDir and its TLS certificates should be signed by a certificate which is inside tlscacerts.

Org1 section inside configtx.yaml

Step 1 ( create a project folder )

Create a folder named tutorial and make it your working directory.

$ mkdir tutorial
$ cd tutorial

Step 2 (Setting up Fabric CA server)

CA (certificate authority) is an authority which manages the lifecycle of a certificate, it is a CA who issues a certificate and revoke it.

We will generate all our orderer and peer’s certificate using fabric CA, it is provided by hyperledger fabric only, we will launch 2 fabric CA servers, one for CA and one for TLSCA.
We will use docker to launch the servers, CA server will run on port 7054 and TLSCA on port 8054.

$ nano docker-compose-ca.yaml

copy the below text in this file.

version: '2'
networks:
fabric:
services:
ca.vaibhav.com:
image: hyperledger/fabric-ca:1.4
hostname: ca.vaibhav.com
environment:
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_CA_NAME=rootca
- FABRIC_CA_SERVER_TLS_ENABLED=false
- FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/server.crt
- FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/server.key
- FABRIC_CA_SERVER_PORT=7054
ports:
- "7054:7054"
command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/server.crt --ca.keyfile /etc/hyperledger/fabric-ca-server-config/server.key -b admin:adminpw -d'
volumes:
- ./ca:/etc/hyperledger/fabric-ca-server-config
networks:
fabric:
aliases:
- ca.vaibhav.com
tlsca.vaibhav.com:
image: hyperledger/fabric-ca:1.4
hostname: tlsca.vaibhav.com
environment:
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_CA_NAME=roottlsca
- FABRIC_CA_SERVER_TLS_ENABLED=false
- FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/server.crt
- FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/server.key
- FABRIC_CA_SERVER_PORT=8054
ports:
- "8054:8054"
command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/server.crt --ca.keyfile /etc/hyperledger/fabric-ca-server-config/server.key -b admin:adminpw -d'
volumes:
- ./tlsca:/etc/hyperledger/fabric-ca-server-config
networks:
fabric:
aliases:
- tlsca.vaibhav.com

Start the servers using the docker-compose.

$ docker-compose -f docker-compose-ca.yaml up -d

After this, containers for both ca server will be up and running.
Check if they are running using below command, and proceed only if you see both the containers up and running

$ docker ps

Step 3 (generating certificates for orderers and peer)

Now we will use generated CAs to generate MSP and TLS certificates for orderers and peers.

According to fabric docs, below is the msp structure for orderers and peers

msp folder structure for orderers and peers

The four compulsory folders are:-
1. admincerts:- we need to manually make this folder and put admin’s CA cert in it, we will generate admin certificate and put it in it.
2. cacerts:- Automatically created by fabric CA while generating certs.
3. signcerts:- Automatically created by fabric CA while generating certs.
4. keystore:- Automatically created by fabric CA while generating certs.

First, we will create the org0 and org1 MSP structure.

$ mkdir -p {orderers/org0/{msp/{cacerts,tlscacerts,admincerts},orderer1,orderer2,orderer3},peers/org1/{msp/{cacerts,tlscacerts,admincerts},peer1},rootca-admin,roottlsca-admin}

we will now generate an admin certificate of CA server which will be used to register peers and orderers on the CA server, after registration the certificates for them can be generated.

$ export FABRIC_CA_HOME=./rootca-admin
$ fabric-ca-client enroll -u http://admin:adminpw@localhost:7054

Generating MSP certificates

We will generate orderers and peers certificate along with 1 admin certificate in each organisation.

$ fabric-ca-client register --id.name orderer1.org0.com --id.secret secret --id.type orderer -u http://localhost:7054
$ fabric-ca-client register --id.name orderer2.org0.com --id.secret secret --id.type orderer -u http://localhost:7054
$ fabric-ca-client register --id.name orderer3.org0.com --id.secret secret --id.type orderer -u http://localhost:7054
$ fabric-ca-client register --id.name peer1.org1.com --id.secret secret --id.type peer -u http://localhost:7054
$ fabric-ca-client register --id.name admin.org0.com --id.secret secret --id.type admin -u http://localhost:7054
$ fabric-ca-client register --id.name admin.org1.com --id.secret secret --id.type admin -u http://localhost:7054
$ export FABRIC_CA_HOME=./orderers/org0/orderer1/
$ fabric-ca-client enroll --csr.hosts "orderer1.org0.com" -u http://orderer1.org0.com:secret@localhost:7054
$ export FABRIC_CA_HOME=./orderers/org0/orderer2/
$ fabric-ca-client enroll --csr.hosts "orderer2.org0.com" -u http://orderer2.org0.com:secret@localhost:7054
$ export FABRIC_CA_HOME=./orderers/org0/orderer3/
$ fabric-ca-client enroll --csr.hosts "orderer3.org0.com" -u http://orderer3.org0.com:secret@localhost:7054
$ export FABRIC_CA_HOME=./peers/org1/peer1/
$ fabric-ca-client enroll --csr.hosts "peer1.org1.com" -u http://peer1.org1.com:secret@localhost:7054
$ export FABRIC_CA_HOME=./orderers/org0/orderer1/msp/user/
$ fabric-ca-client enroll --csr.hosts "admin.org0.com" -u http://admin.org0.com:secret@localhost:7054 -M admin
$ export FABRIC_CA_HOME=./peers/org1/peer1/msp/user/
$ fabric-ca-client enroll --csr.hosts "admin.org1.com" -u http://admin.org1.com:secret@localhost:7054 -M admin

Generating TLS certificates

This will be same as generating MSP certificates but we will use TLS-CA server instead of CA server, we will not generate admin’s tls cert as we will not be using mutual-tls for connecting the client to the network.

$ export FABRIC_CA_HOME=./roottlsca-admin
$ fabric-ca-client enroll -u http://admin:adminpw@localhost:8054
$ fabric-ca-client register --id.name orderer1.org0.com --id.secret secret --id.type orderer -u http://localhost:8054
$ fabric-ca-client register --id.name orderer2.org0.com --id.secret secret --id.type orderer -u http://localhost:8054
$ fabric-ca-client register --id.name orderer3.org0.com --id.secret secret --id.type orderer -u http://localhost:8054
$ fabric-ca-client register --id.name peer1.org1.com --id.secret secret --id.type peer -u http://localhost:8054
$ export FABRIC_CA_HOME=./orderers/org0/orderer1/
$ fabric-ca-client enroll --csr.hosts "orderer1.org0.com" -u http://orderer1.org0.com:secret@localhost:8054 -M tls
$ export FABRIC_CA_HOME=./orderers/org0/orderer2/
$ fabric-ca-client enroll --csr.hosts "orderer2.org0.com" -u http://orderer2.org0.com:secret@localhost:8054 -M tls
$ export FABRIC_CA_HOME=./orderers/org0/orderer3/
$ fabric-ca-client enroll --csr.hosts "orderer3.org0.com" -u http://orderer3.org0.com:secret@localhost:8054 -M tls
$ export FABRIC_CA_HOME=./peers/org1/peer1/
$ fabric-ca-client enroll --csr.hosts "peer1.org1.com" -u http://peer1.org1.com:secret@localhost:8054 -M tls

We will also change the name of tls private key as CA generate a random name to this and we need to reference its path later when we will create docker-compose.yaml later. So, let's change the name to “server.key”.

$ mv orderers/org0/orderer1/tls/keystore/* orderers/org0/orderer1/tls/keystore/server.key
$ mv orderers/org0/orderer2/tls/keystore/* orderers/org0/orderer2/tls/keystore/server.key
$ mv orderers/org0/orderer3/tls/keystore/* orderers/org0/orderer3/tls/keystore/server.key
$ mv peers/org1/peer1/tls/keystore/* peers/org1/peer1/tls/keystore/server.key

STEP 4 (creating MSP folder for org0 and org1)

I already explained what an MSP is and why it is important. You can learn more about MSP here.

On our network, we have 2 organisations “org0” and “org1”.
Generating msp folder for both orgs.

$ cp ca/server.crt orderers/org0/msp/cacerts
$ cp ca/server.crt peers/org1/msp/cacerts
$ cp tlsca/server.crt orderers/org0/msp/tlscacerts
$ cp tlsca/server.crt peers/org1/msp/tlscacerts
$ cp orderers/org0/orderer1/msp/user/admin/signcerts/cert.pem orderers/org0/msp/admincerts/
$ cp peers/org1/peer1/msp/user/admin/signcerts/cert.pem peers/org1/msp/admincerts/
$ mkdir orderers/org0/orderer1/msp/admincerts orderers/org0/orderer2/msp/admincerts orderers/org0/orderer3/msp/admincerts peers/org1/peer1/msp/admincerts
$ cp orderers/org0/orderer1/msp/user/admin/signcerts/cert.pem orderers/org0/orderer1/msp/admincerts
$ cp orderers/org0/orderer1/msp/user/admin/signcerts/cert.pem orderers/org0/orderer2/msp/admincerts
$ cp orderers/org0/orderer1/msp/user/admin/signcerts/cert.pem orderers/org0/orderer3/msp/admincerts
$ cp peers/org1/peer1/msp/user/admin/signcerts/cert.pem peers/org1/peer1/msp/admincerts
$ mkdir peers/org1/peer1/msp/user/admin/admincerts
$ cp peers/org1/peer1/msp/user/admin/signcerts/cert.pem peers/org1/peer1/msp/user/admin/admincerts/

STEP 5 (generating genesis block and a channel)

For starting the orderers, a genesis block is important which contains the information of the network, it contains the information about the MSPs it recognises, organisations which are part of these MSPs will be able to participate in the network. We will provide the msp folders we just created in the previous step to generate the genesis block.
A sample channel will also be created just to join it and to check if the whole network works correctly.
create a new file:-

$ nano configtx.yaml

paste the following in this file:-

Organizations:
- &org0
Name: org0
# ID to load the MSP definition as
ID: org0
# MSPDir is the filesystem path which contains the MSP configuration
MSPDir: orderers/org0/msp
Policies:
Readers:
Type: Signature
Rule: "OR('org0.member')"
Writers:
Type: Signature
Rule: "OR('org0.member')"
Admins:
Type: Signature
Rule: "OR('org0.admin')"
- &org1
# DefaultOrg defines the organization which is used in the sampleconfig
# of the fabric.git development environment
Name: org1
# ID to load the MSP definition as
ID: org1
MSPDir: peers/org1/msp
Policies:
Readers:
Type: Signature
Rule: "OR('org1.admin', 'org1.peer', 'org1.client')"
Writers:
Type: Signature
Rule: "OR('org1.admin', 'org1.client')"
Admins:
Type: Signature
Rule: "OR('org1.admin')"
Capabilities:
Channel: &ChannelCapabilities
V1_4_2: true
# Orderer capabilities apply only to the orderers, and may be safely
# used with prior release peers.
# Set the value of the capability to true to require it.
Orderer: &OrdererCapabilities
V1_4_2: true
# Application capabilities apply only to the peer network, and may be safely
# used with prior release orderers.
# Set the value of the capability to true to require it.
Application: &ApplicationCapabilities
V1_4_2: true
Application: &ApplicationDefaults
# Organizations is the list of orgs which are defined as participants on
# the application side of the network
Organizations:
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
LifecycleEndorsement:
Type: ImplicitMeta
Rule: "MAJORITY Endorsement"
Endorsement:
Type: ImplicitMeta
Rule: "MAJORITY Endorsement"
Capabilities:
<<: *ApplicationCapabilities
Orderer: &OrdererDefaults
# Orderer Type: The orderer implementation to start
OrdererType: etcdraft
EtcdRaft:
Consenters:
- Host: orderer1.org0.com
Port: 7050
ClientTLSCert: orderers/org0/orderer1/tls/signcerts/cert.pem
ServerTLSCert: orderers/org0/orderer1/tls/signcerts/cert.pem
- Host: orderer2.org0.com
Port: 7050
ClientTLSCert: orderers/org0/orderer2/tls/signcerts/cert.pem
ServerTLSCert: orderers/org0/orderer2/tls/signcerts/cert.pem
- Host: orderer3.org0.com
Port: 7050
ClientTLSCert: orderers/org0/orderer3/tls/signcerts/cert.pem
ServerTLSCert: orderers/org0/orderer3/tls/signcerts/cert.pem
# Batch Timeout: The amount of time to wait before creating a batch
BatchTimeout: 2s
# Batch Size: Controls the number of messages batched into a block
BatchSize:
# Max Message Count: The maximum number of messages to permit in a batch
MaxMessageCount: 10
# Absolute Max Bytes: The absolute maximum number of bytes allowed for
# the serialized messages in a batch.
AbsoluteMaxBytes: 99 MB
# Preferred Max Bytes: The preferred maximum number of bytes allowed for
# the serialized messages in a batch. A message larger than the preferred
# max bytes will result in a batch larger than preferred max bytes.
PreferredMaxBytes: 512 KB
# Organizations is the list of orgs which are defined as participants on
# the orderer side of the network
Organizations:
# Policies defines the set of policies at this level of the config tree
# For Orderer policies, their canonical path is
# /Channel/Orderer/<PolicyName>
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
# BlockValidation specifies what signatures must be included in the block
# from the orderer for the peer to validate it.
BlockValidation:
Type: ImplicitMeta
Rule: "ANY Writers"
Channel: &ChannelDefaults
# Policies defines the set of policies at this level of the config tree
# For Channel policies, their canonical path is
# /Channel/<PolicyName>
Policies:
# Who may invoke the 'Deliver' API
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
# Who may invoke the 'Broadcast' API
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
# By default, who may modify elements at this config level
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
# Capabilities describes the channel level capabilities, see the
# dedicated Capabilities section elsewhere in this file for a full
# description
Capabilities:
<<: *ChannelCapabilities
################################################################################
#
# Profile
#
# - Different configuration profiles may be encoded here to be specified
# as parameters to the configtxgen tool
#
################################################################################
Profiles:
default:
Consortium: SampleConsortium
<<: *ChannelDefaults
Application:
<<: *ApplicationDefaults
Organizations:
- *org1
Capabilities:
<<: *ApplicationCapabilities
genesis:
<<: *ChannelDefaults
Capabilities:
<<: *ChannelCapabilities
Orderer:
<<: *OrdererDefaults
OrdererType: etcdraft
Addresses:
- orderer1.org0.com:7050
- orderer2.org0.com:7050
- orderer3.org0.com:7050
Organizations:
- *org0
Capabilities:
<<: *OrdererCapabilities
Application:
<<: *ApplicationDefaults
Organizations:
- <<: *org0
Consortiums:
SampleConsortium:
Organizations:
- *org1

Generate genesis block and default channel using configtxgen binary.

$ mkdir channel-artifacts
$ configtxgen -profile genesis -outputBlock channel-artifacts/genesis.block
$ configtxgen -profile default -outputCreateChannelTx channel-artifacts/default.tx -channelID default

Now we have genesis block and transaction for creating a channel we can go forward to bring up our network.

STEP 6 (bringing up the network)

First, we will create a docker-compose.yaml file.

$ nano docker-compose.yaml

copy paste the below content in this file.

version: '2'
volumes:
orderer1.org0.com:
orderer2.org0.com:
orderer3.org0.com:
peer1.org1.com:
networks:
fabric:
services:
orderer1.org0.com:
hostname: orderer1.org0.com
image: hyperledger/fabric-orderer:1.4.4
environment:
- FABRIC_LOGGING_SPEC=DEBUG
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
- ORDERER_GENERAL_LOCALMSPID=org0
- ORDERER_GENERAL_TLS_ENABLED=true
- ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/keystore/server.key
- ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/signcerts/cert.pem
- ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/cacerts/localhost-8054.pem]
- ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/signcerts/cert.pem
- ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/keystore/server.key
- ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/cacerts/localhost-8054.pem]
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: orderer
volumes:
- ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ./orderers/org0/orderer1/msp:/var/hyperledger/orderer/msp
- ./orderers/org0/orderer1/tls/:/var/hyperledger/orderer/tls
- orderer1.org0.com:/var/hyperledger/production/orderer
networks:
fabric:
aliases:
- orderer1.org0.com
orderer2.org0.com:
hostname: orderer2.org0.com
image: hyperledger/fabric-orderer:1.4.4
environment:
- FABRIC_LOGGING_SPEC=DEBUG
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
- ORDERER_GENERAL_LOCALMSPID=org0
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
- ORDERER_GENERAL_TLS_ENABLED=true
- ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/keystore/server.key
- ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/signcerts/cert.pem
- ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/cacerts/localhost-8054.pem]
- ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/signcerts/cert.pem
- ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/keystore/server.key
- ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/cacerts/localhost-8054.pem]
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: orderer
volumes:
- ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ./orderers/org0/orderer2/msp:/var/hyperledger/orderer/msp
- ./orderers/org0/orderer2/tls/:/var/hyperledger/orderer/tls
- orderer2.org0.com:/var/hyperledger/production/orderer
networks:
fabric:
aliases:
- orderer2.org0.com
orderer3.org0.com:
hostname: orderer3.org0.com
image: hyperledger/fabric-orderer:1.4.4
environment:
- FABRIC_LOGGING_SPEC=DEBUG
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
- ORDERER_GENERAL_LOCALMSPID=org0
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
- ORDERER_GENERAL_TLS_ENABLED=true
- ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/keystore/server.key
- ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/signcerts/cert.pem
- ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/cacerts/localhost-8054.pem]
- ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/signcerts/cert.pem
- ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/keystore/server.key
- ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/cacerts/localhost-8054.pem]
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: orderer
volumes:
- ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ./orderers/org0/orderer3/msp:/var/hyperledger/orderer/msp
- ./orderers/org0/orderer3/tls/:/var/hyperledger/orderer/tls
- orderer3.org0.com:/var/hyperledger/production/orderer
networks:
fabric:
aliases:
- orderer3.org0.com
peer1.org1.com:
container_name: peer1.org1.com
hostname: peer1.org1.com
image: hyperledger/fabric-peer:1.4.4
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_GOSSIP_USELEADERELECTION=false
- CORE_PEER_GOSSIP_ORGLEADER=true
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/signcerts/cert.pem
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/keystore/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/cacerts/localhost-8054.pem
# Allow more time for chaincode container to build on install.
- CORE_CHAINCODE_EXECUTETIMEOUT=300s
- CORE_PEER_ID=peer1.org1.com
- CORE_PEER_ADDRESS=peer1.org1.com:7051
- CORE_PEER_LISTENADDRESS=0.0.0.0:7051
- CORE_PEER_CHAINCODEADDRESS=peer1.org1.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.com:7051
- CORE_PEER_LOCALMSPID=org1
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
volumes:
- /var/run/:/host/var/run/
- ./peers/org1/peer1/msp:/etc/hyperledger/fabric/msp
- ./peers/org1/peer1/tls:/etc/hyperledger/fabric/tls
- peer1.org1.com:/var/hyperledger/production
networks:
fabric:
aliases:
- peer1.org1.com

cli:
container_name: cli
image: hyperledger/fabric-tools:1.4.4
tty: true
stdin_open: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
#- FABRIC_LOGGING_SPEC=DEBUG
- FABRIC_LOGGING_SPEC=INFO
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer1.org1.com:7051
- CORE_PEER_LOCALMSPID=org1
- CORE_PEER_TLS_ENABLED=true
# - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
# - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/org1/msp/tlscacerts/server.crt
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/org1/peer1/msp/user/admin
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: /bin/bash
volumes:
- /var/run/:/host/var/run/
- ./peers/org1/:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/org1/
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
networks:
fabric:

Bring up the network

$ docker-compose up -d

Check if all the containers and up and running

$ docker ps

if you see the containers running, congratulation our network is running successfully.

STEP 7 (creating and joining channel)

Now, let's create a channel and join our only peer on it.
First, let’s bash into out cli container

$ docker exec -it cli bash

inside the container, run the following commands to create and join the peer to channel respectively.

$ peer channel create -f channel-artifacts/default.tx -c default -o orderer1.org0.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/org1/msp/tlscacerts/server.crt
$ peer channel join -b default.block -o orderer1.org0.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/org1/msp/tlscacerts/server.crt

Check if peer joined the channel or not

$ peer channel list

You should see a channel named default.

Thanks for following the tutorial, you just created a simple fabric network on your own. :)

Get Best Software Deals Directly In Your Inbox

Creating a Hyperledger Fabric network from scratch( v 1.4) was originally published in Coinmonks on Medium, where people are continuing the conversation by highlighting and responding to this story.