Add Docker image as output of build (#4223)

This commit is contained in:
Stefano Franz 2018-11-20 13:38:44 +00:00 committed by Michele Sollecito
parent 8827801ae6
commit bbd5369e04
12 changed files with 603 additions and 0 deletions

64
docker/build.gradle Normal file
View File

@ -0,0 +1,64 @@
evaluationDependsOn(":node:capsule")
buildscript {
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.bmuschko:gradle-docker-plugin:3.4.4'
}
}
import com.bmuschko.gradle.docker.DockerRemoteApiPlugin
import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
apply plugin: 'kotlin'
apply plugin: DockerRemoteApiPlugin
apply plugin: 'application'
// We need to set mainClassName before applying the shadow plugin.
mainClassName = 'net.corda.core.ConfigExporterMain'
apply plugin: 'com.github.johnrengelman.shadow'
dependencies{
compile project(':node')
}
shadowJar {
baseName = 'config-exporter'
classifier = null
version = null
zip64 true
}
task buildDockerFolder(dependsOn: [":node:capsule:buildCordaJAR", shadowJar]) {
doLast {
def cordaJar = project(":node:capsule").buildCordaJAR.archivePath
project.copy {
into new File(project.buildDir, "docker-temp")
from "src/bash/run-corda.sh"
from cordaJar
from shadowJar.archivePath
from "src/config/starting-node.conf"
from "src/bash/generate-config.sh"
from "src/docker/Dockerfile"
rename(cordaJar.name, "corda.jar")
rename(shadowJar.archivePath.name, "config-exporter.jar")
}
}
}
task buildOfficialDockerImage(type: DockerBuildImage, dependsOn: [buildDockerFolder]) {
final String runTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))
//if we are a snapshot, append a timestamp
//if we are a release, append RELEASE
final String suffix = project.version.toString().toLowerCase().contains("snapshot") ? runTime : "RELEASE"
inputDir = new File(project.buildDir, "docker-temp")
tags = ["corda/corda-${project.version.toString().toLowerCase()}:${suffix}", "corda/corda-${project.version.toString().toLowerCase()}:latest"]
}

View File

@ -0,0 +1,19 @@
#!/usr/bin/env bash
docker run -ti \
-e MY_PUBLIC_ADDRESS="corda-node.example.com" \
-e ONE_TIME_DOWNLOAD_KEY="bbcb189e-9e4f-4b27-96db-134e8f592785" \
-e LOCALITY="London" -e COUNTRY="GB" \
-v $(pwd)/docker/config:/etc/corda \
-v $(pwd)/docker/certificates:/opt/corda/certificates \
corda/corda-4.0-snapshot:latest config-generator --testnet
docker run -ti \
--memory=2048m \
--cpus=2 \
-v $(pwd)/docker/config:/etc/corda \
-v $(pwd)/docker/certificates:/opt/corda/certificates \
-v $(pwd)/docker/persistence:/opt/corda/persistence \
-v $(pwd)/docker/logs:/opt/corda/logs \
-v $(pwd)/samples/bank-of-corda-demo/build/nodes/BankOfCorda/cordapps:/opt/corda/cordapps \
corda/corda-4.0-snapshot:latest

View File

@ -0,0 +1,27 @@
#!/usr/bin/env bash
##in this example the doorman will be running on the host machine on port 8080
##so the container must be launched with "host" networking
docker run -ti --net="host" \
-e MY_LEGAL_NAME="O=EXAMPLE,L=Berlin,C=DE" \
-e MY_PUBLIC_ADDRESS="corda.example-hoster.com" \
-e NETWORKMAP_URL="https://map.corda.example.com" \
-e DOORMAN_URL="https://doorman.corda.example.com" \
-e NETWORK_TRUST_PASSWORD="trustPass" \
-e MY_EMAIL_ADDRESS="cordauser@r3.com" \
-v $(pwd)/docker/config:/etc/corda \
-v $(pwd)/docker/certificates:/opt/corda/certificates \
corda/corda-4.0-snapshot:latest config-generator --generic
##set memory to 2gb max, and 2cores max
docker run -ti \
--memory=2048m \
--cpus=2 \
-v $(pwd)/docker/config:/etc/corda \
-v $(pwd)/docker/certificates:/opt/corda/certificates \
-v $(pwd)/docker/persistence:/opt/corda/persistence \
-v $(pwd)/docker/logs:/opt/corda/logs \
-v $(pwd)/samples/bank-of-corda-demo/build/nodes/BankOfCorda/cordapps:/opt/corda/cordapps \
-p 10200:10200 \
-p 10201:10201 \
corda/corda-4.0-snapshot:latest

View File

@ -0,0 +1,124 @@
#!/usr/bin/env bash
die() {
printf '%s\n' "$1" >&2
exit 1
}
show_help(){
echo "usage: generate-config <--testnet>|<--generic>"
echo -e "\t --testnet is used to generate config and certificates for joining TestNet"
echo -e "\t --generic is used to generate config and certificates for joining an existing Corda Compatibility Zone"
}
function generateTestnetConfig() {
RPC_PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) \
DB_PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) \
MY_PUBLIC_ADDRESS=${MY_PUBLIC_ADDRESS} \
MY_P2P_PORT=${MY_P2P_PORT} \
MY_RPC_PORT=${MY_RPC_PORT} \
MY_RPC_ADMIN_PORT=${MY_RPC_ADMIN_PORT} \
NETWORKMAP_URL='https://map.testnet.corda.network' \
DOORMAN_URL='https://doorman.testnet.corda.network' \
java -jar config-exporter.jar "TEST-NET-COMBINE" "node.conf" "/opt/corda/starting-node.conf" "${CONFIG_FOLDER}/node.conf"
}
function generateGenericCZConfig(){
: ${NETWORKMAP_URL:? '$NETWORKMAP_URL, the Compatibility Zone to join must be set as environment variable'}
: ${DOORMAN_URL:? '$DOORMAN_URL, the Doorman to use when joining must be set as environment variable'}
: ${MY_LEGAL_NAME:? '$MY_LEGAL_NAME, the X500 name to use when joining must be set as environment variable'}
: ${MY_EMAIL_ADDRESS:? '$MY_EMAIL_ADDRESS, the email to use when joining must be set as an environment variable'}
: ${NETWORK_TRUST_PASSWORD=:? '$NETWORK_TRUST_PASSWORD, the password to the network store to use when joining must be set as environment variable'}
if [[ ! -f ${CERTIFICATES_FOLDER}/${TRUST_STORE_NAME} ]]; then
die "Network Trust Root file not found"
fi
RPC_PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) \
DB_PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) \
MY_PUBLIC_ADDRESS=${MY_PUBLIC_ADDRESS} \
MY_P2P_PORT=${MY_P2P_PORT} \
MY_RPC_PORT=${MY_RPC_PORT} \
MY_RPC_ADMIN_PORT=${MY_RPC_ADMIN_PORT} \
java -jar config-exporter.jar "GENERIC-CZ" "/opt/corda/starting-node.conf" "${CONFIG_FOLDER}/node.conf"
java -Djava.security.egd=file:/dev/./urandom -Dcapsule.jvm.args="${JVM_ARGS}" -jar /opt/corda/bin/corda.jar \
initial-registration \
--base-directory=/opt/corda \
--config-file=/etc/corda/node.conf \
--network-root-truststore-password=${NETWORK_TRUST_PASSWORD} \
--network-root-truststore=${CERTIFICATES_FOLDER}/${TRUST_STORE_NAME}
}
function downloadTestnetCerts() {
if [[ ! -f ${CERTIFICATES_FOLDER}/certs.zip ]]; then
: ${ONE_TIME_DOWNLOAD_KEY:? '$ONE_TIME_DOWNLOAD_KEY must be set as environment variable'}
: ${LOCALITY:? '$LOCALITY (the locality used when registering for Testnet) must be set as environment variable'}
: ${COUNTRY:? '$COUNTRY (the country used when registering for Testnet) must be set as environment variable'}
curl -L -d "{\"x500Name\":{\"locality\":\"${LOCALITY}\", \"country\":\"${COUNTRY}\"}, \"configType\": \"INSTALLSCRIPT\", \"include\": { \"systemdServices\": false, \"cordapps\": false, \"cordaJar\": false, \"cordaWebserverJar\": false, \"scripts\": false} }" \
-H 'Content-Type: application/json' \
-X POST "https://testnet.corda.network/api/user/node/generate/one-time-key/redeem/$ONE_TIME_DOWNLOAD_KEY" \
-o "${CERTIFICATES_FOLDER}/certs.zip"
fi
rm -rf ${CERTIFICATES_FOLDER}/*.jks
unzip ${CERTIFICATES_FOLDER}/certs.zip
}
GENERATE_TEST_NET=0
GENERATE_GENERIC=0
while :; do
case $1 in
-h|-\?|--help)
show_help # Display a usage synopsis.
exit
;;
-t|--testnet)
if [[ ${GENERATE_GENERIC} = 0 ]]; then
GENERATE_TEST_NET=1
else
die 'ERROR: cannot generate config for multiple networks'
fi
;;
-g|--generic)
if [[ ${GENERATE_TEST_NET} = 0 ]]; then
GENERATE_GENERIC=1
else
die 'ERROR: cannot generate config for multiple networks'
fi
;;
--) # End of all options.
shift
break
;;
-?*)
printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
;;
*) # Default case: No more options, so break out of the loop.
break
esac
shift
done
: ${TRUST_STORE_NAME="network-root-truststore.jks"}
: ${JVM_ARGS='-Xmx4g -Xms2g -XX:+UseG1GC'}
if [[ ${GENERATE_TEST_NET} == 1 ]]
then
: ${MY_PUBLIC_ADDRESS:? 'MY_PUBLIC_ADDRESS must be set as environment variable'}
downloadTestnetCerts
generateTestnetConfig
elif [[ ${GENERATE_GENERIC} == 1 ]]
then
: ${MY_PUBLIC_ADDRESS:? 'MY_PUBLIC_ADDRESS must be set as environment variable'}
generateGenericCZConfig
else
show_help
die "No Valid Configuration requested"
fi

10
docker/src/bash/run-corda.sh Executable file
View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
: ${JVM_ARGS='-XX:+UseG1GC'}
JVM_ARGS="-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap "${JVM_ARGS}
if [[ ${JVM_ARGS} == *"Xmx"* ]]; then
echo "WARNING: the use of the -Xmx flag is not recommended within docker containers. Use the --memory option passed to the container to limit heap size"
fi
java -Djava.security.egd=file:/dev/./urandom -Dcapsule.jvm.args="${JVM_ARGS}" -jar /opt/corda/bin/corda.jar --base-directory=/opt/corda --config-file=/etc/corda/node.conf

View File

@ -0,0 +1,39 @@
myLegalName=${MY_LEGAL_NAME}
p2pAddress=${MY_PUBLIC_ADDRESS}":"${MY_P2P_PORT}
rpcSettings {
address="0.0.0.0:"${MY_RPC_PORT}
adminAddress="0.0.0.0:"${MY_RPC_ADMIN_PORT}
}
security {
authService {
dataSource {
type=INMEMORY
users=[
{
password=${RPC_PASSWORD}
permissions=[
ALL
]
user=rpcUser
}
]
}
}
}
networkServices : {
doormanURL = ${DOORMAN_URL}
networkMapURL = ${NETWORKMAP_URL}
}
detectPublicIp = false
dataSourceProperties {
dataSource {
password=${DB_PASSWORD}
url="jdbc:h2:file:/opt/corda/persistence/persistence;DB_CLOSE_ON_EXIT=FALSE;WRITE_DELAY=0;LOCK_TIMEOUT=10000"
user="sa"
}
dataSourceClassName="org.h2.jdbcx.JdbcDataSource"
}
emailAddress = ${MY_EMAIL_ADDRESS}

View File

@ -0,0 +1,70 @@
FROM azul/zulu-openjdk:8u192
RUN apt-get update && apt-get -y upgrade && apt-get -y install bash curl unzip
# Create dirs
RUN mkdir -p /opt/corda/cordapps
RUN mkdir -p /opt/corda/persistence
RUN mkdir -p /opt/corda/certificates
RUN mkdir -p /opt/corda/drivers
RUN mkdir -p /opt/corda/logs
RUN mkdir -p /opt/corda/bin
RUN mkdir -p /opt/corda/additional-node-infos
RUN mkdir -p /etc/corda
# Create corda user
RUN addgroup corda && \
useradd corda -g corda -m -d /opt/corda
WORKDIR /opt/corda
ENV CORDAPPS_FOLDER="/opt/corda/cordapps"
ENV PERSISTENCE_FOLDER="/opt/corda/persistence"
ENV CERTIFICATES_FOLDER="/opt/corda/certificates"
ENV DRIVERS_FOLDER="/opt/corda/drivers"
ENV CONFIG_FOLDER="/etc/corda"
ENV MY_P2P_PORT=10200
ENV MY_RPC_PORT=10201
ENV MY_RPC_ADMIN_PORT=10202
RUN chown -R corda:corda /opt/corda
RUN chown -R corda:corda /etc/corda
##CORDAPPS FOLDER
VOLUME ["/opt/corda/cordapps"]
##PERSISTENCE FOLDER
VOLUME ["/opt/corda/persistence"]
##CERTS FOLDER
VOLUME ["/opt/corda/certificates"]
##OPTIONAL JDBC DRIVERS FOLDER
VOLUME ["/opt/corda/drivers"]
##LOG FOLDER
VOLUME ["/opt/corda/logs"]
##ADDITIONAL NODE INFOS FOLDER
VOLUME ["/opt/corda/additional-node-infos"]
##CONFIG LOCATION
VOLUME ["/etc/corda"]
##CORDA JAR
ADD --chown=corda:corda corda.jar /opt/corda/bin/corda.jar
##CONFIG MANIPULATOR JAR
ADD --chown=corda:corda config-exporter.jar /opt/corda/config-exporter.jar
##CONFIG GENERATOR SHELL SCRIPT
ADD --chown=corda:corda generate-config.sh /opt/corda/bin/config-generator
##CORDA RUN SCRIPT
ADD --chown=corda:corda run-corda.sh /opt/corda/bin/run-corda
##BASE CONFIG FOR GENERATOR
ADD --chown=corda:corda starting-node.conf /opt/corda/starting-node.conf
##SET EXECUTABLE PERMISSIONS
RUN chmod +x /opt/corda/bin/config-generator
RUN chmod +x /opt/corda/bin/run-corda
ENV PATH=$PATH:/opt/corda/bin
EXPOSE $MY_P2P_PORT
EXPOSE $MY_RPC_PORT
USER "corda"
CMD ["run-corda"]

View File

@ -0,0 +1,84 @@
@file:JvmName("ConfigExporterMain")
package net.corda.core
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigRenderOptions
import com.typesafe.config.ConfigValueFactory
import net.corda.common.configuration.parsing.internal.Configuration
import net.corda.common.validation.internal.Validated
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.parseAsNodeConfiguration
import net.corda.nodeapi.internal.config.toConfig
import net.corda.nodeapi.internal.config.toConfigValue
import java.io.File
class ConfigExporter {
fun combineTestNetWithOurConfig(testNetConf: String, ourConf: String, outputFile: String) {
var ourParsedConfig = ConfigFactory.parseFile(File(ourConf))
val testNetParsedConfig = ConfigFactory.parseFile(File(testNetConf))
ourParsedConfig = ourParsedConfig.withValue("keyStorePassword", testNetParsedConfig.getValue("keyStorePassword"))
ourParsedConfig = ourParsedConfig.withValue("myLegalName", testNetParsedConfig.getValue("myLegalName"))
ourParsedConfig = ourParsedConfig.withValue("trustStorePassword", testNetParsedConfig.getValue("trustStorePassword"))
ourParsedConfig = ourParsedConfig.withValue("emailAddress", testNetParsedConfig.getValue("emailAddress"))
File(outputFile).writer().use { fileWriter ->
val finalConfig = ourParsedConfig.parseAsNodeConfigWithFallback().value().toConfig()
var configToWrite = ConfigFactory.empty()
ourParsedConfig.entrySet().sortedBy { it.key }.forEach { configEntry ->
//use all keys present in "ourConfig" but get values from "finalConfig"
val keyWithoutQuotes = configEntry.key.replace("\"", "")
println("creating config key: $keyWithoutQuotes with value: ${finalConfig.getValue(keyWithoutQuotes)}")
configToWrite = configToWrite.withValue(keyWithoutQuotes, finalConfig.getValue(keyWithoutQuotes))
}
fileWriter.write(configToWrite.root().render(ConfigRenderOptions.concise().setFormatted(true).setJson(false)))
}
}
fun buildGenericCZConfig(ourConf: String, outputFile: String){
val ourParsedConfig = ConfigFactory.parseFile(File(ourConf))
File(outputFile).writer().use { fileWriter ->
val finalConfig = ourParsedConfig.parseAsNodeConfigWithFallback().value().toConfig()
var configToWrite = ConfigFactory.empty()
ourParsedConfig.entrySet().sortedBy { it.key }.forEach { configEntry ->
//use all keys present in "ourConfig" but get values from "finalConfig"
val keyWithoutQuotes = configEntry.key.replace("\"", "")
println("creating config key: $keyWithoutQuotes with value: ${finalConfig.getValue(keyWithoutQuotes)}")
configToWrite = configToWrite.withValue(keyWithoutQuotes, finalConfig.getValue(keyWithoutQuotes))
}
fileWriter.write(configToWrite.root().render(ConfigRenderOptions.concise().setFormatted(true).setJson(false)))
}
}
}
fun Config.parseAsNodeConfigWithFallback(): Validated<NodeConfiguration, Configuration.Validation.Error> {
val referenceConfig = ConfigFactory.parseResources("reference.conf")
val nodeConfig = this
.withValue("baseDirectory", ConfigValueFactory.fromAnyRef("/opt/corda"))
.withFallback(referenceConfig)
.resolve()
return nodeConfig.parseAsNodeConfiguration()
}
fun main(args: Array<String>) {
val configExporter = ConfigExporter()
val command = args[0]
when (command) {
"TEST-NET-COMBINE" -> {
val testNetConf = args[1]
val ourConf = args[2]
val outputFile = args[3]
configExporter.combineTestNetWithOurConfig(testNetConf, ourConf, outputFile)
}
"GENERIC-CZ" -> {
val ourConf = args[1]
val outputFile = args[2]
configExporter.buildGenericCZConfig(ourConf, outputFile)
}
else -> {
throw IllegalArgumentException("Unknown command: $command")
}
}
}

View File

@ -15,6 +15,7 @@ CorDapps
upgrade-notes
upgrading-cordapps
secure-coding-guidelines
flow-overriding
corda-api
flow-cookbook
cheat-sheet

View File

@ -6,6 +6,7 @@ Nodes
node-structure
generating-a-node
docker-image
running-a-node
deploying-a-node
corda-configuration-file

View File

@ -0,0 +1,163 @@
Official Corda Docker Image
===========================
Running a Node connected to a Compatibility Zone in Docker
----------------------------------------------------------
.. note:: Requirements: A valid node.conf and a valid set of certificates - (signed by the CZ)
In this example, the certificates are stored at ``/home/user/cordaBase/certificates``, the node configuration is in ``/home/user/cordaBase/config/node.conf`` and the CorDapps to run are in ``/home/TeamCityOutput/cordapps``
.. code-block:: shell
docker run -ti \
--memory=2048m \
--cpus=2 \
-v /home/user/cordaBase/config:/etc/corda \
-v /home/user/cordaBase/certificates:/opt/corda/certificates \
-v /home/user/cordaBase/persistence:/opt/corda/persistence \
-v /home/user/cordaBase/logs:/opt/corda/logs \
-v /home/TeamCityOutput/cordapps:/opt/corda/cordapps \
-p 10200:10200 \
-p 10201:10201 \
corda/corda-4.0-snapshot:latest
As the node runs within a container, several mount points are required
1. CorDapps - CorDapps must be mounted at location ``/opt/corda/cordapps``
2. Certificates - certificates must be mounted at location ``/opt/corda/certificates``
3. Config - the node config must be mounted at location ``/etc/corda/node.config``
4. Logging - all log files will be written to location ``/opt/corda/logs``
If using the H2 database
5. Persistence - the folder to hold the H2 database files must be mounted at location ``/opt/corda/persistence``
Running a Node connected to a Bootstrapped Network
--------------------------------------------------
.. note:: Requirements: A valid node.conf, a valid set of certificates, and an existing network-parameters file
In this example, we have previously generated a network-parameters file using the bootstrapper tool, which is stored at ``/home/user/sharedFolder/network-parameters``
.. code-block:: shell
docker run -ti \
--memory=2048m \
--cpus=2 \
-v /home/user/cordaBase/config:/etc/corda \
-v /home/user/cordaBase/certificates:/opt/corda/certificates \
-v /home/user/cordaBase/persistence:/opt/corda/persistence \
-v /home/user/cordaBase/logs:/opt/corda/logs \
-v /home/TeamCityOutput/cordapps:/opt/corda/cordapps \
-v /home/user/sharedFolder/node-infos:/opt/corda/additional-node-infos \
-v /home/user/sharedFolder/network-parameters:/opt/corda/network-parameters \
-p 10200:10200 \
-p 10201:10201 \
corda/corda-4.0-snapshot:latest
There is a new mount ``/home/user/sharedFolder/node-infos:/opt/corda/additional-node-infos`` which is used to hold the ``nodeInfo`` of all the nodes within the network.
As the node within the container starts up, it will place it's own nodeInfo into this directory. This will allow other nodes also using this folder to see this new node.
Generating Configs and Certificates
===================================
It is possible to utilize the image to automatically generate a sensible minimal configuration for joining an existing Corda network.
Joining TestNet
---------------
.. note:: Requirements: A valid registration for TestNet and a one-time code for joining TestNet.
.. code-block:: shell
docker run -ti \
-e MY_PUBLIC_ADDRESS="corda-node.example.com" \
-e ONE_TIME_DOWNLOAD_KEY="bbcb189e-9e4f-4b27-96db-134e8f592785" \
-e LOCALITY="London" -e COUNTRY="GB" \
-v /home/user/docker/config:/etc/corda \
-v /home/user/docker/certificates:/opt/corda/certificates \
corda/corda-4.0-snapshot:latest config-generator --testnet
``$MY_PUBLIC_ADDRESS`` will be the public address that this node will be advertised on.
``$ONE_TIME_DOWNLOAD_KEY`` is the one-time code provided for joining TestNet.
``$LOCALITY`` and ``$COUNTRY`` must be set to the values provided when joining TestNet.
When the container has finished executing ``config-generator`` the following will be true
1. A skeleton, but sensible minimum node.conf is present in ``/home/user/docker/config``
2. A set of certificates signed by TestNet in ``/home/user/docker/certificates``
It is now possible to start the node using the generated config and certificates
.. code-block:: shell
docker run -ti \
--memory=2048m \
--cpus=2 \
-v /home/user/docker/config:/etc/corda \
-v /home/user/docker/certificates:/opt/corda/certificates \
-v /home/user/docker/persistence:/opt/corda/persistence \
-v /home/user/docker/logs:/opt/corda/logs \
-v /home/user/corda/samples/bank-of-corda-demo/build/nodes/BankOfCorda/cordapps:/opt/corda/cordapps \
-p 10200:10200 \
-p 10201:10201 \
corda/corda-4.0-snapshot:latest
Joining An Existing Compatibility Zone
--------------------------------------
.. note:: Requirements: A Compatibility Zone, the Zone Trust Root and authorisation to join said Zone.
It is possible to use the image to automate the process of joining an existing Zone as detailed `here <joining-a-compatibility-zone.html#connecting-to-a-compatibility-zone>`__
The first step is to obtain the Zone Trust Root, and place it within a directory. In the below example, the Trust Root is stored at ``/home/user/docker/certificates/network-root-truststore.jks``.
It is possible to configure the name of the Trust Root file by setting the ``TRUST_STORE_NAME`` environment variable in the container.
.. code-block:: shell
docker run -ti --net="host" \
-e MY_LEGAL_NAME="O=EXAMPLE,L=Berlin,C=DE" \
-e MY_PUBLIC_ADDRESS="corda.example-hoster.com" \
-e NETWORKMAP_URL="https://map.corda.example.com" \
-e DOORMAN_URL="https://doorman.corda.example.com" \
-e NETWORK_TRUST_PASSWORD="trustPass" \
-e MY_EMAIL_ADDRESS="cordauser@r3.com" \
-v /home/user/docker/config:/etc/corda \
-v /home/user/docker/certificates:/opt/corda/certificates \
corda/corda-4.0-snapshot:latest config-generator --generic
Several environment variables must also be passed to the container to allow it to register:
1. ``MY_LEGAL_NAME`` - The X500 to use when generating the config. This must be the same as registered with the Zone.
2. ``MY_PUBLIC_ADDRESS`` - The public address to advertise the node on.
3. ``NETWORKMAP_URL`` - The address of the Zone's network map service (this should be provided to you by the Zone).
4. ``DOORMAN_URL`` - The address of the Zone's doorman service (this should be provided to you by the Zone).
5. ``NETWORK_TRUST_PASSWORD`` - The password to the Zone Trust Root (this should be provided to you by the Zone).
6. ``MY_EMAIL_ADDRESS`` - The email address to use when generating the config. This must be the same as registered with the Zone.
There are some optional variables which allow customisation of the generated config:
1. ``MY_P2P_PORT`` - The port to advertise the node on (defaults to 10200). If changed, ensure the container is launched with the correct published ports.
2. ``MY_RPC_PORT`` - The port to open for RPC connections to the node (defaults to 10201). If changed, ensure the container is launched with the correct published ports.
Once the container has finished performing the initial registration, the node can be started as normal
.. code-block:: shell
docker run -ti \
--memory=2048m \
--cpus=2 \
-v /home/user/docker/config:/etc/corda \
-v /home/user/docker/certificates:/opt/corda/certificates \
-v /home/user/docker/persistence:/opt/corda/persistence \
-v /home/user/docker/logs:/opt/corda/logs \
-v /home/user/corda/samples/bank-of-corda-demo/build/nodes/BankOfCorda/cordapps:/opt/corda/cordapps \
-p 10200:10200 \
-p 10201:10201 \
corda/corda-4.0-snapshot:latest

View File

@ -14,6 +14,7 @@ include 'client:jfx'
include 'client:mock'
include 'client:rpc'
include 'djvm'
include 'docker'
include 'djvm:cli'
include 'webserver'
include 'webserver:webcapsule'