Running JSON API in the container

Hi,

I am looking for some guidance in running JSON API as container. Does anyone know where I can find the documentation?

Kind regards,
Frank

Hi @Frankie

Do you have the JSON API docker container downloaded?

If not then you can use::
docker pull digitalasset-docker.jfrog.io/http-json:2.6.4

you can run the container with the usual flags: e.g.

docker run --name json-api --rm -it digitalasset-docker.jfrog.io/http-json:2.6.4 --http-port 7575 --ledger-host localhost --ledger-port 5011

/Rohit

Small clarification: the above Docker repository is only available to Enterprise Edition users.

If you do not have an Enterprise Edition license (I don’t know what the status of @Frankie is, specifically, but since this is a public forum this is definitely going to be true for some readers), you are using the Community Edition and it does not come with any supported Docker image.

In that case, you’ll have to create your own images. It’s not very hard if you’re familiar with Docker - the JSON API is essentially a single JAR file you can download directly from the GitHub releases page for your specific release, so all you need to do is add that to a Docker image with a JVM - but you’ll have to build it yourself.

Hi @Gary_Verhaegen, I have the EE license and here is the error I got.

command:

docker run --rm -it --add-host=host.docker.internal:host-gateway -p 8080:8080 --volume "$PWD:/canton/jsonapi" digitalasset-docker.jfrog.io/http-json:2.6.3 --config /canton/jsonapi/jsonapi.conf

The query store configuration, I guess there is something wrong here since the connection does not work

  query-store {
    base-config {
      user = "json"
      password = "********"
      driver = "org.postgresql.Driver"
      url = "jdbc:postgresql://host.docker.internal:5432/postgres"

      // prefix for table names to avoid collisions, empty by default
      table-prefix = "foo"

      // max pool size for the database connection pool
      pool-size = 12
      //specifies the min idle connections for database connection pool.
      min-idle = 4
      //specifies the idle timeout for the database connection pool.
      idle-timeout = 12s
      //specifies the connection timeout for database connection pool.
      connection-timeout = 90s
    }
    // option setting how the schema should be handled.
    // Valid options are start-only, create-only, create-if-needed-and-start and create-and-start
    start-mode = "start-only"
  }

2023-06-06 13:55:05.512 [main] INFO  com.daml.http.Main - Config(ledgerHost=127.0.0.1, ledgerPort=10011, address=127.0.0.1, httpPort=8080, portFile=None, packageReloadInterval=5 seconds, packageMaxInboundMessageSize=None, maxInboundMessageSize=4194304, tlsConfig=TlsConfiguration(false,None,None,None,None,REQUIRE,false,None), jdbcConfig=Some(JdbcConfig(driver=org.postgresql.Driver, url=jdbc:postgresql://host.docker.internal:5432/postgres, user=json, start-mode=StartOnly)), staticContentConfig=None, allowNonHttps=true, wsConfig=Some(WebsocketConfig(maxDuration=120 minutes, heartBeatPer=5 seconds)), nonRepudiationCertificateFile=None, nonRepudiationPrivateKeyFile=None, nonRepudiationPrivateKeyAlgorithm=None, surrogateTpIdCacheMaxEntries=None), context: {instance_uuid: "bda3acbb-2e84-405c-b42e-626962f85943"} 
2023-06-06 13:55:05.977 [http-json-ledger-api-akka.actor.default-dispatcher-6] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting... 
2023-06-06 13:55:07.035 [http-json-ledger-api-akka.actor.default-dispatcher-6] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. 
org.postgresql.util.PSQLException: Connection to host.docker.internal:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
	at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:319)
	at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
	at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:223)
	at org.postgresql.Driver.makeConnection(Driver.java:402)
	at org.postgresql.Driver.connect(Driver.java:261)
	at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:136)
	at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:369)
	at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:198)
	at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:467)
	at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:541)
	at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
	at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:81)
	at com.daml.dbutils.ConnectionPool$.dataSource(Connection.scala:69)
	at com.daml.dbutils.ConnectionPool$.connect(Connection.scala:45)
	at com.daml.http.dbbackend.ContractDao$.$anonfun$apply$4(ContractDao.scala:112)
	at scala.util.Either.map(Either.scala:382)
	at com.daml.http.dbbackend.ContractDao$.$anonfun$apply$2(ContractDao.scala:106)
	at scala.util.Either.flatMap(Either.scala:352)
	at com.daml.http.dbbackend.ContractDao$.apply(ContractDao.scala:101)
	at com.daml.http.Main$.$anonfun$main$5(Main.scala:120)
	at scala.Option.map(Option.scala:242)
	at com.daml.http.Main$.$anonfun$main$4(Main.scala:120)
	at scala.concurrent.impl.Promise$Transformation.run(Promise.scala:467)
	at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:63)
	at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:100)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
	at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:94)
	at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:100)
	at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:49)
	at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:48)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
Caused by: java.net.ConnectException: Connection refused (Connection refused)
	at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:412)
	at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:255)
	at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:237)
	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.base/java.net.Socket.connect(Socket.java:609)
	at org.postgresql.core.PGStream.createSocket(PGStream.java:241)
	at org.postgresql.core.PGStream.<init>(PGStream.java:98)
	at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:109)
	at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:235)
	... 34 common frames omitted
2023-06-06 13:55:07.041 [http-json-ledger-api-akka.actor.default-dispatcher-7] ERROR com.daml.http.Main - Cannot start server, context: {instance_uuid: "bda3acbb-2e84-405c-b42e-626962f85943"} 
com.zaxxer.hikari.pool.HikariPool$PoolInitializationException: Failed to initialize pool: Connection to host.docker.internal:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
	at com.zaxxer.hikari.pool.HikariPool.throwPoolInitializationException(HikariPool.java:576)
	at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:562)
	at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
	at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:81)
	at com.daml.dbutils.ConnectionPool$.dataSource(Connection.scala:69)
	at com.daml.dbutils.ConnectionPool$.connect(Connection.scala:45)
	at com.daml.http.dbbackend.ContractDao$.$anonfun$apply$4(ContractDao.scala:112)
	at scala.util.Either.map(Either.scala:382)
	at com.daml.http.dbbackend.ContractDao$.$anonfun$apply$2(ContractDao.scala:106)
	at scala.util.Either.flatMap(Either.scala:352)
	at com.daml.http.dbbackend.ContractDao$.apply(ContractDao.scala:101)
	at com.daml.http.Main$.$anonfun$main$5(Main.scala:120)
	at scala.Option.map(Option.scala:242)
	at com.daml.http.Main$.$anonfun$main$4(Main.scala:120)
	at scala.concurrent.impl.Promise$Transformation.run(Promise.scala:467)
	at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:63)
	at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:100)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
	at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:94)
	at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:100)
	at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:49)
	at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:48)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
Caused by: org.postgresql.util.PSQLException: Connection to host.docker.internal:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
	at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:319)
	at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
	at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:223)
	at org.postgresql.Driver.makeConnection(Driver.java:402)
	at org.postgresql.Driver.connect(Driver.java:261)
	at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:136)
	at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:369)
	at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:198)
	at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:467)
	at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:541)
	... 25 common frames omitted
Caused by: java.net.ConnectException: Connection refused (Connection refused)
	at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:412)
	at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:255)
	at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:237)
	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.base/java.net.Socket.connect(Socket.java:609)
	at org.postgresql.core.PGStream.createSocket(PGStream.java:241)
	at org.postgresql.core.PGStream.<init>(PGStream.java:98)
	at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:109)
	at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:235)
	... 34 common frames omitted


This is a bit outside of my comfort zone, so hopefully someone more knowledgeable about Docker can chime in.

The first thing I’d try in your situation is to remove the HTTP JSON service from the equation: what if instead you started a plain Ubuntu container with the same options, and tried to connect from there? I would expect a psql connection, or even a telnet connection, to fail in the same way as the JSON API here, as the error message looks like a network definition issue rather than a JSON-API-specific issue, but it would be good to confirm.

I have never used the --add-host option on a Docker command (I started using Docker a very long time ago and have not broken the --link habit yet). Can you confirm whether you need to explicitly forward the port? The above error could appear if you have correct DNS setup but the port wasn’t open. Also, I suppose, do confirm that the PostgreSQL server is indeed running on host-gateway, which I assume is a route to your ost machine.

Specifically, try to connect to your local database from the host machine using psql but explicitly telling it to connect to 127.1.2.3:5432. I can think of a few possible issues here: maybe the PostgreSQL server is not listening on a network port, but on a network socket (which I believe is the default, as that is more secure and sufficient for local connections), or maybe it’s listening on a port but exclusively for connections to 127.0.0.1, and the Docker network bridge may appear as another IP in your virtual internal network.

If you’re familiar with lsof -i perhaps that can help confirm how your PostgreSQL server is configured.

That’s unfortunately all I have; as I said this is not an area I’m very familiar with.

Also I found another interesting thing… I can give any value in the ledger api section and the JSON API will start regardless. It doesn’t seem to check or connect to the ledger during start-up. Is that right?

 ledger-api {
    address = "127.0.0.1"
    port = 50011
  }