Table of Contents
- Upgrading to Hyperledger Fabric 2.0: Complete Migration Guide
- Step 1: Prepare Environment Configurations
- Peer Environment Variables
- Ordering Node Environment Variables
- Step 2: Understand Ledger Backup Strategies
- Step 3: Upgrade Ordering Nodes
- Set Orderer Environment Variables
- Execute Orderer Rolling Upgrades
- Replace Peer Containers and Clear Chaincode
- Step 5: Upgrade Auxiliary Network Components
- Step 6: Enable Channel Capabilities
- Update the Orderer System Channel
- Update Application Channels
- Step 7: Activate the Fabric 2.0 Chaincode Lifecycle
- Update Organization Policies in the System Channel
- Update Organization and Endorsement Policies in Application Channels
- Update Peer Configuration (core.yaml)
Upgrading to Hyperledger Fabric 2.0: Complete Migration Guide
Upgrading nodes and channels to the latest Hyperledger Fabric version involves a high-level four-step process:
Back up the ledger and Membership Service Providers (MSPs).
Upgrade orderer binaries in a rolling fashion.
Upgrade peer binaries in a rolling fashion.
Update channel capabilities across the orderer system channel and application channels.
Because node and channel capability upgrades represent standard Fabric procedures, this guide assumes a Docker deployment where images contain configuration files and environment variables override default settings.
Step 1: Prepare Environment Configurations
Before starting your containers, maintain consistent configuration settings by saving your environment variables locally.
Peer Environment Variables
Export the primary network variables for each peer:
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
CORE_PEER_ID=peer0.org1.example.com
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
CORE_PEER_LISTENADDRESS=0.0.0.0:7051
CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052
CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
CORE_PEER_LOCALMSPID=Org1MSP Ordering Node Environment Variables
Store these variables in a local configuration file for every orderer node:
ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
ORDERER_GENERAL_GENESISMETHOD=file
ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
ORDERER_GENERAL_LOCALMSPID=OrdererMSP
ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
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]
ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt
ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key
ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] Step 2: Understand Ledger Backup Strategies
While a peer can rebuild its ledger by syncing blocks across the channel, restoring from a backup saves hours of processing time.
The default data directory is
/var/hyperledger/production/for peers and/var/hyperledger/production/ordererfor orderers.You can reduce storage size by omitting the
stateLeveldb,historyLeveldb, andchains/indexfolders; however, re-indexing will lengthen the subsequent startup time.When utilizing CouchDB as your state database, ensure your CouchDB backup is older than your peer ledger backup to avoid block-height mismatches during state reconstruction.
Step 3: Upgrade Ordering Nodes
Upgrade your orderers sequentially in a rolling fashion to maintain network consensus. Always upgrade orderer nodes before upgrading peers.
Set Orderer Environment Variables
Set your operational target parameters:
export ORDERER_CONTAINER=orderer.example.com
export LEDGERS_BACKUP=/opt/backup
export IMAGE_TAG=2.0 Execute Orderer Rolling Upgrades
Stop the container, copy the data directories, and launch the new Fabric 2.0 image:
# Stop the orderer instance
docker stop $ORDERER_CONTAINER
# Back up the ledger and MSP
docker cp $ORDERER_CONTAINER:/var/hyperledger/production/orderer/ $LEDGERS_BACKUP/$ORDERER_CONTAINER
# Launch the upgraded orderer container
docker run -d \
-v /opt/backup/$ORDERER_CONTAINER/:/var/hyperledger/production/orderer/ \
-v /opt/msp/:/etc/hyperledger/fabric/msp/ \
--env-file ./env_${ORDERER_CONTAINER}.list \
--name $ORDERER_CONTAINER \
hyperledger/fabric-orderer:$IMAGE_TAG orderer Repeat this procedure for every ordering node in your cluster.
Step 4: Upgrade Peer Nodes
Once the ordering service runs on version 2.0, upgrade your peers one by one.
Step 4: Upgrade Peer Nodes
Define the target peer variables:
export PEER_CONTAINER=peer0.org1.example.com
export LEDGERS_BACKUP=/opt/backup
export IMAGE_TAG=2.0 Replace Peer Containers and Clear Chaincode
Shut down the running node, back up the filesystem, and remove stale chaincode runtimes:
Need skilled IT professionals?
# Stop the peer instance
docker stop $PEER_CONTAINER
# Back up the peer filesystem
docker cp $PEER_CONTAINER:/var/hyperledger/production $LEDGERS_BACKUP/$PEER_CONTAINER
# Remove old chaincode containers
CC_CONTAINERS=$(docker ps -a | grep dev-$PEER_CONTAINER | awk '{print $1}')
if [ -n "$CC_CONTAINERS" ] ; then docker rm -f $CC_CONTAINERS ; fi
# Remove old chaincode images
CC_IMAGES=$(docker images | grep dev-$PEER_CONTAINER | awk '{print $1}')
if [ -n "$CC_IMAGES" ] ; then docker rmi -f $CC_IMAGES ; fi
# Remove the old peer container
docker rm -f $PEER_CONTAINER
# Launch the upgraded peer container
docker run -d \
-v /opt/backup/$PEER_CONTAINER/:/var/hyperledger/production/ \
-v /opt/msp/:/etc/hyperledger/fabric/msp/ \
--env-file ./env_${PEER_CONTAINER}.list \
--name $PEER_CONTAINER \
hyperledger/fabric-peer:$IMAGE_TAG peer node start Peers automatically rebuild chaincode images on the first subsequent invoke or query. Verify the upgrade by issuing a test query to the ledger.
Step 5: Upgrade Auxiliary Network Components
Ensure you update client-side libraries and supporting databases to prevent compatibility issues.
Fabric CA: Upgrade CA server binaries using the official CA migration procedure.
Node SDK Clients: Update client dependencies in your application root directory:
npm install fabric-client@latest fabric-ca-client@latest CouchDB: Stop CouchDB, back up
/opt/couchdb/data, deploy the new container image, and restart the service alongside the peer.Chaincode Shims: Update
fabric-shimwithin your chaincode’spackage.jsonto the target 2.0 release, then re-vendor and re-install the package across your endorsing peers.
Step 6: Enable Channel Capabilities
After upgrading all binaries, execute channel update transactions to unlock Fabric 2.0 capabilities. Follow the sequence: Orderer System Channel $\rightarrow$ Application Channels.
[System Channel: Orderer Group] ──> [System Channel: Channel Group]
│
▼
[App Channels: Orderer Group] ──> [App Channels: Channel Group] ──> [App Channels: Application Group] Update the Orderer System Channel
Export the system channel parameters:
export CH_NAME=orderer-system-channel
export CORE_PEER_LOCALMSPID=OrdererMSP
export TLS_ROOT_CA=/etc/hyperledger/fabric/orderer-tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/orderer-msp
export ORDERER_CONTAINER=orderer.example.com Apply capabilities to the system channel groups sequentially:
# 1. Update Orderer Group Capability
jq -s '.[0] * {"channel_group":{"groups":{"Orderer": {"values": {"Capabilities": .[1].orderer}}}}}' \
config.json ./capabilities.json > modified_config.json
# Re-encode and submit transaction via Orderer Admin signatures
# 2. Update Channel Group Capability
jq -s '.[0] * {"channel_group":{"values": {"Capabilities": .[1].channel}}}' \
config.json ./capabilities.json > modified_config.json
# Re-encode and submit transaction via Orderer Admin signatures Update Application Channels
Define the target channel values:
export CH_NAME=mychannel
export CORE_PEER_LOCALMSPID=Org1MSP
export TLS_ROOT_CA=/etc/hyperledger/fabric/peer-tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/peer-msp
export ORDERER_CONTAINER=orderer.example.com Update each group across your application channels:
# 1. Update Orderer Group (Requires Orderer Admin Majority)
jq -s '.[0] * {"channel_group":{"groups":{"Orderer": {"values": {"Capabilities": .[1].orderer}}}}}' \
config.json ./capabilities.json > modified_config.json
# 2. Update Channel Group (Requires Orderer + Peer Admin Majority)
jq -s '.[0] * {"channel_group":{"values": {"Capabilities": .[1].channel}}}' \
config.json ./capabilities.json > modified_config.json
# 3. Update Application Group (Requires Peer Admin Majority)
jq -s '.[0] * {"channel_group":{"groups":{"Application": {"values": {"Capabilities": .[1].application}}}}}' \
config.json ./capabilities.json > modified_config.json Warning: Never specify an invalid or non-existent capability (e.g., typing V20 instead of V2_0). Ordering nodes pass application capabilities directly to peers without validating syntax, which will cause peers to crash permanently upon processing the invalid block.
Step 7: Activate the Fabric 2.0 Chaincode Lifecycle
To use decentralized chaincode governance, append lifecycle policies to your channel configurations.
Update Organization Policies in the System Channel
Export the target consortium settings:
export CH_NAME=orderer-system-channel
export CORE_PEER_LOCALMSPID=OrdererMSP
export ORGNAME=Org1MSP
export CONSORTIUM_NAME=SampleConsortium Merge the lifecycle organization definitions from enable_lifecycle.json:
jq -s ".[0] * {\"channel_group\":{\"groups\":{\"Consortiums\":{\"groups\": {\"$CONSORTIUM_NAME\": {\"groups\": {\"$ORGNAME\": {\"policies\": .[1].${ORGNAME}Policies}}}}}}}}" \
config.json ./enable_lifecycle.json > modified_config.json Update Organization and Endorsement Policies in Application Channels
Export the target application channel configuration variables:
export CH_NAME=mychannel
export ORGNAME=Org1MSP Inject peer organization policies and channel-wide endorsement rules:
# Apply Organization Policies
jq -s ".[0] * {\"channel_group\":{\"groups\":{\"Application\": {\"groups\": {\"$ORGNAME\": {\"policies\": .[1].${ORGNAME}Policies}}}}}}" \
config.json ./enable_lifecycle.json > modified_config.json
# Apply Channel Endorsement Policies
jq -s '.[0] * {"channel_group":{"groups":{"Application": {"policies": .[1].appPolicies}}}}' \
config.json ./enable_lifecycle.json > modified_config.json Update Peer Configuration (core.yaml)
When replacing core.yaml with the official 2.0 artifact, Fabric automatically includes _lifecycle: enable under chaincode/system. If you update an existing configuration file manually, verify that the system whitelist contains this entry:
chaincode:
system:
_lifecycle: enable
cscc: enable
lscc: enable
qscc: enable Execute a chaincode test transaction on each channel to confirm that all nodes, capabilities, and governance policies function properly.