From a8d294f08a00a6992a615ebb445b95567b652f17 Mon Sep 17 00:00:00 2001 From: Moritz Kiefer Date: Thu, 28 Aug 2025 09:44:09 +0000 Subject: [PATCH 1/5] Expose ledger API in docker compose setup fixes #2038 [ci] This keeps coming up every few days so rather than copy pasting the config snippet around let's just include it. Signed-off-by: Moritz Kiefer --- ...poseValidatorFrontendIntegrationTest.scala | 36 +++++++++++++++++-- cluster/compose/validator/nginx.conf | 28 +++++++++++++++ docs/src/release_notes.rst | 4 +++ .../validator_operator/validator_compose.rst | 21 +++++++++++ 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/DockerComposeValidatorFrontendIntegrationTest.scala b/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/DockerComposeValidatorFrontendIntegrationTest.scala index d3680e9c83..0c88f89e85 100644 --- a/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/DockerComposeValidatorFrontendIntegrationTest.scala +++ b/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/DockerComposeValidatorFrontendIntegrationTest.scala @@ -67,6 +67,9 @@ class DockerComposeValidatorFrontendIntegrationTest } "docker-compose based validator works" in { implicit env => + implicit val actorSystem: ActorSystem = env.actorSystem + registerHttpConnectionPoolsCleanup(env) + val aliceTap = 123.4 val adminTap = 234.5 @@ -132,6 +135,37 @@ class DockerComposeValidatorFrontendIntegrationTest // Take a backup of the validator Seq("build-tools/splice-compose.sh", "backup_node", backupsDir.toString) ! + clue("JSON ledger API is exposed") { + val response = + Http().singleRequest(Get("http://json-ledger-api.localhost/v2/version")).futureValue + response.status should be(StatusCodes.OK) + response.entity.toStrict(10.seconds).futureValue.data.utf8String should include( + "\"version\":\"3." // check that it reports a version. We don't care about the exact version + ) + } + + clue("GRPC ledger API is exposed") { + import com.digitalasset.canton.ledger.client.GrpcChannel + import scala.util.Using + val channelConfig = com.digitalasset.canton.ledger.client.configuration + .LedgerClientChannelConfiguration(sslContext = None) + implicit val releasableChannel: Using.Releasable[io.grpc.ManagedChannel] = + (resource: io.grpc.ManagedChannel) => { + GrpcChannel.close(resource) + } + Using.resource( + channelConfig + .builderFor("grpc-ledger-api.localhost", 80) + .executor(env.executionContext) + .build + ) { channel => + import com.daml.ledger.api.v2.version_service.* + val stub = VersionServiceGrpc.stub(channel) + val version = stub.getLedgerApiVersion(GetLedgerApiVersionRequest()).futureValue + version.version should startWith("3.") + } + } + } // Restore the node from backup @@ -256,8 +290,6 @@ class DockerComposeValidatorFrontendIntegrationTest } clue("validator and participant metrics work") { - implicit val sys: ActorSystem = env.actorSystem - registerHttpConnectionPoolsCleanup(env) def metricsAreAvailableFor(node: String) = { val result = Http() diff --git a/cluster/compose/validator/nginx.conf b/cluster/compose/validator/nginx.conf index 949ad83f6d..c735123f65 100644 --- a/cluster/compose/validator/nginx.conf +++ b/cluster/compose/validator/nginx.conf @@ -42,4 +42,32 @@ http { proxy_pass http://participant:10013/metrics; } } + + server { + listen 80; + server_name json-ledger-api.localhost; + location / { + proxy_pass http://participant:7575; + } + } + + server { + listen 80 http2; + server_name grpc-ledger-api.localhost; + location / { + grpc_pass grpc://participant:5001; + } + } + + # Note: There is no auth at the admin API at this point so this is not exposed + # exposed by default. If you need it during development, you can enable this section. + # If you need access in prod, make sure to protect access otherwise, e.g., through network restrictions. + # server { + # listen 80; + # http2 on; + # server_name grpc-admin-api.localhost; + # location / { + # grpc_pass grpc://participant:5002; + # } + # } } diff --git a/docs/src/release_notes.rst b/docs/src/release_notes.rst index c126c7ef0f..5a072bb196 100644 --- a/docs/src/release_notes.rst +++ b/docs/src/release_notes.rst @@ -39,6 +39,10 @@ Upcoming - Canton/Sequencer Messages dashboard now includes hourly totals, and a pie chart of the distribution of message types over the last 24 hours. +- Validator Compose Deployment + + - Expose Canton ledger API by default. Reference the :ref:`docs ` for details. + - Daml - Fix a bug where activity record expiration had a reference to the ``AmuletRules`` contract which resulted in transactions diff --git a/docs/src/validator_operator/validator_compose.rst b/docs/src/validator_operator/validator_compose.rst index 24cfcce7cd..7f95953df1 100644 --- a/docs/src/validator_operator/validator_compose.rst +++ b/docs/src/validator_operator/validator_compose.rst @@ -138,6 +138,27 @@ You can open your browser at http://ans.localhost (note that this is currently b `ans` and not `cns`), and login using the same administrator user, or any other user that has been onboarded via the wallet, in order to purchase a CNS entry for that user. +.. _compose_canton_apis: + +Accessing the Canton Participant APIs +------------------------------------- + +The `JSON Ledger API `_ +is exposed under ``json-ledger-api.localhost:80``. Note that for some +clients you may explicitly need to set the ``Host: +json-ledger-api.localhost`` header for this to get resolved correctly. + +The `gRPC Ledger API +`_ +is exposed under ``grpc-ledger-api.localhost:80``. Note that for some +clients you may explicitly need to set the ``:authority: +json-ledger-api.localhost`` pseudo-header for this to get resolved correctly. + +The Canton Admin API is not exposed by default as it does not yet +support auth. There is a commented out section in ``nginx.conf`` that +you can enable to expose it if you ensure that it is not exposed +publicly, e.g., through network restrictions. + .. _compose_validator_auth: From c5c4d9e4735c35032d884761a28f15a877eac783 Mon Sep 17 00:00:00 2001 From: Moritz Kiefer Date: Fri, 29 Aug 2025 06:33:27 +0000 Subject: [PATCH 2/5] align localnet and docker compose setups [ci] Signed-off-by: Moritz Kiefer --- .../localnet/conf/nginx/app-provider.conf | 27 ++++++++++++++----- .../compose/localnet/conf/nginx/app-user.conf | 26 +++++++++++++----- cluster/compose/validator/nginx.conf | 1 + 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/cluster/compose/localnet/conf/nginx/app-provider.conf b/cluster/compose/localnet/conf/nginx/app-provider.conf index c5e3733190..dd5d0c14c3 100644 --- a/cluster/compose/localnet/conf/nginx/app-provider.conf +++ b/cluster/compose/localnet/conf/nginx/app-provider.conf @@ -10,21 +10,34 @@ server { } } +# Deprecated, use json-ledger-api.localhost instead server { listen ${APP_PROVIDER_UI_PORT}; server_name canton.localhost; - location /docs/openapi { - proxy_pass http://canton:3${PARTICIPANT_JSON_API_PORT_SUFFIX}/docs/openapi; - include /etc/nginx/includes/cors-headers.conf; + location / { + proxy_pass http://canton:3${PARTICIPANT_JSON_API_PORT_SUFFIX}; + include /etc/nginx/includes/cors-headers.conf; } +} - location /v2 { - include /etc/nginx/includes/cors-options-headers.conf; - proxy_pass http://canton:3${PARTICIPANT_JSON_API_PORT_SUFFIX}/v2; - include /etc/nginx/includes/cors-headers.conf; +server { + listen ${APP_PROVIDER_UI_PORT}; + server_name json-ledger-api.localhost; + location / { + proxy_pass http://participant:3${PARTICIPANT_JSON_API_PORT_SUFFIX}; + include /etc/nginx/includes/cors-headers.conf; } } +server { + listen ${APP_PROVIDER_UI_PORT} http2; + server_name grpc-ledger-api.localhost; + location / { + grpc_pass grpc://participant:3${PARTICIPANT_LEDGER_API_PORT_SUFFIX}; + } +} + + server { listen ${APP_PROVIDER_UI_PORT}; server_name wallet.localhost; diff --git a/cluster/compose/localnet/conf/nginx/app-user.conf b/cluster/compose/localnet/conf/nginx/app-user.conf index c8ddc5d402..1e999bebfa 100644 --- a/cluster/compose/localnet/conf/nginx/app-user.conf +++ b/cluster/compose/localnet/conf/nginx/app-user.conf @@ -10,18 +10,30 @@ server { } } +# Deprecated, use json-ledger-api.localhost instead server { listen ${APP_USER_UI_PORT}; server_name canton.localhost; - location /docs/openapi { - proxy_pass http://canton:2${PARTICIPANT_JSON_API_PORT_SUFFIX}/docs/openapi; - include /etc/nginx/includes/cors-headers.conf; + location / { + proxy_pass http://canton:2${PARTICIPANT_JSON_API_PORT_SUFFIX}; + include /etc/nginx/includes/cors-headers.conf; + } +} + +server { + listen ${APP_USER_UI_PORT}; + server_name json-ledger-api.localhost; + location / { + proxy_pass http://participant:2${PARTICIPANT_JSON_API_PORT_SUFFIX}; + include /etc/nginx/includes/cors-headers.conf; } +} - location /v2 { - include /etc/nginx/includes/cors-options-headers.conf; - proxy_pass http://canton:2${PARTICIPANT_JSON_API_PORT_SUFFIX}/v2; - include /etc/nginx/includes/cors-headers.conf; +server { + listen ${APP_USER_UI_PORT} http2; + server_name grpc-ledger-api.localhost; + location / { + grpc_pass grpc://participant:2${PARTICIPANT_LEDGER_API_PORT_SUFFIX}; } } diff --git a/cluster/compose/validator/nginx.conf b/cluster/compose/validator/nginx.conf index c735123f65..5f8d117091 100644 --- a/cluster/compose/validator/nginx.conf +++ b/cluster/compose/validator/nginx.conf @@ -48,6 +48,7 @@ http { server_name json-ledger-api.localhost; location / { proxy_pass http://participant:7575; + include /etc/nginx/includes/cors-headers.conf; } } From c6109cd9f6daedcda6cf105de6947a4d892d8c7e Mon Sep 17 00:00:00 2001 From: Moritz Kiefer Date: Fri, 29 Aug 2025 08:15:06 +0000 Subject: [PATCH 3/5] fix config [ci] Signed-off-by: Moritz Kiefer --- cluster/compose/localnet/conf/nginx/app-provider.conf | 4 ++-- cluster/compose/localnet/conf/nginx/app-user.conf | 4 ++-- cluster/compose/validator/compose.yaml | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cluster/compose/localnet/conf/nginx/app-provider.conf b/cluster/compose/localnet/conf/nginx/app-provider.conf index dd5d0c14c3..b907d2dd5d 100644 --- a/cluster/compose/localnet/conf/nginx/app-provider.conf +++ b/cluster/compose/localnet/conf/nginx/app-provider.conf @@ -24,7 +24,7 @@ server { listen ${APP_PROVIDER_UI_PORT}; server_name json-ledger-api.localhost; location / { - proxy_pass http://participant:3${PARTICIPANT_JSON_API_PORT_SUFFIX}; + proxy_pass http://canton:3${PARTICIPANT_JSON_API_PORT_SUFFIX}; include /etc/nginx/includes/cors-headers.conf; } } @@ -33,7 +33,7 @@ server { listen ${APP_PROVIDER_UI_PORT} http2; server_name grpc-ledger-api.localhost; location / { - grpc_pass grpc://participant:3${PARTICIPANT_LEDGER_API_PORT_SUFFIX}; + grpc_pass grpc://canton:3${PARTICIPANT_LEDGER_API_PORT_SUFFIX}; } } diff --git a/cluster/compose/localnet/conf/nginx/app-user.conf b/cluster/compose/localnet/conf/nginx/app-user.conf index 1e999bebfa..994d5222fe 100644 --- a/cluster/compose/localnet/conf/nginx/app-user.conf +++ b/cluster/compose/localnet/conf/nginx/app-user.conf @@ -24,7 +24,7 @@ server { listen ${APP_USER_UI_PORT}; server_name json-ledger-api.localhost; location / { - proxy_pass http://participant:2${PARTICIPANT_JSON_API_PORT_SUFFIX}; + proxy_pass http://canton:2${PARTICIPANT_JSON_API_PORT_SUFFIX}; include /etc/nginx/includes/cors-headers.conf; } } @@ -33,7 +33,7 @@ server { listen ${APP_USER_UI_PORT} http2; server_name grpc-ledger-api.localhost; location / { - grpc_pass grpc://participant:2${PARTICIPANT_LEDGER_API_PORT_SUFFIX}; + grpc_pass grpc://canton:2${PARTICIPANT_LEDGER_API_PORT_SUFFIX}; } } diff --git a/cluster/compose/validator/compose.yaml b/cluster/compose/validator/compose.yaml index 17c18990f1..04014b061c 100644 --- a/cluster/compose/validator/compose.yaml +++ b/cluster/compose/validator/compose.yaml @@ -150,6 +150,7 @@ services: image: "nginx:${NGINX_VERSION}" volumes: - ./nginx.conf:/etc/nginx/nginx.conf + - ./nginx:/etc/nginx/includes ports: - 80:80 depends_on: From fe0d2823869546b4a37018dc52e40c098ae04a43 Mon Sep 17 00:00:00 2001 From: Moritz Kiefer Date: Fri, 29 Aug 2025 09:21:01 +0000 Subject: [PATCH 4/5] try to log validator nginx [ci] Signed-off-by: Moritz Kiefer --- build-tools/splice-compose.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-tools/splice-compose.sh b/build-tools/splice-compose.sh index 948a5f9c11..a257fd11aa 100755 --- a/build-tools/splice-compose.sh +++ b/build-tools/splice-compose.sh @@ -57,7 +57,7 @@ function _do_start_validator { "$@" \ | tee -a "${SPLICE_ROOT}/log/compose.log" 2>&1 || _error "Failed to start validator, please check ${SPLICE_ROOT}/log/compose.log for details" - for c in validator participant; do + for c in validator participant nginx; do docker logs -f splice-validator-${c}-1 >> "${SPLICE_ROOT}/log/compose-${c}.clog" 2>&1 & done From 853bd07c121a0cbd464740afe3f1932e681a25ee Mon Sep 17 00:00:00 2001 From: Moritz Kiefer Date: Fri, 29 Aug 2025 09:42:55 +0000 Subject: [PATCH 5/5] why am i so dumb [ci] Signed-off-by: Moritz Kiefer --- cluster/compose/validator/nginx/cors-headers.conf | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 cluster/compose/validator/nginx/cors-headers.conf diff --git a/cluster/compose/validator/nginx/cors-headers.conf b/cluster/compose/validator/nginx/cors-headers.conf new file mode 100644 index 0000000000..49cf42d5b6 --- /dev/null +++ b/cluster/compose/validator/nginx/cors-headers.conf @@ -0,0 +1,3 @@ +add_header Access-Control-Allow-Origin *; +add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; +add_header Access-Control-Allow-Headers 'Origin, Content-Type, Accept';