在Ubuntu20.0的操作系统下,在 /usr/fabric/device_network 文件夹下创建目录 docker
配置3个order节点
在 docker 目录下创建文件 docker-compose-orderer3.yaml 将以下代码写入
version: '3.7'
services:
cli:
image: hyperledger/fabric-tools:2.5.10
restart: always
container_name: fabric-cli
hostname: fabric-cli
tty: true
extra_hosts:
- "orderer0.example.com:192.168.206.138"
- "orderer1.example.com:192.168.206.138"
- "orderer2.example.com:192.168.206.138"
- "peer0.org1.example.com:192.168.206.138"
- "peer1.org1.example.com:192.168.206.138"
- "peer0.org2.example.com:192.168.206.138"
- "peer1.org2.example.com:192.168.206.138"
environment:
- CORE_PEER_ID=fabric-cli
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051 # default to operate on peer0.org1
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
- FABRIC_LOGGING_SPEC=DEBUG
- FABRIC_LOGGING_FORMAT=%{color}[%{id:03x} %{time:01-02 15:04:05.00 MST}] [%{module}] %{shortfunc} -> %{level:.4s}%{color:reset} %{message}
- CORE_PEER_TLS_ENABLED=true # to enable TLS, change to true
- ORDERER_CA=/etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
volumes:
- ../config/crypto-config.yaml:/etc/hyperledger/fabric/crypto-config.yaml
- ../config/configtx.yaml:/etc/hyperledger/fabric/configtx.yaml
- ../crypto-config:/etc/hyperledger/fabric/crypto-config
- ../channel-artifacts:/tmp/channel-artifacts
- ../chaincodes:/etc/hyperledger/fabric/chaincodes
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: bash -c 'cd /tmp; source scripts/func.sh; while true; do sleep 20170504; done'
orderer0.example.com: # There can be multiple orderers
image: hyperledger/fabric-orderer:2.5.10
restart: always
container_name: orderer0.example.com
hostname: orderer0.example.com
ports:
- "7050:7050"
- "8443:8443"
extra_hosts:
- "orderer0.example.com:192.168.206.138"
- "orderer1.example.com:192.168.206.138"
- "orderer2.example.com:192.168.206.138"
- "peer0.org1.example.com:192.168.206.138"
- "peer1.org1.example.com:192.168.206.138"
- "peer0.org2.example.com:192.168.206.138"
- "peer1.org2.example.com:192.168.206.138"
environment:
- FABRIC_LOGGING_FORMAT="%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 # default: 127.0.0.1
- ORDERER_GENERAL_LISTENPORT=7050
- ORDERER_GENERAL_GENESISMETHOD=file # default: provisional
- ORDERER_GENERAL_BOOTSTRAPFILE=/etc/hyperledger/fabric/orderer.genesis.block # by default, all materials should be put under $FABRIC_CFG_PATH, which defaults to /etc/hyperledger/fabric
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP # default: DEFAULT
- ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/fabric/msp
- ORDERER_GENERAL_LEDGERTYPE=file
#- ORDERER_GENERAL_LEDGERTYPE=json # default: file
- ORDERER_OPERATIONS_LISTENADDRESS=0.0.0.0:8443 # operation RESTful API
- ORDERER_METRICS_PROVIDER=prometheus # prometheus will pull metrics from orderer via /metrics RESTful API
#- ORDERER_RAMLEDGER_HISTORY_SIZE=100 #only useful when use ram ledger
# enabled TLS
- ORDERER_GENERAL_TLS_ENABLED=true # default: false
- ORDERER_GENERAL_TLS_PRIVATEKEY=/etc/hyperledger/fabric/tls/server.key
- ORDERER_GENERAL_TLS_CERTIFICATE=/etc/hyperledger/fabric/tls/server.crt
- ORDERER_GENERAL_TLS_ROOTCAS=[/etc/hyperledger/fabric/tls/ca.crt]
# Only required by raft mode
- ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/etc/hyperledger/fabric/tls/server.key
- ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/etc/hyperledger/fabric/tls/server.crt
- ORDERER_GENERAL_CLUSTER_ROOTCAS=[/etc/hyperledger/fabric/tls/ca.crt]
- FABRIC_LOGGING_SPEC=DEBUG
volumes:
- ../crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/:/etc/hyperledger/fabric/tls
- ../channel-artifacts/orderer.genesis.block:/etc/hyperledger/fabric/orderer.genesis.block
expose:
- "7050" # gRPC
- "8443" # Operation REST
command: orderer start
orderer1.example.com:
image: hyperledger/fabric-orderer:2.5.10
restart: always
container_name: orderer1.example.com
hostname: orderer1.example.com
ports:
- "8050:7050"
- "8444:8443"
extra_hosts:
- "orderer0.example.com:192.168.206.138"
- "orderer1.example.com:192.168.206.138"
- "orderer2.example.com:192.168.206.138"
- "peer0.org1.example.com:192.168.206.138"
- "peer1.org1.example.com:192.168.206.138"
- "peer0.org2.example.com:192.168.206.138"
- "peer1.org2.example.com:192.168.206.138"
environment:
- FABRIC_LOGGING_SPEC=DEBUG
- FABRIC_LOGGING_FORMAT="%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 # default: 127.0.0.1
- ORDERER_GENERAL_LISTENPORT=7050
- ORDERER_GENERAL_GENESISMETHOD=file # default: provisional
- ORDERER_GENERAL_BOOTSTRAPFILE=/etc/hyperledger/fabric/orderer.genesis.block # by default, all materials should be put under $FABRIC_CFG_PATH, which defaults to /etc/hyperledger/fabric
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP # default: DEFAULT
- ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/fabric/msp
- ORDERER_GENERAL_LEDGERTYPE=file
#- ORDERER_GENERAL_LEDGERTYPE=json # default: file
- ORDERER_OPERATIONS_LISTENADDRESS=0.0.0.0:8443 # operation RESTful API
- ORDERER_METRICS_PROVIDER=prometheus # prometheus will pull metrics from orderer via /metrics RESTful API
#- ORDERER_RAMLEDGER_HISTORY_SIZE=100 #only useful when use ram ledger
# enabled TLS
- ORDERER_GENERAL_TLS_ENABLED=true # default: false
- ORDERER_GENERAL_TLS_PRIVATEKEY=/etc/hyperledger/fabric/tls/server.key
- ORDERER_GENERAL_TLS_CERTIFICATE=/etc/hyperledger/fabric/tls/server.crt
- ORDERER_GENERAL_TLS_ROOTCAS=[/etc/hyperledger/fabric/tls/ca.crt]
# Only required by raft mode
- ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/etc/hyperledger/fabric/tls/server.key
- ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/etc/hyperledger/fabric/tls/server.crt
- ORDERER_GENERAL_CLUSTER_ROOTCAS=[/etc/hyperledger/fabric/tls/ca.crt]
- ORDERER_GENERAL_CLUSTER_SENDBUFFERSIZE=10
volumes:
- ../crypto-config/ordererOrganizations/example.com/orderers/orderer1.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/ordererOrganizations/example.com/orderers/orderer1.example.com/tls/:/etc/hyperledger/fabric/tls
- ../channel-artifacts/orderer.genesis.block:/etc/hyperledger/fabric/orderer.genesis.block
command: orderer start
orderer2.example.com:
image: hyperledger/fabric-orderer:2.5.10
restart: always
container_name: orderer2.example.com
hostname: orderer2.example.com
ports:
- "9050:7050"
- "8445:8443"
extra_hosts:
- "orderer0.example.com:192.168.206.138"
- "orderer1.example.com:192.168.206.138"
- "orderer2.example.com:192.168.206.138"
- "peer0.org1.example.com:192.168.206.138"
- "peer1.org1.example.com:192.168.206.138"
- "peer0.org2.example.com:192.168.206.138"
- "peer1.org2.example.com:192.168.206.138"
environment:
- FABRIC_LOGGING_SPEC=DEBUG # default: INFO
- FABRIC_LOGGING_FORMAT="%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 # default: 127.0.0.1
- ORDERER_GENERAL_LISTENPORT=7050
- ORDERER_GENERAL_GENESISMETHOD=file # default: provisional
- ORDERER_GENERAL_BOOTSTRAPFILE=/etc/hyperledger/fabric/orderer.genesis.block # by default, all materials should be put under $FABRIC_CFG_PATH, which defaults to /etc/hyperledger/fabric
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP # default: DEFAULT
- ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/fabric/msp
- ORDERER_GENERAL_LEDGERTYPE=file
#- ORDERER_GENERAL_LEDGERTYPE=json # default: file
- ORDERER_OPERATIONS_LISTENADDRESS=0.0.0.0:8443 # operation RESTful API
- ORDERER_METRICS_PROVIDER=prometheus # prometheus will pull metrics from orderer via /metrics RESTful API
#- ORDERER_RAMLEDGER_HISTORY_SIZE=100 #only useful when use ram ledger
# enabled TLS
- ORDERER_GENERAL_TLS_ENABLED=true # default: false
- ORDERER_GENERAL_TLS_PRIVATEKEY=/etc/hyperledger/fabric/tls/server.key
- ORDERER_GENERAL_TLS_CERTIFICATE=/etc/hyperledger/fabric/tls/server.crt
- ORDERER_GENERAL_TLS_ROOTCAS=[/etc/hyperledger/fabric/tls/ca.crt]
# Only required by raft mode
- ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/etc/hyperledger/fabric/tls/server.key
- ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/etc/hyperledger/fabric/tls/server.crt
- ORDERER_GENERAL_CLUSTER_ROOTCAS=[/etc/hyperledger/fabric/tls/ca.crt]
- ORDERER_GENERAL_CLUSTER_SENDBUFFERSIZE=10
volumes:
- ../crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/:/etc/hyperledger/fabric/tls
- ../channel-artifacts/orderer.genesis.block:/etc/hyperledger/fabric/orderer.genesis.block
command: orderer start
主要更改的是 extra_hosts 这个是配置我们多节点的网络端口,192.168.206.138是虚拟机本地ip使用 ifconfig 可以查看,还有每个节点的 volumes 需要仔细看看,这些文件本机目录中你生成的身份文件和节点配置文件,一定要找准文件位置不能出错。
接下来使用命令去启动3个order节点的网络
docker-compose -f docker-compose-orderer3.yaml up -d
因为我之前的 volumes 的路径错误,执行一遍后报错,之后再命令的时候报错了
docker-compose -f docker-compose-order3.yaml up -d
WARN[0000] /usr/fabric/device_network/docker/docker-compose-order3.yaml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion [+] Running 0/4 ⠹ Container orderer2.example.com Sta... 1.2s ⠹ Container fabric-cli Starting 1.2s ⠹ Container orderer0.example.com Sta... 1.2s ⠹ Container orderer1.example.com Sta... 1.2s Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/usr/fabric/device_network/config/crypto-config.yaml" to rootfs at "/etc/hyperledger/fabric/crypto-config.yaml": mount src=/usr/fabric/device_network/config/crypto-config.yaml, dst=/etc/hyperledger/fabric/crypto-config.yaml, dstFd=/proc/thread-self/fd/9, flags=0x5000: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type
究其原因是因为 docker 镜像上已经有了 /etc/hyperledger/fabric/crypto-config.yaml 文件的镜像,考虑之后可能其他文件镜像也在上面,便需要将所有缓存都清掉,下面是查看 docker 中有多少存在的缓存。
docker run --rm hyperledger/fabric-tools:2.5.10 ls -l /etc/hyperledger/fabric/
total 92
-rw-r--r-- 1 root root 26700 Sep 20 11:23 configtx.yaml
-rw-r--r-- 1 root root 36952 Sep 20 11:23 core.yaml
drwxr-xr-x 8 root root 4096 Feb 26 12:00 msp
-rw-r--r-- 1 root root 17589 Sep 20 11:23 orderer.yaml
需要清理缓存,执行下面一条命令后根据指令选择是否删除,是的话就开始删除
docker system prune -a --volumes
在文件路径都没有问题时,再启动就可以执行成功
停止启动的orderer或peer节点节点
有三种方式停止:
- 停止所有关联容器
docker-compose -f docker-compose-orderer.yaml down
这种方式会停止并删除 compose 文件中定义的所有容器,同时移除默认网络。
- 仅停止不删除容器
docker-compose -f docker-compose-orderer.yaml stop
容器和网络会被保留,数据卷不会删除
- 停止单个 orderer 节点
docker stop [节点名称]
- 持久化清理数据
docker-compose -f docker-compose-orderer.yaml down -v
添加 -v 参数会同时删除 compose 文件中定义的 volumes 卷
例如:
# 重新启动已停止的容器(保持原有配置) docker-compose -f docker-compose-orderer.yaml start
# 或使用 up 命令重新构建并启动(推荐方式) docker-compose -f docker-compose-orderer.yaml up -d
配置两个组织的peer节点内容
这一部分也是不能错一个字母,不然后面修改比较麻烦
首先看org1的peer节点,配置。docker-compose-order01-peer2.yaml
version: '2.0'
services:
peer0.org1.example.com:
image: hyperledger/fabric-peer:2.5
restart: always
container_name: peer0.org1.example.com
hostname: peer0.org1.example.com
ports:
- 7051:7051
- 7052:7052
- 9443:9443
extra_hosts:
- "orderer0.example.com:192.168.206.138"
- "orderer1.example.com:192.168.206.138"
- "orderer2.example.com:192.168.206.138"
- "peer0.org1.example.com:192.168.206.138"
- "peer1.org1.example.com:192.168.206.138"
- "peer0.org2.example.com:192.168.206.138"
- "peer1.org2.example.com:192.168.206.138"
environment:
- FABRIC_LOGGING_SPEC=INFO
- FABRIC_LOGGING_FORMAT="%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"
- CORE_PEER_ADDRESSAUTODETECT=false
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=host # uncomment this to use specific network
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false # whether this node is the org leader, default to false
- CORE_OPERATIONS_LISTENADDRESS=0.0.0.0:9443 # operation RESTful API
- CORE_METRICS_PROVIDER=prometheus # prometheus will pull metrics from fabric via /metrics RESTful API
- CORE_PEER_PROFILE_ENABLED=false
- CORE_PEER_TLS_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
- CORE_CHAINCODE_BUILDER=hyperledger/fabric-ccenv:2.5
- CORE_CHAINCODE_GOLANG_RUNTIME=hyperledger/fabric-baseos:2.5
- CORE_CHAINCODE_JAVA_RUNTIME=hyperledger/fabric-javaenv:2.5
- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.5
- CORE_PEER_ID=peer0.org1.example.com
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- FABRIC_LOGGING_SPEC=DEBUG # info:core.chaincode=debug
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=peer0.org1.couchdb:5984
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpw
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ../crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls
# - /var/hyperledger/production:/var/hyperledger/production # uncomment this to use production level db
expose:
- "7051" # gRPC
- "9443" # Operation REST
#command: bash -c 'bash /tmp/peer_build.sh; peer node start'
command: peer node start
depends_on:
- peer0.org1.couchdb
peer1.org1.example.com:
image: hyperledger/fabric-peer:2.5
restart: always
container_name: peer1.org1.example.com
hostname: peer1.org1.example.com
ports:
- 8051:7051
- 8052:7052
- 9444:9443
extra_hosts:
- "orderer0.example.com:192.168.206.138"
- "orderer1.example.com:192.168.206.138"
- "orderer2.example.com:192.168.206.138"
- "peer0.org1.example.com:192.168.206.138"
- "peer1.org1.example.com:192.168.206.138"
- "peer0.org2.example.com:192.168.206.138"
- "peer1.org2.example.com:192.168.206.138"
environment:
- FABRIC_LOGGING_SPEC=INFO
- FABRIC_LOGGING_FORMAT="%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"
- CORE_PEER_ADDRESSAUTODETECT=false
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=host # uncomment this to use specific network
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false # whether this node is the org leader, default to false
- CORE_OPERATIONS_LISTENADDRESS=0.0.0.0:9443 # operation RESTful API
- CORE_METRICS_PROVIDER=prometheus # prometheus will pull metrics from fabric via /metrics RESTful API
- CORE_PEER_PROFILE_ENABLED=false
- CORE_PEER_TLS_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
- CORE_CHAINCODE_BUILDER=hyperledger/fabric-ccenv:2.5
- CORE_CHAINCODE_GOLANG_RUNTIME=hyperledger/fabric-baseos:2.5
- CORE_CHAINCODE_JAVA_RUNTIME=hyperledger/fabric-javaenv:2.5
- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.5
- CORE_PEER_ID=peer1.org1.example.com
- CORE_PEER_ADDRESS=peer1.org1.example.com:8051
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_CHAINCODEADDRESS=peer1.org1.example.com:8051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.example.com:8051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:8051
- CORE_PEER_LOCALMSPID=Org1MSP
- FABRIC_LOGGING_SPEC=DEBUG # info:core.chaincode=debug
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=peer1.org1.couchdb:5984
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpw
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ../crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls:/etc/hyperledger/fabric/tls
# - /var/hyperledger/production:/var/hyperledger/production # uncomment this to use production level db
expose:
- "8051" # gRPC
- "9444" # Operation REST
#command: bash -c 'bash /tmp/peer_build.sh; peer node start'
command: peer node start
depends_on:
- peer1.org1.couchdb
peer0.org1.couchdb:
image: couchdb:3.3.3
container_name: peer0.org1.couchdb
ports:
- 5984:5984 # this is the restful API addr, can also access fauxton web ui thru http://localhost:5984/_utils/
environment:
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=adminpw
peer1.org1.couchdb:
image: couchdb:3.3.3
container_name: peer1.org1.couchdb
ports:
- 6984:5984 # this is the restful API addr, can also access fauxton web ui thru http://localhost:5984/_utils/
environment:
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=adminpw
org2的peer类似,注意端口和名字要更换。docker-compose-order02-peer2.yaml
version: '2.0'
services:
peer0.org2.example.com:
image: hyperledger/fabric-peer:2.5
restart: always
container_name: peer0.org2.example.com
hostname: peer0.org2.example.com
ports:
- 9051:7051
- 9052:7052
- 9445:9443
extra_hosts:
- "orderer0.example.com:192.168.206.138"
- "orderer1.example.com:192.168.206.138"
- "orderer2.example.com:192.168.206.138"
- "peer0.org1.example.com:192.168.206.138"
- "peer1.org1.example.com:192.168.206.138"
- "peer0.org2.example.com:192.168.206.138"
- "peer1.org2.example.com:192.168.206.138"
environment:
- FABRIC_LOGGING_SPEC=INFO
- FABRIC_LOGGING_FORMAT="%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"
- CORE_PEER_ADDRESSAUTODETECT=false
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=host # uncomment this to use specific network
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false # whether this node is the org leader, default to false
- CORE_OPERATIONS_LISTENADDRESS=0.0.0.0:9443 # operation RESTful API
- CORE_METRICS_PROVIDER=prometheus # prometheus will pull metrics from fabric via /metrics RESTful API
- CORE_PEER_PROFILE_ENABLED=false
- CORE_PEER_TLS_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
- CORE_CHAINCODE_BUILDER=hyperledger/fabric-ccenv:2.5
- CORE_CHAINCODE_GOLANG_RUNTIME=hyperledger/fabric-baseos:2.5
- CORE_CHAINCODE_JAVA_RUNTIME=hyperledger/fabric-javaenv:2.5
- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.5
- CORE_PEER_ID=peer0.org2.example.com
- CORE_PEER_ADDRESS=peer0.org2.example.com:9051
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_CHAINCODEADDRESS=peer0.org2.example.com:9051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:9051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:9051
- CORE_PEER_LOCALMSPID=Org2MSP
- FABRIC_LOGGING_SPEC=DEBUG # info:core.chaincode=debug
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=peer0.org2.couchdb:5984
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpw
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ../crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls:/etc/hyperledger/fabric/tls
# - /var/hyperledger/production:/var/hyperledger/production # uncomment this to use production level db
expose:
- "7051" # gRPC
- "9443" # Operation REST
#command: bash -c 'bash /tmp/peer_build.sh; peer node start'
command: peer node start
depends_on:
- peer0.org2.couchdb
peer1.org2.example.com:
image: hyperledger/fabric-peer:2.5
restart: always
container_name: peer1.org2.example.com
hostname: peer1.org2.example.com
ports:
- 10051:7051
- 10052:7052
- 9446:9443
extra_hosts:
- "orderer0.example.com:192.168.206.138"
- "orderer1.example.com:192.168.206.138"
- "orderer2.example.com:192.168.206.138"
- "peer0.org1.example.com:192.168.206.138"
- "peer1.org1.example.com:192.168.206.138"
- "peer0.org2.example.com:192.168.206.138"
- "peer1.org2.example.com:192.168.206.138"
environment:
- FABRIC_LOGGING_SPEC=INFO
- FABRIC_LOGGING_FORMAT="%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"
- CORE_PEER_ADDRESSAUTODETECT=false
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=host # uncomment this to use specific network
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false # whether this node is the org leader, default to false
- CORE_OPERATIONS_LISTENADDRESS=0.0.0.0:9443 # operation RESTful API
- CORE_METRICS_PROVIDER=prometheus # prometheus will pull metrics from fabric via /metrics RESTful API
- CORE_PEER_PROFILE_ENABLED=false
- CORE_PEER_TLS_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
- CORE_CHAINCODE_BUILDER=hyperledger/fabric-ccenv:2.5
- CORE_CHAINCODE_GOLANG_RUNTIME=hyperledger/fabric-baseos:2.5
- CORE_CHAINCODE_JAVA_RUNTIME=hyperledger/fabric-javaenv:2.5
- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.5
- CORE_PEER_ID=peer1.org2.example.com
- CORE_PEER_ADDRESS=peer1.org2.example.com:10051
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_CHAINCODEADDRESS=peer1.org2.example.com:10051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org2.example.com:10051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org2.example.com:10051
- CORE_PEER_LOCALMSPID=Org2MSP
- FABRIC_LOGGING_SPEC=DEBUG # info:core.chaincode=debug
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=peer1.org2.couchdb:5984
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpw
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ../crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls:/etc/hyperledger/fabric/tls
# - /var/hyperledger/production:/var/hyperledger/production # uncomment this to use production level db
expose:
- "8051" # gRPC
- "9444" # Operation REST
#command: bash -c 'bash /tmp/peer_build.sh; peer node start'
command: peer node start
depends_on:
- peer1.org2.couchdb
peer0.org2.couchdb:
image: couchdb:3.3.3
container_name: peer0.org2.couchdb
ports:
- 7984:5984 # this is the restful API addr, can also access fauxton web ui thru http://localhost:5984/_utils/
environment:
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=adminpw
peer1.org2.couchdb:
image: couchdb:3.3.3
container_name: peer1.org2.couchdb
ports:
- 8984:5984 # this is the restful API addr, can also access fauxton web ui thru http://localhost:5984/_utils/
environment:
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=adminpw
启动peer节点
docker-compose -f docker-compose-order01-peer2.yaml up -d
docker-compose -f docker-compose-order02-peer2.yaml up -d
启动成功的标准是,peer节点和order节点的日志不能有报错的,这一个需要查看日志才能知道
docker logs [节点名]
加入docker容器创建通道
节点启动后可以查看启动状态
docker ps -a
启动成功后可以加入 fabric-cli 容器进行创建通道作用
docker exec -it fabric-cli bash
执行命令创建通道
export APP_CHANNEL=businesschannel export TIMEOUT=30 export CORE_PEER_LOCALMSPID=Org1MSP export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
peer channel create -o orderer0.example.com:7050 -c ${APP_CHANNEL} -f "/tmp/channel-artifacts/$APP_CHANNEL.tx" --timeout "${TIMEOUT}s" --tls --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
创建通道时报错,这个问题大概是我在使用前面环境变量配置的身份去创建通道导致的权限报错
Error: got unexpected status: FORBIDDEN -- implicit policy evaluation failed - 0 sub-policies were satisfied, but this policy requires 1 of the 'Writers' sub-policies to be satisfied: permission denied
这个问题困扰我很久了,没有好的解决方法,我先说一下我的docker、go环境版本:
DOCKER Version: 27.4.1
API version: 1.47 (minimum version 1.24)
Go version: go1.22.10Docker Compose version v2.33.1
我上网查过,也用AI问过,基本问题是以下几点
- 在配置 configtx.yaml 的身份,就是图片所示的policies 是没有对上权限的,但是我去网上找了很多相关的代码,基本上我的这个没有问题,查过AI看了身份文件也是有对应身份。
- 第二种就是,通道名称问题,网友说是因为我创建的通道名称和之前生成初始交易的通道名称对不上,我觉得并不是。
- 第三种是版本问题,因为我的fabric使用的是2.5.10
最后的解决办法,我切换了fabric的版本是2.5,注意这些也是2.5,最终代码参考上面节点的配置

最后交易通道创建完成,可以看到当前目录有一个 businesschannel.block 文件
参考文章:
Hyperledger Fabric Docker 方式多机部署生产网络 - OSCHINA - 中文开源技术交流社区
hyperledger-fabric 【11】 docker 方式搭建多机网络_哔哩哔哩_bilibili
有问题可以讨论。此文章自用,记录学习联盟链搭建的过程,并希望能够帮助更多人了解到区块链的搭建,方便找资源。