---
# System prepended metadata

title: Fabric 1.4 LTS Multi Hosts Install

---


Fabric 1.4 LTS Multi Hosts Install
===

**Version**

==Hyperledger Fabric v1.4.1==

**Updated Date**

==2019/12/05==
* remove Kafka

**Menu**
[TOC]

Intro
---

In this case, we'll have 3 *orderer (use **raft**, if want to use kafka also have settings below)*, *muilti peers (include **couchdb**)* of diffrient organization and *ca-server*

Setting files below reference from project of official Fabric github "fabric-samples/first-network".

or clone from vuetronica_insurance/fabric-multi-hosts

recommend do every action in *==tmux==*

#### TODO: 
* Dynamic add or remove Org

---

## Prepare

### Set timezone (All)

``` bash=
sudo timedatectl set-timezone Asia/Taipei
```
### Install package (All)

``` bash=
sudo yum install -y vim wget git tree
```

### Install package (peers, express need)

``` bash=
sudo yum install -y gcc-c++
```

### Install go (All)

``` bash=
wget https://dl.google.com/go/go1.12.6.linux-amd64.tar.gz && sudo tar -C /usr/local -xzf go1.12.6.linux-amd64.tar.gz

export PATH=$PATH:/usr/local/go/bin && source ~/.bashrc

go version
```

### Install docker (All)

``` bash=
sudo yum remove docker \
        docker-client \
        docker-client-latest \
        docker-common \
        docker-latest \
        docker-latest-logrotate \
        docker-logrotate \
        docker-engine

sudo yum install -y yum-utils \
     device-mapper-persistent-data \
     lvm2

sudo yum-config-manager \
     --add-repo \
     https://download.docker.com/linux/centos/docker-ce.repo
     
sudo yum install docker-ce docker-ce-cli containerd.io

sudo systemctl start docker && sudo systemctl enable docker

sudo usermod -aG docker $USER
```

After installed docker, relogin your user.

### Install docker-composed (All)

``` bash=
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose
```

### Download fabric bin (on client)

``` bash=
fabric@client#

wget https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric/linux-amd64-1.4.1/hyperledger-fabric-linux-amd64-1.4.1.tar.gz

tar -C ~/fabric -zxvf hyperledger-fabric-linux-amd64-1.4.1.tar.gz

cp -r ~/fabric/bin ~/
```

### Install python 3 (only on peers)

``` bash=
sudo yum install -y gcc openssl-devel bzip2-devel libffi-devel

wget https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tgz

tar xzf Python-3.7.2.tgz

cd Python-3.7.2 && ./configure --enable-optimizations

sudo make altinstall

cd && sudo rm -rf ~/Python-3.7.2.tgz && sudo rm -rf Python-3.7.2

python3.7 -V
```

### Install NVM and change to npm v8.15.1 (only on peers)
``` bash=
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash && source ~/.bashrc

nvm install v8.15.1 && nvm use v8.15.1
```

### Add hosts
add ip and domain to `/etc/hosts` of orderers, peers and ca-servers


## Generate required certificates and genesis block

### Generate Certs
``` bash=
fabric@client#

cd

./bin/cryptogen generate --config=./crypto-config.yaml
```
### Generate ChannelArtifacts
``` bash=
fabric@client#

mkdir channel-artifacts

./bin/configtxgen -profile {OrdererGenesisProfile} -outputBlock ./channel-artifacts/mygenesis.block
```

### Generate channel configuration transaction
``` bash=
fabric@client#

./bin/configtxgen -profile {TwoOrgsChannelProfile} -outputCreateChannelTx ./channel-artifacts/{CHANNEL_NAME0}.tx -channelID {CHANNEL_NAME0}
```

### Anchor peer update for ORG1 in channel0
``` bash=
fabric@client#

./configtxgen -profile TwoOrgsChannel0 -outputAnchorPeersUpdate \
./channel-artifacts/Org1MSPanchors_$CHANNEL_NAME0.tx -channelID $CHANNEL_NAME0 -asOrg {ORG1}
```

### Anchor peer update for ORG2 in channel0
``` bash=
fabric@client#

./configtxgen -profile TwoOrgsChannel0 -outputAnchorPeersUpdate \
./channel-artifacts/Org1MSPanchors_$CHANNEL_NAME0.tx -channelID $CHANNEL_NAME0 -asOrg {ORG2}
```

then repeat two action above on other org and channel

## Generate required certificates and genesis block (by script)
``` bash=
fabric@client

./byfn.sh generate
```

## Start services
### Start couchdb
``` bash=
fabric@couchdb#

vim couchdb.yaml
:set paste
i
```
paste below in to the file
``` yaml=
version: '2'
services:
  couchdb:
    container_name: couchdb
    image: hyperledger/fabric-couchdb
    volumes:
      - "/etc/localtime:/etc/localtime:ro"
    environment:
      COUCHDB_USER:
      COUCHDB_PASSWORD:
    ports:
      - "5984:5984"
```
then
``` bash=
docker-compose up -f couchdb.yaml
```
### Start orderer
``` bash=
fabric@client#

scp -r channel-artifacts/mygenesis.block \
orderer{NUM}.yaml \
crypto-config/ordererOrganizations/example.com/orderers/orderer{num}.example.com/msp \
crypto-config/ordererOrganizations/example.com/orderers/orderer{num}.example.com/tls \
fabric@{orderer ip}:/home/fabric/
```
In orderer host
``` bash=
fabric@orderer#

mv orderer{NUM}.yaml orderer.yaml

./orderer
```
### Start peer
``` bash=
fabric@client#

scp -r \
peer{PEER}-{ORG}.core.yaml \
crypto-config/peerOrganizations/{ORG}.example.com/peers/peer{PEER}.{ORG}.example.com/msp \
crypto-config/peerOrganizations/{ORG}.example.com/peers/peer{PEER}.{ORG}.example.com/tls \
fabric@{peer ip}:/home/fabric/
```
``` bash=
fabric@peer#

mv peer{PEER}-{ORG}.core.yaml core.yaml

./peer node start
```

## CA Server
deploy by docker compose
``` bash=
fabric@ca-server

vim ca-server.yaml
:set paste
i
```
paste yaml below and replace org key file name
``` yaml=
version: '2'
# networks:
#   ca-cluster:

services:
  ca.example.com:
    image: hyperledger/fabric-ca
    container_name: ca.example.com
    ports:
      - "7055:7055"
    environment:
      - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
      - FABRIC_CA_SERVER_CA_NAME=ca-example.com
      - FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/ca/ca.example.com-cert.pem
      - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/ca/{orderer_key}
      # - FABRIC_CA_SERVER_TLS_ENABLED=true
      # - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/tlsca/tlsca.example.com-cert.pem
      # - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/tlsca/{orderer_tls_key}
    volumes:
      - "/etc/localtime:/etc/localtime:ro"
      - "../example.com:/etc/hyperledger/fabric-ca-server"
      - "./crypto-config/ordererOrganizations/example.com/ca:/etc/hyperledger/ca:ro"
    command: sh -c 'fabric-ca-server start -b admin:adminpw -p 7055 --cfg.affiliations.allowremove --cfg.identities.allowremove'

  ca-insurance0001.example.com:
    image: hyperledger/fabric-ca
    container_name: ca-insurance0001
    ports:
      - "7056:7056"
    environment:
      - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
      - FABRIC_CA_SERVER_CA_NAME=ca-insurance0001
      - FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/ca/ca.insurance0001.example.com-cert.pem
      - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/ca/{org1_key}
      # - FABRIC_CA_SERVER_TLS_ENABLED=true
      # - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/tlsca/tlsca.insurance0001.example.com-cert.pem
      # - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/tlsca/{org1_tls_key}
    volumes:
      - "/etc/localtime:/etc/localtime:ro"
      - "../ca-insurance0001.example.com:/etc/hyperledger/fabric-ca-server"
      - "./crypto-config/peerOrganizations/insurance0001.example.com/ca:/etc/hyperledger/ca:ro"
    command: sh -c 'fabric-ca-server start -b admin:adminpw -p 7056 --cfg.affiliations.allowremove --cfg.identities.allowremove'

  ca-hospital0001.example.com:
    image: hyperledger/fabric-ca
    container_name: ca-hospital0001
    ports:
      - "7057:7057"
    environment:
      - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
      - FABRIC_CA_SERVER_CA_NAME=ca-hospital0001
      - FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/ca/ca.hospital0001.example.com-cert.pem
      - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/ca/{org2_key}      
      # - FABRIC_CA_SERVER_TLS_ENABLED=true
      # - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/tlsca/tlsca.hospital0001.example.com-cert.pem
      # - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/tlsca/{org2_tls_key}
    volumes:
      - "/etc/localtime:/etc/localtime:ro"
      - "../ca-hospital0001.example.com:/etc/hyperledger/fabric-ca-server"
      - "./crypto-config/peerOrganizations/hospital0001.example.com/ca:/etc/hyperledger/ca:ro"
    command: sh -c 'fabric-ca-server start -b admin:adminpw -p 7057 --cfg.affiliations.allowremove --cfg.identities.allowremove'

  ca-hospital0002.example.com:
    image: hyperledger/fabric-ca
    container_name: ca-hospital0002
    ports:
      - "7058:7058"
    environment:
      - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
      - FABRIC_CA_SERVER_CA_NAME=ca-hospital0002
      - FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/ca/ca.hospital0002.example.com-cert.pem
      - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/ca/{org3_key}      
      # - FABRIC_CA_SERVER_TLS_ENABLED=true
      # - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/tlsca/tlsca.hospital0002.example.com-cert.pem
      # - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/tlsca/{org3_tls_key}
    volumes:
      - "/etc/localtime:/etc/localtime:ro"
      - "../ca-hospital0002.example.com:/etc/hyperledger/fabric-ca-server"
      - "./crypto-config/peerOrganizations/hospital0002.example.com/ca:/etc/hyperledger/ca:ro"
    command: sh -c 'fabric-ca-server start -b admin:adminpw -p 7058 --cfg.affiliations.allowremove --cfg.identities.allowremove'

  ca-hospital0003.example.com:
    image: hyperledger/fabric-ca
    container_name: ca-hospital0003
    ports:
      - "7059:7059"
    environment:
      - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
      - FABRIC_CA_SERVER_CA_NAME=ca-hospital0003
      - FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/ca/ca.hospital0003.example.com-cert.pem
      - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/ca/{org4_key}      
      # - FABRIC_CA_SERVER_TLS_ENABLED=true
      # - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/tlsca/tlsca.hospital0003.example.com-cert.pem
      # - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/tlsca/{org4_tls_key}
    volumes:
      - "/etc/localtime:/etc/localtime:ro"
      - "../ca-hospital0003.example.com:/etc/hyperledger/fabric-ca-server"
      - "./crypto-config/peerOrganizations/hospital0003.example.com/ca:/etc/hyperledger/ca:ro"
    command: sh -c 'fabric-ca-server start -b admin:adminpw -p 7059 --cfg.affiliations.allowremove --cfg.identities.allowremove'    
```
then
``` bash=
docker-compose -f ca-server.yaml up
```
## Create Channel (by byfn script)
``` bash=
fabric@client#

./byfn.sh createChannel
```

## Join Channel (by byfn script)
``` bash=
fabric@client#

./byfn.sh joinChannel
```

## Update Anchor (by byfn script)
``` bash=
fabric@client#

./byfn.sh updateAnchor
```

## Install Chaincode (by byfn script)
``` bash=
fabric@client#

./byfn.sh installChaincode

```

## Instantiate Chaincode (by byfn script)
``` bash=
fabric@client#

./byfn.sh instantiateChaincode

```

## Start express

### pm2 (recommend)
#### Install
``` bash=
npm install pm2 -g
```
#### Start project
``` bash=
cd {express path}
pm2 start npm -- start --watch
```
#### Check logs
``` bash=
pm2 logs 0
```

### Forever
#### Start npm by forever
``` bash=
cd {express path}
forever start -o ./log.txt -c "npm run start" ./
```
#### Check logs
``` bash=
tail -50f ~/.forever/{logfilename}.log
```
you can find {logfilename} using `forever list`

``` bash=
fabric-ca-client enroll -u http://Admin@insurance0001.example.com:password@localhost:7054  -H `pwd`/fabric-ca-files/insurance0001.example.com/admin
  267  fabric-ca-client enroll -u http://Admin@insurance0001.example.com:password@localhost:7056  -H `pwd`/fabric-ca-files/insurance0001.example.com/admin
  268  vim fabric-ca-files/admin/fabric-ca-client-config.yaml
  269  fabric-ca-client -H `pwd`/fabric-ca-files/admin -u http://admin:adminpw@localhost:7056 identity list
  270  fabric-ca-client register --id.name user1 --id.secret user1pw --id.type user --id.affiliation com.example.insurance0001 --id.attrs 'role=user:ecert,email=user1@insurance0001.example.com'
  271  fabric-ca-client register --id.name user1 --id.secret user1pw --id.type user --id.affiliation com.example.insurance0001 --id.attrs 'role=user:ecert,email=user1@insurance0001.example.com' -H fabric-
ca-files/admin -u http://admin:adminpw@localhost:7057
```