寫在前面:
本文內容翻譯自:https://chainhero.io/2018/03/tutorial-build-blockchain-app-2/ ,文檔中的命令操做均在實際環境進行驗證,現將成果分享給你們。node
目錄linux
一.概述git
二.安裝環境github
三.安裝Fabric SDK Gogolang
四.啓動區塊鏈網絡docker
五.使用Fabric SDK Govim
一. 概述api
首先,爲新入門的開發小白普及一下何爲SDK網絡
軟件開發工具包(外語首字母縮寫:SDK、外語全稱:Software Development Kit)通常都是一些軟件工程師爲特定的軟件包、軟件框架、硬件平臺、操做系統等創建應用軟件時的開發工具的集合。軟件開發工具包括廣義上指輔助開發某一類軟件的相關文檔、範例和工具的集合。軟件開發工具包是一些被軟件工程師用於爲特定的軟件包、軟件框架、硬件平臺、操做系統等建立應用軟件的開發工具的集合,通常而言SDK即開發 Windows 平臺下的應用程序所使用的 SDK。它能夠簡單的爲某個程序設計語言提供應用程序接口 API 的一些文件,但也可能包括能與某種嵌入式系統通信的複雜的硬件。通常的工具包括用於調試和其餘用途的實用工具。SDK 還常常包括示例代碼、支持性的技術註解或者其餘的爲基本參考資料澄清疑點的支持文檔。爲了鼓勵開發者使用其系統或者語言,許多 SDK 是免費提供的。session
Farbric的Peer節點和Orderer節點都提供了基於GRPC協議(Google開發的遠程過程調用RPC)的接口,經過這些接口能夠和Peer節點與Orderer節點進行命令/數據交互,爲了簡化開發,官方提供了多語言版本的SDK,官網原文
Hyperledger Fabric SDKs Hyperledger Fabric intends to offer a number of SDKs for a wide variety of programming languages. The first two delivered are the Node.js and Java SDKs. We hope to provide Python, REST and Go SDKs in a subsequent release. Hyperledger Fabric Node SDK documentation. Hyperledger Fabric Java SDK documentation.
實際上目前主流支持的已經有Go版本了,列出主流的三個:
考慮到Golang是Fabric原生的開發語言,Fabric,Fabric-ca,Chaincode都是採用Golang開發的,因此本文仍是圍繞Golang版本的Fabric SDK進行闡述SDK的安裝部署與測試。
二.安裝環境
在Ubuntu 16.04上發佈,但Hyperledger Fabric架構與Mac OS X,Windows和其餘Linux發行版兼容。Hyperledger Fabric使用Docker輕鬆部署區塊鏈網絡。 另外,一些組件(同級)也部署docker容器來分離數據(通道)。 因此請確保所使用的平臺支持這種虛擬化。
須要Docker版本17.03.0-ce或更高版本。
$docker -v
返回結果
Docker version 17.12.1-ce, build 7390fc6
查看Docker-Compose版本
$docker-compose version
返回結果
docker-compose version 1.17.1, build unknown docker-py version: 2.5.1 CPython version: 2.7.15rc1 OpenSSL version: OpenSSL 1.1.0g 2 Nov 2017
須要版本1.9.x或更高版本
$go version
返回結果
go version go1.10.3 linux/amd64
查看GOPATH,GOROOT,GOBIN環境變量
$ go env |egrep 'GOROOT|GOPATH|GOBIN'
返回結果
GOBIN="/home/bruce/go/bin" GOPATH="/home/bruce/go" GOROOT="/usr/local/go"
三.安裝Fabric SDK Go
安裝依賴包
$ sudo apt update
$ sudo apt install libltdl-dev
(1) 下載軟件包
$ go get -u github.com/hyperledger/fabric-sdk-go
(2) 安裝依賴包
$ cd $GOPATH/src/github.com/hyperledger/fabric-sdk-go $ chmod +x test/scripts/*.sh # make depend-install操做會調用dependencies.sh腳本 $ make depend //注意1.1.0版本是make depend-install
以上命令會下載以下依賴包並安裝至$GOBIN目錄下
github.com/axw/gocov/... github.com/AlekSi/gocov-xml github.com/client9/misspell/cmd/misspell github.com/golang/lint/golint golang.org/x/tools/cmd/goimports github.com/golang/mock/mockgen
安裝完成後檢查$GOBIN目錄下文件
-rwxrwxr-x 1 bruce bruce 13128127 Jul 19 17:38 dep -rwxrwxr-x 1 bruce bruce 4332114 Jul 19 17:50 gocov -rwxrwxr-x 1 bruce bruce 2752093 Jul 19 17:50 gocov-xml -rwxrwxr-x 1 bruce bruce 5220554 Jul 19 17:50 goimports -rwxrwxr-x 1 bruce bruce 5669065 Jul 19 17:50 golint -rwxrwxr-x 1 bruce bruce 9470763 Jul 19 17:50 misspell -rwxrwxr-x 1 bruce bruce 5070526 Jul 19 17:51 mockgen
(3) 安裝vendor
$ make populate
返回結果
Populate script last ran 07-21-2018 on revision e230c04e with Gopkg.lock revision d489eba9 Populating vendor ... Populating dockerd vendor ... Cloning into 'scripts/_go/src/chaincoded/vendor/github.com/hyperledger/fabric'... remote: Counting objects: 4530, done. remote: Compressing objects: 100% (3778/3778), done. remote: Total 4530 (delta 543), reused 2596 (delta 376), pack-reused 0 Receiving objects: 100% (4530/4530), 16.51 MiB | 120.00 KiB/s, done. Resolving deltas: 100% (543/543), done.
四.啓動區塊鏈網絡
爲了構建區塊鏈網絡,使用docker構建處理不一樣角色的虛擬計算機。 在這裏咱們將盡量保持簡單。 Hyperledger Fabric須要大量證書來確保在整個端到端流程(TSL,身份驗證,簽名塊......)期間進行加密。 建立這些文件須要一點時間,爲了直接瞭解問題的核心,咱們已經在此存儲庫的文件夾中爲您準備了全部相關內容。
在GOPATH的src文件夾中新建一個目錄以下:
$ mkdir -p $GOPATH/src/github.com/ticket $ cd $GOPATH/src/github.com/ticket
新建fixtures文件夾
$ mkdir fixtures
將 channel-artifacts 及 crypto-config 兩個文件夾複製到 fixture 目錄中
$ cd fixtures $ sudo cp -r ~/hyfa/fabric-samples/first-network/channel-artifacts . $ sudo cp -r ~/hyfa/fabric-samples/first-network/crypto-config .
將 channel-artifacts 文件夾名稱修改成 artifacts
$ mv channel-artifacts/ artifacts
移除無用的文件
$ sudo rm -f artifacts/.gitkeep
將 fabric-samples/basic-network/docker-compose.yml 文件複製至當前的 fixtures 目錄下, 進行編輯
$ sudo cp ~/hyfa/fabric-samples/basic-network/docker-compose.yml ./ $ sudo vim docker-compose.yml
(1) 修改網絡模式
version: '2' networks: default:
(2) orderer部分
services: orderer.example.com: container_name: orderer.example.com image: hyperledger/fabric-orderer environment: - ORDERER_GENERAL_LOGLEVEL=debug - 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_LISTENPORT=7050 # 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, /var/hyperledger/peerOrg1/tls/ca.crt, /var/hyperledger/peerOrg2/tls/ca.crt] working_dir: /opt/gopath/src/github.com/hyperledger/fabric command: orderer ports: - 7050:7050 volumes: - ./artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block - ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp - ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls:/var/hyperledger/orderer/tls - ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/:/var/hyperledger/peerOrg1 - ./crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/:/var/hyperledger/peerOrg2 networks: default: aliases: - orderer.example.com
(3) ca配置
ca.org1.example.com: image: hyperledger/fabric-ca environment: - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server - FABRIC_CA_SERVER_CA_NAME=ca.org1.example.com - FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/b4a9a9585aebe52646e1987d4eca4a0ecf3f0ab688ca7924c07249c0303553ba_sk - FABRIC_CA_SERVER_TLS_ENABLED=true - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/b4a9a9585aebe52646e1987d4eca4a0ecf3f0ab688ca7924c07249c0303553ba_sk ports: - "7054:7054" command: sh -c 'fabric-ca-server start -b admin:adminpw -d' volumes: - ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config container_name: ca.org1.example.com networks: default: aliases: - ca.org1.example.com
注意:
FABRIC_CA_SERVER_CA_KEYFILE與FABRIC_CA_SERVER_TLS_KEYFILE的參數值須要設置成
...fixtures/crypto-config/peerOrganizations/org1.example.com/ca目錄下面的私鑰文件,不然會啓動失敗,報錯證書與祕鑰不匹配。
(4) Peer配置
peer0.org1.example.com 內容以下
peer0.org1.example.com:
image: hyperledger/fabric-peer
container_name: peer0.org1.example.com
environment:
peer1.org1.example.com內容以下
peer1.org1.example.com:
image: hyperledger/fabric-peer
container_name: peer1.org1.example.com
environment:
暫時只須要如上功能模塊便可
將 fixtures 文件的所屬修改成當前用戶及組
$ sudo chown -R bruce:bruce ../fixtures
爲了檢查網絡是否正常工做,使用docker-compose同時啓動或中止全部容器。 進入fixtures文件夾,運行:
$ cd $GOPATH/src/github.com/kongyixueyuan.com/bill/fixtures $ docker-compose up
啓動完畢,將看到:兩個peer,orderer和一個CA容器。 表明已成功建立了一個新的網絡,能夠隨SDK一塊兒使用。 要中止網絡,請返回到上一個終端,按Ctrl+C並等待全部容器都中止。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 932b5364664f hyperledger/fabric-peer "peer node start" 26 hours ago Up 26 hours 0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp peer0.org1.example.com cf9385a5e1ae hyperledger/fabric-peer "peer node start" 26 hours ago Up 26 hours 0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp peer1.org1.example.com a1cd2a83af57 hyperledger/fabric-orderer "orderer" 26 hours ago Up 26 hours 0.0.0.0:7050->7050/tcp orderer.example.com 6a9a54d9d82b hyperledger/fabric-ca "/bin/sh -c 'fabric-…" 26 hours ago Up 26 hours 0.0.0.0:7054->7054/tcp ca.org1.example.com
提示 :當網絡中止時,全部使用的容器均可以訪問。 例如,這對檢查日誌很是有用。 能夠用docker ps -a來看它們。 爲了清理這些容器,須要使用docker rm $(docker ps -aq)將其刪除,或者若是使用了docker-compose文件,請轉至此文件的位置並運行docker-compose down 。
提示 :能夠在後臺運行docker-compose命令以保持提示。 爲此,請使用參數-d ,以下所示: docker-compose up -d 。 要中止容器,請在docker-compose.yaml所在的文件夾中運行命令: docker-compose stop (或docker-compose down進行清理中止全部容器)。
五.使用Fabric SDK Go
1.建立配置文件
$ cd $GOPATH/src/github.com/ticket $ vim config.yaml
配置文件內容以下:
name: "ticket-network" # Describe what the target network is/does. description: "The network which will host my first blockchain" # Schema version of the content. Used by the SDK to apply the corresponding parsing rules. version: 2 # The client section used by GO SDK. client: # Which organization does this application instance belong to? The value must be the name of an org organization: Org1 logging: level: info # Global configuration for peer, event service and orderer timeouts peer: timeout: connection: 3s queryResponse: 45s executeTxResponse: 30s eventService: timeout: connection: 3s registrationResponse: 3s orderer: timeout: connection: 3s response: 5s # Root of the MSP directories with keys and certs. The Membership Service Providers is component that aims to offer an abstraction of a membership operation architecture. cryptoconfig: path: "${GOPATH}/src/github.com/kongyixueyuan.com/bill/fixtures/crypto-config" # Some SDKs support pluggable KV stores, the properties under "credentialStore" are implementation specific credentialStore: path: "/tmp/bill-kvs" # [Optional]. Specific to the CryptoSuite implementation used by GO SDK. Software-based implementations requiring a key store. PKCS#11 based implementations does not. cryptoStore: path: "/tmp/bill-msp" # BCCSP config for the client. Used by GO SDK. It's the Blockchain Cryptographic Service Provider. # It offers the implementation of cryptographic standards and algorithms. BCCSP: security: enabled: true default: provider: "SW" hashAlgorithm: "SHA2" softVerify: true ephemeral: false level: 256 tlsCerts: systemCertPool: false # [Optional]. But most apps would have this section so that channel objects can be constructed based on the content below. # If one of your application is creating channels, you might not use this channels: mychannel: orderers: - orderer.example.com # Network entity which maintains a ledger and runs chaincode containers in order to perform operations to the ledger. Peers are owned and maintained by members. peers: peer0.org1.example.com: # [Optional]. will this peer be sent transaction proposals for endorsement? The peer must # have the chaincode installed. The app can also use this property to decide which peers # to send the chaincode install request. Default: true endorsingPeer: true # [Optional]. will this peer be sent query proposals? The peer must have the chaincode # installed. The app can also use this property to decide which peers to send the # chaincode install request. Default: true chaincodeQuery: true # [Optional]. will this peer be sent query proposals that do not require chaincodes, like # queryBlock(), queryTransaction(), etc. Default: true ledgerQuery: true # [Optional]. will this peer be the target of the SDK's listener registration? All peers can # produce events but the app typically only needs to connect to one to listen to events. # Default: true eventSource: true peer1.org1.example.com: # List of participating organizations in this network organizations: Org1: mspid: Org1MSP cryptoPath: "peerOrganizations/org1.example.com/users/{userName}@org1.example.com/msp" peers: - peer0.org1.example.com - peer1.org1.example.com certificateAuthorities: - ca.org1.example.com # List of orderers to send transaction and channel create/update requests to. # The orderers consent on the order of transactions in a block to be committed to the ledger. For the time being only one orderer is needed. orderers: orderer.example.com: url: grpcs://localhost:7050 grpcOptions: ssl-target-name-override: orderer.example.com grpc-max-send-message-length: 15 tlsCACerts: path: "${GOPATH}/src/github.com/ticket/fixtures/crypto-config/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem" # List of peers to send various requests to, including endorsement, query and event listener registration. peers: peer0.org1.example.com: # this URL is used to send endorsement and query requests url: grpcs://localhost:7051 # this URL is used to connect the EventHub and registering event listeners eventUrl: grpcs://localhost:7053 # These parameters should be set in coordination with the keepalive policy on the server grpcOptions: ssl-target-name-override: peer0.org1.example.com grpc.http2.keepalive_time: 15 tlsCACerts: path: "${GOPATH}/src/github.com/ticket/fixtures/crypto-config/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem" peer1.org1.example.com: url: grpcs://localhost:8051 eventUrl: grpcs://localhost:8053 grpcOptions: ssl-target-name-override: peer1.org1.example.com grpc.http2.keepalive_time: 15 tlsCACerts: # Certificate location absolute path path: "${GOPATH}/src/github.com/ticket/fixtures/crypto-config/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem" # Fabric-CA is a special kind of Certificate Authority provided by Hyperledger Fabric which allows certificate management to be done via REST APIs. certificateAuthorities: ca.org1.example.com: url: https://localhost:7054 # the properties specified under this object are passed to the 'http' client verbatim when making the request to the Fabric-CA server httpOptions: verify: false registrar: enrollId: admin enrollSecret: adminpw caName: ca.org1.example.com
以上配置文件模板能夠經過config.yaml獲取
建立一個blockchain的新文件夾,其中將包含與區塊鏈網絡通信的全部接口。
$ mkdir blockchain $ vim blockchain/setup.go
代碼以下
package blockchain import ( "github.com/hyperledger/fabric-sdk-go/api/apitxn/resmgmtclient" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/pkg/config" "fmt" "github.com/hyperledger/fabric-sdk-go/api/apitxn/chmgmtclient" "time" ) //定義結構體 type FabricSetup struct { ConfigFile string //sdk配置文件所在路徑 ChannelID string //應用通道名稱 ChannelConfig string //應用通道交易配置文件所在路徑 OrgAdmin string // 組織管理員名稱 OrgName string //組織名稱 Initialized bool //是否初始化 Admin resmgmtclient.ResourceMgmtClient //fabric環境中資源管理者 SDK *fabsdk.FabricSDK //SDK實例 } //1. 建立SDK實例並使用SDK實例建立應用通道,將Peer節點加入到建立的應用通道中 func (f *FabricSetup) Initialize() error { //判斷是否已經初始化 if f.Initialized { return fmt.Errorf("SDK已被實例化") } //建立SDK對象 sdk, err := fabsdk.New(config.FromFile(f.ConfigFile)) if err != nil { return fmt.Errorf("SDK實例化失敗:%v", err) } f.SDK = sdk //建立一個具備管理權限的應用通道客戶端管理對象 chmClient, err := f.SDK.NewClient(fabsdk.WithUser(f.OrgAdmin), fabsdk.WithOrg(f.OrgName)).ChannelMgmt() if err != nil { return fmt.Errorf("建立應用通道管理客戶端管理對象失敗,%v", err) } //獲取當前的會話用戶對象 session, err := f.SDK.NewClient(fabsdk.WithUser(f.OrgAdmin), fabsdk.WithOrg(f.OrgName)).Session() if err != nil { return fmt.Errorf("獲取當前會話用戶對象失敗%v", err) } orgAdminUser := session //指定建立應用通道所須要的全部參數 /* $ peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls --cafile \ /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem */ chReq := chmgmtclient.SaveChannelRequest{ChannelID: f.ChannelID, ChannelConfig: f.ChannelConfig, SigningIdentity: orgAdminUser} //建立應用通道 err = chmClient.SaveChannel(chReq) if err != nil { return fmt.Errorf("建立應用通道失敗:%v", err) } time.Sleep(time.Second * 5) //建立一個管理資源的客戶端對象 f.Admin, err = f.SDK.NewClient(fabsdk.WithUser(f.OrgAdmin)).ResourceMgmt() if err != nil { return fmt.Errorf("建立資源管理對象失敗:%v", err) } //將peer 節點加入到應用通道中 err = f.Admin.JoinChannel(f.ChannelID) if err != nil { return fmt.Errorf("peer加入節點失敗:%v", err) } f.Initialized = true fmt.Println("SDK實例化成功") return nil }
該測試代碼能夠從blockchain/setup.go獲取
在這個階段
初始化一個客戶端,它將與 peer,CA 和 orderer進行通訊。
爲了確保客戶端可以初始化全部組件,將在啓動網絡的狀況下進行簡單的測試。 爲了作到這一點,咱們須要構建主程序代碼進行功能調用
$ vim main.go package main import ( "FabricDev/ticket/blockchain" "os" "fmt" ) func main() { fsetup := blockchain.FabricSetup{ ConfigFile: "config.yaml", ChannelID: "mychannel", ChannelConfig: os.Getenv("GOPATH") + "src/github.com/ticket/fixtures/artifacts/channel.tx", OrgAdmin: "Admin", OrgName: "Org1", } err := fsetup.Initialize() if err != nil { fmt.Errorf("Fabric SDK初始化失敗:%v", err) fmt.Println(err.Error()) } }
代碼模板:main.go
在開始編譯以前,最後一件事是使用一個vendor目錄來包含咱們全部的依賴關係。 在咱們的GOPATH中,咱們有Fabric SDK Go和其餘項目。 當嘗試編譯應用程序時,Golang會在GOPATH中搜索依賴項,但首先會檢查項目中是否存在vendor文件夾。 若是依賴性獲得知足,那麼Golang就不會去看GOPATH或GOROOT。 這在使用幾個不一樣版本的依賴關係時很是有用(可能會發生一些衝突,好比在例子中有多個BCCSP定義,經過使用像dep這樣的工具來處理這些依賴關係在vendor目錄中。
$ vim Gopkg.toml
配置文件內容
[[constraint]] name = "github.com/hyperledger/fabric" revision = "014d6befcf67f3787bb3d67ff34e1a98dc6aec5f" [[constraint]] name = "github.com/hyperledger/fabric-sdk-go" revision = "614551a752802488988921a730b172dada7def1d"
這是dep一個限制,以便在 vendor 中指定但願SDK轉到特定版本。
保存該文件,而後執行此命令將vendor目錄與項目的依賴關係同步:
$ dep ensure $ls vendor -l //查看vendor目錄內容 drwxrwxr-x 13 bruce bruce 4096 Jul 20 14:06 github.com drwxrwxr-x 3 bruce bruce 4096 Jul 20 14:06 golang.org drwxrwxr-x 4 bruce bruce 4096 Jul 20 14:06 google.golang.org drwxrwxr-x 3 bruce bruce 4096 Jul 20 14:06 gopkg.in
5.構建代碼
$go build //構建代碼生成ticket可執行文件 $ls ticket -l -rwxrwxr-x 1 bruce bruce 19784971 Jul 20 14:06 ticket
6.執行命令
$ ./ticket [fabric_sdk_go] 2018/07/21 09:19:23 UTC - config.initConfig -> INFO config fabric_sdk_go logging level is set to: INFO SDK實例化成功
7.清理環境
Fabric SDK生成一些文件,如證書,二進制文件和臨時文件。 關閉網絡不會徹底清理環境,當須要從新啓動時,這些文件將被重複使用以免構建過程。 對於開發,能夠快速測試,但對於真正的測試,須要清理全部內容並從頭開始。
如何清理環境
docker ps -a --no-trunc | grep "bill" | cut -d ' ' -f 1
2>/dev/nulldocker images --no-trunc | grep "bill" | cut -d ' ' -f 1
2>/dev/null如何更有效率?
能夠在一個步驟中自動完成全部這些任務。 構建和啓動過程也能夠自動化。 爲此,將建立一個Makefile。 首先,確保 make 工具:
make --version
若是沒有安裝make (Ubuntu):
sudo apt install make
而後使用如下內容在項目的根目錄下建立一個名爲Makefile的文件:
$ cd $GOPATH/src/github.com/kongyixueyuan.com/bill $ vim Makefile .PHONY: all dev clean build env-up env-down run all: clean build env-up run dev: build run ##### BUILD build: @echo "Build ..." @dep ensure @go build @echo "Build done" ##### ENV env-up: @echo "Start environment ..." @cd fixtures && docker-compose up --force-recreate -d @echo "Sleep 15 seconds in order to let the environment setup correctly" @sleep 15 @echo "Environment up" env-down: @echo "Stop environment ..." @cd fixtures && docker-compose down @echo "Environment down" ##### RUN run: @echo "Start app ..." @./ticket ##### CLEAN clean: env-down @echo "Clean up ..." @rm -rf /tmp/bill-* bill @docker rm -f -v `docker ps -a --no-trunc | grep "ticket" | cut -d ' ' -f 1` 2>/dev/null || true @docker rmi `docker images --no-trunc | grep "ticket" | cut -d ' ' -f 1` 2>/dev/null || true @echo "Clean up done"
如今完成任務:
要使用它,請進入項目的根目錄並使用make命令: