Your first Hyperledger Fabric network
Tags: hyperledger, fabric, blockchain
Published: 2018-06-22 19:17:26

---
title: Your first Hyperledger Fabric network
published: true
description: We build our very first network from scratch.
tags: hyperledger, fabric, blockchain
cover_image: https://thepracticaldev.s3.amazonaws.com/i/ltwm8keifo6r9v9fi20j.png
---

## Introduction

In this article, we will build a simple blockchain network with Hyperledger Fabric. Fabric allows us to build a private blockchain. There are no cryptocurrencies involved. After this, you will have a decent understanding of the different parts needed to start your own private blockchain. In this example, our network will be composed of 3 organisations. Each organisation will have two peers each.

## Pre-requisites

- You must have **docker** and **docker-compose** installed. Refer to the <a href='https://docs.docker.com/install/'>Docker install page</a>. To make sure you have Docker installed, you can run `docker -v` in your terminal. This should return something like: 

```
Docker version 18.03.1-ce, build 9ee9f40
```

- Fabric already gives us some network samples to play around and explore. To get them, open a terminal window and run:
`git clone -b master https://github.com/hyperledger/fabric-samples.git`

This will create a `fabric-samples` folder with some fabric samples inside. There are a lot of useful informations in these folders, but we won't explore them here.

- Next, we will download the platform specific binaries. This will extract some binaries that we will need later. Move into the `fabric-samples` folder with `cd fabric-samples` and run :

```
curl -sSL https://goo.gl/6wtTN5 | bash -s 1.1.0
```

This will create a `bin` folder in your `fabric-samples` folder.


That's it! Now, we are ready to build our new network from scratch!


## Cryptogen

First, inside your `fabric-samples` folder, create a new folder called `cool-network`, this is where all the magic will happen. Then, because we will use the 1.1.0 version, let's do a `git checkout v1.1.0` to make sure there are no mistakes because of the version.

### Generate our certificates and keys

Our first step will be to generate all the certificates and keys for the organisations and peers inside them. In our network, everyone will have to prove who they claim to be. The certificates we will generate will prove their identities and allow them to sign and verify transactions. Transactions will be signed by an entity's private key and verified by a public one.

To generate these materials, we will use the **cryptogen** tool. We got this tool by downloading the platform-specific binaries ( you have a file called cryptogen in the `bin` folder ). The **cryptogen** tool consumes a `crypto-config.yaml` file. So, inside our `cool-network` folder, go ahead and create this file. You can copy and paste the following inside and I'll explain what is going on:

```yaml
OrdererOrgs:
  - Name: OrderingService
    Domain: cool-network.com
    Specs:
      - Hostname: orderer

PeerOrgs:
  - Name: Microsoft
    Domain: microsoft.cool-network.com
    EnableNodeOUs: true
    Template:
      Count: 2
    Users: 
      Count: 1
  - Name: Apple
    Domain: apple.cool-network.com
    EnableNodeOUs: true
    Template:
      Count: 2
    Users: 
      Count: 1
  - Name: IBM
    Domain: ibm.cool-network.com
    EnableNodeOUs: true
    Template:
      Count: 2
    Users:
      Count: 1
```

There are two parts in this file: *OrdererOrgs* and *PeerOrgs*. Before we study this file we must explain what *Orderers* are.

In Fabric, the Ordering Service is a collection of network entities. The orderers make sure that the transactions are dealt with in the right order ( first-come-first-serve ). The orderer is then responsible for packaging transactions into blocks.

So, what do we have in this file? We first define the Orderer Service. We give it a name, a domain and a hostname under the specs key. The naming convention goes like this: {Hostname}.{Domain}. So, our orderer will be named *orderer.cool-network.com*.

Next, we define our 3 organisations. We define their names and domains. The key *EnableNodeOUs* is set to true. This is outside the scope of this article but setting this to true will allow us to define additional policies for the network members. Finally, we have a Count key set to 1 for each organisation. This means that there will be two peers per organisation. Why? Because each organisation will have an Admin by default. So, the number of peers in an organisation will be [Count + 1].

### Running the cryptogen tool

Everything is now in place for us to generate our certificates and keys. Make sure you are inside the `cool-network` folder and run:

`../bin/cryptogen generate --config crypto-config.yaml --output=crypto-config`

The *cryptogen* tool has a generate method that will do the job for us. We provide a config file and an output folder. You should see the following in your terminal:

```
microsoft.cool-network.com
apple.cool-network.com
ibm.cool-network.com
```

And a `crypto-config` file just appeared in your `cool-network` folder! This is where all the certificates and keys for the orderers, organisations and peers are stored.

## Configtxgen

Next, we will use the configtxgen tool. This tool will do three important things:

- create the orderer genesis block
- create the channel configuration transaction
- create the anchor peer transactions, one for each peer organisation

**Channel**: In Fabric, you have the possibility to create channels. These channels allow organisations to create private sub-networks inside the greater network. In our case, we could imagine a channel that only Microsoft and IBM would be a part of, and another that only Apple and IBM would be a part of.

**Anchor peer**: An anchor peer on a channel is a public peer that all others peers can discover and communicate with. Each organisation on a channel has an anchor peer.

### Creating the file

The configtxgen tool consumes a *configtx.yaml* file. Create it and copy-paste the following:

```yaml
# Profiles

Profiles:
    OrdererGenesis:
      Capabilities:
        <<: *ChannelCapabilities
      Orderer:
        <<: *OrdererDefaults
        Organizations:
          - *OrdererOrg
        Capabilities:
          <<: *OrdererCapabilities
      Consortiums:
        MyFirstConsortium:
          Organizations:
            - *Microsoft
            - *IBM
            - *Apple
    channelthreeorgs:
      Consortium: MyFirstConsortium
      Application:
        <<: *ApplicationDefaults
        Organizations:
          - *Microsoft
          - *IBM
          - *Apple
        Capabilities:
          <<: *ApplicationCapabilities


# Organizations

Organizations:

  - &OrdererOrg
    Name: OrderingService
    ID: OrdererMSP
    MSPDir: crypto-config/ordererOrganizations/cool-network.com/msp
  
  - &Microsoft
    Name: MicrosoftMSP
    ID: MicrosoftMSP
    MSPDir: crypto-config/peerOrganizations/microsoft.cool-network.com/msp
    AnchorPeers:
      - Host: peer0.microsoft.cool-network.com
        Port: 7051
  
  - &Apple
    Name: AppleMSP
    ID: AppleMSP
    MSPDir: crypto-config/peerOrganizations/apple.cool-network.com/msp
    AnchorPeers:
      - Host: peer0.apple.cool-network.com
        Port: 7051

  - &IBM
    Name: IBMMSP
    ID: IBMMSP
    MSPDir: crypto-config/peerOrganizations/ibm.cool-network.com/msp
    AnchorPeers:
      - Host: peer0.ibm.cool-network.com
        Port: 7051
    
# Orderer

Orderer: &OrdererDefaults

  OrdererType: solo
  Addresses: 
    - orderer.cool-network.com:7050
  BatchTimeout: 2s
  BatchSize:
    MaxMessageCount: 10
    AbsoluteMaxBytes: 99 MB
    PreferredMaxBytes: 512 KB
  Kafka:
    Brokers: 
      - 127.0.0.1:9092
  
  Organizations:

# Application

Application: &ApplicationDefaults
  
  Organizations:

# Capabilities

Capabilities:
    Global: &ChannelCapabilities
        V1_1: true
    Orderer: &OrdererCapabilities
        V1_1: true
    Application: &ApplicationCapabilities
        V1_1: true

```

There are a few different sections here. The most important Profiles and Organizations for now. In Profiles, we describe the orderer genesis block, our channel ( with the three organisations ) and we also defined a Consortium. Pay attention to the headers ( OrdererGenesis and channelthreeorgs) as they will be used later. In Organizations, we specify where are stored the certificates for each organisation. We just created these certificates with *cryptogen*. We also specify the anchor peers for each organisation. ( MSP means Membership Service Provider )

The *ordererType* key in the *Orderer* section is set to *solo*. Because we are in a development environment, we have only one orderer. If we were in a production environment, we would define several orderers in case one or several of them were faulty. For now, this will do just fine.

### Running configtxgen

First, create a folder called `channel-artifacts` to hold our artifacts.

We can now run the *configtxgen* tool. Run the following command: 

```
../bin/configtxgen -profile OrdererGenesis -outputBlock ./channel-artifacts/genesis.block
```

Notice the *OrdererGenesis* header we specified earlier. This will create a *genesis.block* file for our orderer genesis block. . You should see the following in your terminal:

```
2018-06-22 18:39:13.218 CEST [common/tools/configtxgen] main -> INFO 001 Loading configuration
2018-06-22 18:39:13.251 CEST [msp] getMspConfig -> INFO 002 Loading NodeOUs
2018-06-22 18:39:13.252 CEST [msp] getMspConfig -> INFO 003 Loading NodeOUs
2018-06-22 18:39:13.254 CEST [msp] getMspConfig -> INFO 004 Loading NodeOUs
2018-06-22 18:39:13.254 CEST [common/tools/configtxgen] doOutputBlock -> INFO 005 Generating genesis block
2018-06-22 18:39:13.258 CEST [common/tools/configtxgen] doOutputBlock -> INFO 006 Writing genesis block
```

Next, we must run a command to create our channel configuration transaction:

```
../bin/configtxgen -profile channelthreeorgs -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID channelthreeorgs
```

Notice the *channelthreeorgs* header we specified earlier. This will create a channel.tx file and this should appear in your terminal:

```
2018-06-22 18:41:42.241 CEST [common/tools/configtxgen] main -> INFO 001 Loading configuration
2018-06-22 18:41:42.263 CEST [common/tools/configtxgen] doOutputChannelCreateTx -> INFO 002 Generating new channel configtx
2018-06-22 18:41:42.267 CEST [msp] getMspConfig -> INFO 003 Loading NodeOUs
2018-06-22 18:41:42.271 CEST [msp] getMspConfig -> INFO 004 Loading NodeOUs
2018-06-22 18:41:42.273 CEST [msp] getMspConfig -> INFO 005 Loading NodeOUs
2018-06-22 18:41:42.317 CEST [common/tools/configtxgen] doOutputChannelCreateTx -> INFO 006 Writing new channel tx
```


Next, we must create our anchor peers transactions. We will have three commands to run, one for each organisation. For Microsoft: 

```
../bin/configtxgen -profile channelthreeorgs -outputAnchorPeersUpdate ./channel-artifacts/MicrosoftAnchor.tx -channelID channelthreeorgs -asOrg MicrosoftMSP
```

Notice we use the same channel header, and we use the ID we specified earlier (MicrosoftMSP). We specify a output file ( here MicrosoftAnchor.tx)

This should appear in your terminal:

```
2018-06-22 18:46:30.945 CEST [common/tools/configtxgen] main -> INFO 001 Loading configuration
2018-06-22 18:46:30.973 CEST [common/tools/configtxgen] doOutputAnchorPeersUpdate -> INFO 002 Generating anchor peer update
2018-06-22 18:46:30.976 CEST [common/tools/configtxgen] doOutputAnchorPeersUpdate -> INFO 003 Writing anchor peer update
```

Great! Now run that following two commands for IBM and Apple respectively:

```
../bin/configtxgen -profile channelthreeorgs -outputAnchorPeersUpdate ./channel-artifacts/IBMAnchor.tx -channelID channelthreeorgs -asOrg IBMMSP


../bin/configtxgen -profile channelthreeorgs -outputAnchorPeersUpdate ./channel-artifacts/AppleAnchor.tx -channelID channelthreeorgs -asOrg AppleMSP
```

## Creating peer-base and docker-compose files

We are almost there, we now need to specify a few docker files to tell our network where to find some images, how to be configured...

First, create a *base* folder. In this folder, create two files, one called *docker-compose-base.yaml* and another called peer-base.yaml.

*peer-base.yaml*

```yaml
version: '2'

services:
  peer-base:
    image: hyperledger/fabric-peer:x86_64-1.0.0-rc1
    environment:
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_byfn
      - CORE_LOGGING_LEVEL=INFO
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_GOSSIP_USELEADERELECTION=true
      - CORE_PEER_GOSSIP_ORGLEADER=false
      - CORE_PEER_PROFILE_ENABLED=true
      - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: peer node start
```

*docker-compose-base.yaml*

```yaml
version: '2'

services:

  orderer.cool-network.com:
    container_name: orderer.cool-network.com
    image: hyperledger/fabric-orderer:x86_64-1.0.0-rc1
    environment:
      - ORDERER_GENERAL_LOGLEVEL=INFO
      - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
      - ORDERER_GENERAL_GENESISMETHOD=file
      - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/genesis.block
      - ORDERER_GENERAL_LOCALMSPID=OrdererMSP
      - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
      # enabled TLS
      - ORDERER_GENERAL_TLS_ENABLED=true
      - ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
      - ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
      - ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric
    command: orderer
    volumes:
    - ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
    - ../crypto-config/ordererOrganizations/cool-network.com/orderers/orderer.cool-network.com/msp:/var/hyperledger/orderer/msp
    - ../crypto-config/ordererOrganizations/cool-network.com/orderers/orderer.cool-network.com/tls/:/var/hyperledger/orderer/tls
    - orderer.cool-network.com:/var/hyperledger/production/orderer
    ports:
      - 7050:7050

  peer0.microsoft.cool-network.com:
    container_name: peer0.microsoft.cool-network.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer0.microsoft.cool-network.com
      - CORE_PEER_ADDRESS=peer0.microsoft.cool-network.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.microsoft.cool-network.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.microsoft.cool-network.com:7051
      - CORE_PEER_LOCALMSPID=MicrosoftMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/microsoft.cool-network.com/peers/peer0.microsoft.cool-network.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/microsoft.cool-network.com/peers/peer0.microsoft.cool-network.com/tls:/etc/hyperledger/fabric/tls
        - peer0.microsoft.cool-network.com:/var/hyperledger/production
    ports:
      - 7051:7051
      - 7053:7053

  peer1.microsoft.cool-network.com:
    container_name: peer1.microsoft.cool-network.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer1.microsoft.cool-network.com
      - CORE_PEER_ADDRESS=peer1.microsoft.cool-network.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.microsoft.cool-network.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.microsoft.cool-network.com:7051
      - CORE_PEER_LOCALMSPID=MicrosoftMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/microsoft.cool-network.com/peers/peer1.microsoft.cool-network.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/microsoft.cool-network.com/peers/peer1.microsoft.cool-network.com/tls:/etc/hyperledger/fabric/tls
        - peer1.microsoft.cool-network.com:/var/hyperledger/production

    ports:
      - 8051:7051
      - 8053:7053

  peer0.apple.cool-network.com:
    container_name: peer0.apple.cool-network.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer0.apple.cool-network.com
      - CORE_PEER_ADDRESS=peer0.apple.cool-network.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.apple.cool-network.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.apple.cool-network.com:7051
      - CORE_PEER_LOCALMSPID=AppleMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/apple.cool-network.com/peers/peer0.apple.cool-network.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/apple.cool-network.com/peers/peer0.apple.cool-network.com/tls:/etc/hyperledger/fabric/tls
        - peer0.apple.cool-network.com:/var/hyperledger/production
    ports:
      - 9051:7051
      - 9053:7053

  peer1.apple.cool-network.com:
    container_name: peer1.apple.cool-network.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer1.apple.cool-network.com
      - CORE_PEER_ADDRESS=peer1.apple.cool-network.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.apple.cool-network.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.apple.cool-network.com:7051
      - CORE_PEER_LOCALMSPID=AppleMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/apple.cool-network.com/peers/peer1.apple.cool-network.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/apple.cool-network.com/peers/peer1.apple.cool-network.com/tls:/etc/hyperledger/fabric/tls
        - peer1.apple.cool-network.com:/var/hyperledger/production
    ports:
      - 10051:7051
      - 10053:7053

  peer0.ibm.cool-network.com:
    container_name: peer0.ibm.cool-network.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer0.ibm.cool-network.com
      - CORE_PEER_ADDRESS=peer0.ibm.cool-network.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.ibm.cool-network.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.ibm.cool-network.com:7051
      - CORE_PEER_LOCALMSPID=IBMMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/ibm.cool-network.com/peers/peer0.ibm.cool-network.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/ibm.cool-network.com/peers/peer0.ibm.cool-network.com/tls:/etc/hyperledger/fabric/tls
        - peer0.ibm.cool-network.com:/var/hyperledger/production
    ports:
      - 11051:7051
      - 11053:7053

  peer1.ibm.cool-network.com:
    container_name: peer1.ibm.cool-network.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer1.ibm.cool-network.com
      - CORE_PEER_ADDRESS=peer1.ibm.cool-network.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.ibm.cool-network.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.ibm.cool-network.com:7051
      - CORE_PEER_LOCALMSPID=IBMMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/ibm.cool-network.com/peers/peer1.ibm.cool-network.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/ibm.cool-network.com/peers/peer1.ibm.cool-network.com/tls:/etc/hyperledger/fabric/tls
        - peer1.ibm.cool-network.com:/var/hyperledger/production
    ports:
      - 12051:7051
      - 12053:7053

```

These files set up the base for our network, with some fabric images along with some environments variables.

Finally, the last file we will add is a *docker-compose-cli.yaml* file. This file will be in the root of our `cool-network` project. The file creates a `cli` container and bootstrap all of our organisations declared in our `base` folder.

*docker-compose-cli.yaml*

```yaml

version: '2'

volumes:
  orderer.cool-network.com:
  peer0.microsoft.cool-network.com:
  peer1.microsoft.cool-network.com:
  peer0.apple.cool-network.com:
  peer1.apple.cool-network.com:
  peer0.ibm.cool-network.com:
  peer1.ibm.cool-network.com:

networks:
  byfn:

services:

  orderer.cool-network.com:
    extends:
      file:   base/docker-compose-base.yaml
      service: orderer.cool-network.com
    container_name: orderer.cool-network.com
    networks:
      - byfn

  peer0.microsoft.cool-network.com:
    container_name: peer0.microsoft.cool-network.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer0.microsoft.cool-network.com
    networks:
      - byfn

  peer1.microsoft.cool-network.com:
    container_name: peer1.microsoft.cool-network.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer1.microsoft.cool-network.com
    networks:
      - byfn

  peer0.apple.cool-network.com:
    container_name: peer0.apple.cool-network.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer0.apple.cool-network.com
    networks:
      - byfn

  peer1.apple.cool-network.com:
    container_name: peer1.apple.cool-network.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer1.apple.cool-network.com
    networks:
      - byfn

  peer0.ibm.cool-network.com:
    container_name: peer0.ibm.cool-network.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer0.ibm.cool-network.com
    networks:
      - byfn

  peer1.ibm.cool-network.com:
    container_name: peer1.ibm.cool-network.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer1.ibm.cool-network.com
    networks:
      - byfn

  cli:
    container_name: cli
    image: hyperledger/fabric-tools:x86_64-1.0.0-rc1
    tty: true
    stdin_open: true
    environment:
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      #- CORE_LOGGING_LEVEL=DEBUG
      - CORE_LOGGING_LEVEL=INFO
      - CORE_PEER_ID=cli
      - CORE_PEER_ADDRESS=peer0.microsoft.cool-network.com:7051
      - CORE_PEER_LOCALMSPID=MicrosoftMSP
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/microsoft.cool-network.com/peers/peer0.microsoft.cool-network.com/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/microsoft.cool-network.com/peers/peer0.microsoft.cool-network.com/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/apple.cool-network.com/peers/peer0.apple.cool-network.com/tls/ca.crt
      - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/apple.cool-network.com/users/Admin@apple.cool-network.com/msp
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: /bin/bash
    volumes:
        - /var/run/:/host/var/run/
        - ./../chaincode/:/opt/gopath/src/github.com/chaincode
        - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
        - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
        - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
    depends_on:
      - orderer.cool-network.com
      - peer0.microsoft.cool-network.com
      - peer1.microsoft.cool-network.com
      - peer0.apple.cool-network.com
      - peer1.apple.cool-network.com
      - peer0.ibm.cool-network.com
      - peer1.ibm.cool-network.com
    networks:
      - byfn

```

Great, now we can run `docker-compose -f docker-compose-cli.yaml up -d`. You should see something like this is your terminal:

```
WARNING: The COMPOSE_PROJECT_NAME variable is not set. Defaulting to a blank string.
Creating network "cool-network_byfn" with the default driver
Creating volume "cool-network_orderer.cool-network.com" with default driver
Creating volume "cool-network_peer0.microsoft.cool-network.com" with default driver
Creating volume "cool-network_peer1.microsoft.cool-network.com" with default driver
Creating volume "cool-network_peer0.apple.cool-network.com" with default driver
Creating volume "cool-network_peer1.apple.cool-network.com" with default driver
Creating volume "cool-network_peer0.ibm.cool-network.com" with default driver
Creating volume "cool-network_peer1.ibm.cool-network.com" with default driver
Creating peer1.apple.cool-network.com     ... done
Creating peer0.apple.cool-network.com     ... done
Creating orderer.cool-network.com         ... done
Creating peer1.microsoft.cool-network.com ... done
Creating peer1.ibm.cool-network.com       ... done
Creating peer0.ibm.cool-network.com       ... done
Creating peer0.microsoft.cool-network.com ... done
Creating cli                              ... done
```

Now, we can run our `cli` container with `docker start cli` and enter inside the container with `docker exec -it cli bash`:

```
➜  cool-network git:(1252c7a) ✗ docker exec -it cli bash
root@9f8760ee6be8:/opt/gopath/src/github.com/hyperledger/fabric/peer#
```

Tadaaaa, our network is now running!! You can explore the different folders, you will find all the certificates, variables and everything that we defined in our yaml files.

## Conclusion

I hope this tutorial was clear enough for you to understand how to setup a Hyperledger Fabric environment. Of course, for now, this network can't do much without any chaincode ( or smart contracts ). This will be the topic for a later article. Have fun!