Deploying the REST server for a business network
When deploying the Hyperledger Composer REST server in a production environment, for example using Docker Swarm or Kubernetes, the REST server should be configured to be highly available. This means that you must deploy multiple instances of the REST server, and those instances should be configured to share data. For example, data such as connection profiles, Blockchain identities, and REST API authentication settings should be shared so that a REST API client can make a request to any of the instances without having to reauthenticate.
Business network cards and the business network card store
The REST server uses a business network card specified during startup to connect to and discover the assets, participants, and transactions within a deployed business network. This information is required in order to generate the REST API. This business network card is known as the discovery business network card. By default, the discovery business network card is also used to handle all requests to the REST API. However the REST server can also be configured to multiple user mode, which allows authenticated users to supply their own business network cards for handling requests to the REST API.
In order to use a discovery business network card, that business network card must first be imported into a business network card store available to the REST server. The default business network card store is a local file system directory with the path ~/.composer
(where ~
is the current users home directory). When using the Docker image for the REST server, you must mount a volume into place of the default business network card store that contains an imported discovery business network card. In the Docker image for the REST server, the business network card store used by the REST server is in the directory /home/composer/.composer
(because the REST server in the Docker image always runs under the composer
user).
A business network card contains a connection profile that describes how to connect to the Hyperledger Fabric network where the deployed business network is running. Note that the connection profile must be valid for use within the Docker image for the REST server, and the hostnames must be correct and accessible by this Docker image.
Configuring the REST server with a persistent data store
All information regarding authenticated users and their wallets (containing that users business network cards when multiple user mode is enabled) is persisted in a LoopBack data source by using a LoopBack connector. By default, the REST server uses the LoopBack "memory" connector to persist user information, which is lost when the REST server is terminated. The REST server should be configured with a LoopBack connector that stores data in a highly available data source, for example a database.
You should be able to use any LoopBack connector, but we recommend that you use a LoopBack connector for a NoSQL database. For example, MongoDB or Apache CouchDB.
The LoopBack connector needs to be installed in order for the REST server to locate and use it. You can install additional LoopBack connectors by using npm
, for example:
npm install -g loopback-connector-mongodb
Finally, you need to supply the REST server with the connection information required by the LoopBack connector. This connection information should be supplied by using the COMPOSER_DATASOURCES
environment variable. For more information on the environment variables that can be used to configure the REST server, see the reference documentation: Hyperledger Composer REST Server
Extending the Docker image for the REST server with additional Node.js modules
In order to deploy the REST server as a Docker container with additional LoopBack connectors and Passport strategies, you must extend the hyperledger/composer-rest-server
Docker image.
Here is an example Dockerfile that adds the LoopBack connector for MongoDB and the Passport strategy for GitHub to the Docker image:
FROM hyperledger/composer-rest-server
RUN npm install --production loopback-connector-mongodb passport-github && \
npm cache clean --force && \
ln -s node_modules .node_modules
You can build this Docker image by placing the Dockerfile above into a directory and using the docker build
command, for example:
docker build -t myorg/my-composer-rest-server .
You may need to publish this Docker image to a Docker image repository, for example Docker Hub, in order to use it with cloud based Docker deployment services.
Deploying a persistent and secured REST server using Docker
The following example will demonstrate how to deploy the REST server using Docker. The deployed REST server will persist data using MongoDB, and will be secured using GitHub authentication.
The examples are based on the business network that is deployed to Hyperledger Fabric v1.0 as part of the Developer Tutorial, and may need adjusting for your configuration, for example if the Docker network name does not match.
Ensure that a valid business network card for your business network is in your local business network card store by running the following
composer network ping
command. This example uses a business network card for theadmin
user on themy-network
business network:composer network ping -c admin@my-network
Note that you must use the
composer network ping
command to test the connection to the business network before proceeding. If the business network card only contains a user ID and enrollment secret, then thecomposer network ping
command will trigger the enrollment process to occur and certificates to be stored in the business network card. It is not advisable to use a business network card with only a user ID and enrollment secret when using the Docker image for the REST server.Start an instance of the Docker image for MongoDB named
mongo
. This MongoDB instance will be used to persist all information regarding authenticated users and their wallets (containing that users business network cards when multiple user mode is enabled) for the REST server.docker run -d --name mongo --network composer_default -p 27017:27017 mongo
Note that the MongoDB instance is attached to the Docker network named
composer_default
. This means that the MongoDB instance will be available on the Docker network namedcomposer_default
using the hostnamemongo
. We will use the hostnamemongo
to configure the REST server in a subsequent step. Depending on your Docker networking configuration, you may need to specify a different Docker network name. The MongoDB port27017
is also exposed on the host network using port27017
, so you can use other MongoDB client applications to interact with this MongoDB instance if desired.Extend the Docker image for the REST server by adding the LoopBack connector for MongoDB and the Passport strategy for GitHub authentication. Create a new, empty directory on your local file system, and create a new file named
Dockerfile
in the new directory, with the following contents:FROM hyperledger/composer-rest-server RUN npm install --production loopback-connector-mongodb passport-github && \ npm cache clean --force && \ ln -s node_modules .node_modules
Build the extended Docker image by running the following
docker build
command in the directory containing the file namedDockerfile
that you just created:docker build -t myorg/my-composer-rest-server .
If this command completes successfully, a new Docker image called
myorg/my-composer-rest-server
has been built and stored in the local Docker registry on your system. If you wish to use this Docker image on other systems, you may need to push the Docker image into a Docker registry, such as Docker Hub.The Docker image for the REST server is configured using environment variables rather than command line options. Create a new file named
envvars.txt
to store the environment variables for our REST server, with the following contents:COMPOSER_CARD=admin@my-network COMPOSER_NAMESPACES=never COMPOSER_AUTHENTICATION=true COMPOSER_MULTIUSER=true COMPOSER_PROVIDERS='{ "github": { "provider": "github", "module": "passport-github", "clientID": "REPLACE_WITH_CLIENT_ID", "clientSecret": "REPLACE_WITH_CLIENT_SECRET", "authPath": "/auth/github", "callbackURL": "/auth/github/callback", "successRedirect": "/", "failureRedirect": "/" } }' COMPOSER_DATASOURCES='{ "db": { "name": "db", "connector": "mongodb", "host": "mongo" } }'
Note that the name of the discovery business network card
admin@my-network
has been set as the value of theCOMPOSER_CARD
environment variable. We have disabled namespaces in the generated REST API by specifyingnever
as the value of theCOMPOSER_NAMESPACES
environment variable. We have enabled authentication of REST API clients by setting theCOMPOSER_AUTHENTICATION
environment variable totrue
, and also enabled multi-user mode by setting theCOMPOSER_MULTIUSER
environment variable totrue
.We have configured our REST server to use GitHub authentication by configuring the Passport strategy for GitHub in the
COMPOSER_PROVIDERS
environment variable. Note that you must replace bothREPLACE_WITH_CLIENT_ID
andREPLACE_WITH_CLIENT_SECRET
with the appropriate configuration from GitHub in order for this configuration to work successfully.We have configured our REST server to use our MongoDB instance by configuring the LoopBack connector for MongoDB in the
COMPOSER_DATASOURCES
environment variable. Note that the host name of the MongoDB instance,mongo
, has been specified in thehost
property of the LoopBack data source nameddb
.Load the environment variables into your current shell by running the following command:
source envvars.txt
If you open a new shell, for example a new terminal window or tab, then you must run the same
source
command again to load the environment variables into the new shell.For more information on the environment variables that can be used to configure the REST server, see the reference documentation: Hyperledger Composer REST Server
Start a new instance of the extended Docker image for the REST server that you created in step 3 by running the following
docker run
command:docker run \ -d \ -e COMPOSER_CARD=${COMPOSER_CARD} \ -e COMPOSER_NAMESPACES=${COMPOSER_NAMESPACES} \ -e COMPOSER_AUTHENTICATION=${COMPOSER_AUTHENTICATION} \ -e COMPOSER_MULTIUSER=${COMPOSER_MULTIUSER} \ -e COMPOSER_PROVIDERS="${COMPOSER_PROVIDERS}" \ -e COMPOSER_DATASOURCES="${COMPOSER_DATASOURCES}" \ -v ~/.composer:/home/composer/.composer \ --name rest \ --network composer_default \ -p 3000:3000 \ myorg/my-composer-rest-server
Note that we have passed through all of the environment variables that we set in previous steps by using multiple
-e
options. If you need to add or remove any additional environment variables to configure the REST server, then you must add or remove the appropriate-e
options as well.We have mounted our local business network card store into the REST server Docker container by specifying
-v ~/.composer:/home/composer/.composer
. This permits the REST server to access and use our local business network card store when trying to load the discovery business network card specified using theCOMPOSER_CARD
environment variable.We have also specified the Docker network name
composer_default
, and name of the Docker container asrest
. This means that the REST server instance will be available on the Docker network namedcomposer_default
using the hostnamerest
. The REST server port3000
is also exposed on the host network using port3000
.You can check that the REST server has started successfully by using the
docker logs
command, for example:docker logs -f rest
If the REST server has started successfully, then you will see it output a log message similar to
Browse your REST API at http://localhost:3000/explorer
.
Now that the REST server has started successfully, you can access the REST server running inside the Docker container by using the following URL: http://localhost:3000/explorer/.
Final notes
In this guide, you have seen how to start a single instance of the REST server using Docker, where that single instance is configured to use MongoDB as a persistent data store. For a true highly available, production deployment of the REST server, you will need to:
- Configure a highly available instance of the persistent data store, for example a MongoDB replica set.
- Run multiple instances of the REST server Docker image. This is easy to do by changing the name of the Docker container using the
--name
argument, and updating or removing the host port mapping for subsequent REST server instances using the-p 3000:3000
argument. - Deploy a load balancer, for example Nginx, to distribute REST requests from clients across all of the instances of the REST server.
Once you have performed these three tasks, you should be able to stop, restart, or remove any of the REST server instances (but not all!) without losing access to the deployed business network over REST.