Connection issues with Python/Java SDK with local Docker Cluster

Hello im trying learn Couchbase for an Universityproject.

I’m having trouble using a Local Couchbase Cluster in Docker with any SDK.

I can setup 3 Nodes in Docker connect them via the Management tool and load the “travel-sample” bucket.

Queries in the Web-UI work just fine but as soon as I try to use any SDK to connect I run into problems.

I tried using the Java SDK and the Python version but I can’t get them to work and I don’t really understand the problem.

Any help or tipps would be appreciated.

This is the Java example I tried to run import com.couchbase.client.java.;
import com.couchbase.client.java.kv.
;
import com.couchbase.client.java.json.;
import com.couchbase.client.java.query.
;
import java.time.Duration;

public class StartUsing {
// Update these variables to point to your Couchbase Server instance and credentials.
static String connectionString = “couchbase://localhost”;
static String username = “Administrator”;
static String password = “123456”;
static String bucketName = “travel-sample”;

public static void main(String... args) {
    Cluster cluster = Cluster.connect(connectionString, username, password);

    // get a bucket reference
    Bucket bucket = cluster.bucket(bucketName);
    bucket.waitUntilReady(Duration.parse("PT10S")) ;

    // get a user defined collection reference
    Scope scope = bucket.scope("tenant_agent_00");
    Collection collection = scope.collection("users");

    // Upsert Document
    MutationResult upsertResult = collection.upsert(
            "my-document",
            JsonObject.create().put("name", "mike")
    );

    // Get Document
    GetResult getResult = collection.get("my-document");
    String name = getResult.contentAsObject().getString("name");
    System.out.println(name); // name == "mike"

    // Call the query() method on the cluster object and store the result.
    QueryResult result = cluster.query("select \"Hello World\" as greeting");

    // Return the result rows with the rowsAsObject() method and print to the terminal.
    System.out.println(result.rowsAsObject());
}

}

The output is the Following:

/Users/jonathandeissler/Library/Java/JavaVirtualMachines/openjdk-18/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=60731:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/jonathandeissler/Documents/BDEA/CA_3/java_test/test_couchbase/target/classes:/Users/jonathandeissler/.m2/repository/com/couchbase/client/java-client/3.3.0/java-client-3.3.0.jar:/Users/jonathandeissler/.m2/repository/com/couchbase/client/core-io/2.3.0/core-io-2.3.0.jar:/Users/jonathandeissler/.m2/repository/io/projectreactor/reactor-core/3.4.17/reactor-core-3.4.17.jar:/Users/jonathandeissler/.m2/repository/org/reactivestreams/reactive-streams/1.0.3/reactive-streams-1.0.3.jar StartUsing
Jun 05, 2022 6:27:49 PM com.couchbase.client.core.cnc.LoggingEventConsumer$JdkLogger info
INFO: [com.couchbase.core][DnsSrvLookupFailedEvent][90ms] DNS SRV lookup failed (name not found), trying to bootstrap from given hostname directly.
Jun 05, 2022 6:27:49 PM com.couchbase.client.core.cnc.LoggingEventConsumer$JdkLogger info
INFO: [com.couchbase.core][CoreCreatedEvent] {“clientVersion”:“3.3.0”,“clientGitHash”:"${buildNumber}",“coreVersion”:“2.3.0”,“coreGitHash”:"${buildNumber}",“userAgent”:“couchbase-java/3.3.0 (Mac OS X 12.3.1 aarch64; OpenJDK 64-Bit Server VM 18+36-2087)”,“maxNumRequestsInRetry”:32768,“ioEnvironment”:{“nativeIoEnabled”:true,“eventLoopThreadCount”:4,“eventLoopGroups”:[“NioEventLoopGroup”]},“ioConfig”:{“captureTraffic”:,“mutationTokensEnabled”:true,“networkResolution”:“auto”,“dnsSrvEnabled”:true,“tcpKeepAlivesEnabled”:true,“tcpKeepAliveTimeMs”:60000,“configPollIntervalMs”:2500,“kvCircuitBreakerConfig”:“disabled”,“queryCircuitBreakerConfig”:“disabled”,“viewCircuitBreakerConfig”:“disabled”,“searchCircuitBreakerConfig”:“disabled”,“analyticsCircuitBreakerConfig”:“disabled”,“managerCircuitBreakerConfig”:“disabled”,“eventingCircuitBreakerConfig”:“disabled”,“backupCircuitBreakerConfig”:“disabled”,“numKvConnections”:1,“maxHttpConnections”:12,“idleHttpConnectionTimeoutMs”:4500,“configIdleRedialTimeoutMs”:300000,“memcachedHashingStrategy”:“StandardMemcachedHashingStrategy”},“compressionConfig”:{“enabled”:true,“minRatio”:0.83,“minSize”:32},“securityConfig”:{“tlsEnabled”:false,“nativeTlsEnabled”:true,“hostnameVerificationEnabled”:true,“trustCertificates”:null,“trustManagerFactory”:null,“ciphers”:},“timeoutConfig”:{“kvMs”:2500,“kvDurableMs”:10000,“managementMs”:75000,“queryMs”:75000,“viewMs”:75000,“searchMs”:75000,“analyticsMs”:75000,“connectMs”:10000,“disconnectMs”:10000,“eventingMs”:75000,“backupMs”:75000},“loggerConfig”:{“customLogger”:null,“fallbackToConsole”:false,“consoleLogLevel”:{“name”:“INFO”,“resourceBundleName”:“sun.util.logging.resources.logging”,“localizedName”:“INFO”},“disableSlf4j”:false,“loggerName”:“CouchbaseLogger”,“diagnosticContextEnabled”:false},“orphanReporterConfig”:{“emitIntervalMs”:10000,“sampleSize”:10,“queueLength”:1024,“enabled”:true},“thresholdLoggingTracerConfig”:{“enabled”:true,“emitIntervalMs”:10000,“sampleSize”:10,“queueLength”:1024,“kvThresholdMs”:500,“queryThresholdMs”:1000,“searchThresholdMs”:1000,“analyticsThresholdMs”:1000,“viewThresholdMs”:1000},“loggingMeterConfig”:{“enabled”:true,“emitIntervalMs”:600000},“retryStrategy”:“BestEffortRetryStrategy”,“requestTracer”:“ThresholdLoggingTracer”,“meter”:“LoggingMeter”,“numRequestCallbacks”:0,“scheduler”:“ParallelScheduler”,“schedulerThreadCount”:8,“transactionsConfig”:{“durabilityLevel”:“MAJORITY”,“timeoutMs”:15000,“cleanupConfig”:{“runLostAttemptsCleanupThread”:true,“runRegularAttemptsCleanupThread”:true,“cleanupWindowMs”:60000,“cleanupSet”:""},“numAtrs”:1024,“metadataCollection”:“none”,“scanConsistency”:“none”}} {“coreId”:“0xcf94def100000001”,“seedNodes”:[{“address”:“localhost”}]}
Jun 05, 2022 6:27:49 PM com.couchbase.client.core.cnc.LoggingEventConsumer$JdkLogger info
INFO: [com.couchbase.transactions.cleanup.regular][LogEvent] Starting background cleanup thread to find transactions from this client
Jun 05, 2022 6:27:49 PM com.couchbase.client.core.cnc.LoggingEventConsumer$JdkLogger info
INFO: [com.couchbase.transactions][TransactionsStartedEvent] Transactions successfully initialised, regular cleanup enabled=true, lost cleanup enabled=true
Jun 05, 2022 6:27:49 PM com.couchbase.client.core.cnc.LoggingEventConsumer$JdkLogger info
INFO: [com.couchbase.node][NodeConnectedEvent] Node connected {“coreId”:“0xcf94def100000001”,“managerPort”:“8091”,“remote”:“localhost”}
Jun 05, 2022 6:27:49 PM com.couchbase.client.core.cnc.LoggingEventConsumer$JdkLogger info
INFO: [com.couchbase.node][NodeConnectedEvent] Node connected {“coreId”:“0xcf94def100000001”,“managerPort”:“8091”,“remote”:“172.17.0.2”}
Jun 05, 2022 6:27:49 PM com.couchbase.client.core.cnc.LoggingEventConsumer$JdkLogger info
INFO: [com.couchbase.node][NodeConnectedEvent] Node connected {“coreId”:“0xcf94def100000001”,“managerPort”:“8091”,“remote”:“172.17.0.3”}
Jun 05, 2022 6:27:49 PM com.couchbase.client.core.cnc.LoggingEventConsumer$JdkLogger info
INFO: [com.couchbase.node][NodeConnectedEvent] Node connected {“coreId”:“0xcf94def100000001”,“managerPort”:“8091”,“remote”:“172.17.0.4”}
Jun 05, 2022 6:27:49 PM com.couchbase.client.core.cnc.LoggingEventConsumer$JdkLogger info
INFO: [com.couchbase.node][NodeDisconnectedEvent][748us] Node disconnected {“coreId”:“0xcf94def100000001”,“managerPort”:“8091”,“remote”:“localhost”}
Jun 05, 2022 6:27:49 PM com.couchbase.client.core.cnc.LoggingEventConsumer$JdkLogger info
INFO: [com.couchbase.core][BucketOpenedEvent][144ms] Opened bucket “travel-sample” {“coreId”:“0xcf94def100000001”}
Exception in thread “main” com.couchbase.client.core.error.UnambiguousTimeoutException: WaitUntilReady timed out {“bucket”:“travel-sample”,“checkedServices”:[“VIEWS”,“MANAGER”,“QUERY”,“KV”,“SEARCH”],“currentState”:“OFFLINE”,“desiredState”:“ONLINE”,“services”:{“mgmt”:[{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”},{“state”:“connecting”}],“kv”:[{“namespace”:“travel-sample”,“state”:“connecting”},{“state”:“connecting”},{“namespace”:“travel-sample”,“state”:“connecting”},{“state”:“connecting”},{“namespace”:“travel-sample”,“state”:“connecting”},{“state”:“connecting”}]},“state”:{“current_stage”:“BUCKET_NODES_HEALTHY”,“current_stage_since_ms”:7348,“timings_ms”:{“BUCKET_NODES_HEALTHY”:9,“BUCKET_CONFIG_READY”:0,“CONFIG_LOAD”:143},“total_ms”:9888},“timeoutMs”:10000}
at com.couchbase.client.java.AsyncUtils.block(AsyncUtils.java:51)
at com.couchbase.client.java.Bucket.waitUntilReady(Bucket.java:229)
at StartUsing.main(StartUsing.java:20)
Suppressed: java.lang.Exception: The above exception was originally thrown by another thread at the following location.
at com.couchbase.client.core.diagnostics.WaitUntilReadyHelper.lambda$waitUntilReady$12(WaitUntilReadyHelper.java:179)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44)
at reactor.core.publisher.Mono.subscribe(Mono.java:4400)
at reactor.core.publisher.FluxTimeout$TimeoutMainSubscriber.handleTimeout(FluxTimeout.java:301)
at reactor.core.publisher.FluxTimeout$TimeoutMainSubscriber.doTimeout(FluxTimeout.java:280)
at reactor.core.publisher.FluxTimeout$TimeoutTimeoutSubscriber.onNext(FluxTimeout.java:419)
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
at reactor.core.publisher.MonoDelay$MonoDelayRunnable.propagateDelay(MonoDelay.java:271)
at reactor.core.publisher.MonoDelay$MonoDelayRunnable.run(MonoDelay.java:286)
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:68)
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:28)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)

Process finished with exit code 1

For Python I used:

from datetime import timedelta

needed for any cluster connection

from couchbase.auth import PasswordAuthenticator
from couchbase.cluster import Cluster

needed for options – cluster, timeout, SQL++ (N1QL) query, etc.

from couchbase.options import (ClusterOptions, ClusterTimeoutOptions,
QueryOptions)

Update this to your cluster

username = “Administrator”
password = “123456”
bucket_name = “travel-sample”
cert_path = “path/to/certificate”

User Input ends here.

Connect options - authentication

auth = PasswordAuthenticator(
username,
password,
# NOTE: If using SSL/TLS, add the certificate path.
# We strongly reccomend this for production use.
# cert_path=cert_path
)

Get a reference to our cluster

NOTE: For TLS/SSL connection use ‘couchbases://’ instead

cluster = Cluster(‘couchbase://localhost’, ClusterOptions(auth))

Wait until the cluster is ready for use.

cluster.wait_until_ready(timedelta(seconds=5))

get a reference to our bucket

cb = cluster.bucket(bucket_name)

cb_coll = cb.scope(“inventory”).collection(“airline”)

Get a reference to the default collection, required for older Couchbase server versions

cb_coll_default = cb.default_collection()

upsert document function

def upsert_document(doc):
print("\nUpsert CAS: ")
try:
# key will equal: “airline_8091”
key = doc[“type”] + “_” + str(doc[“id”])
result = cb_coll.upsert(key, doc)
print(result.cas)
except Exception as e:
print(e)

get document function

def get_airline_by_key(key):
print("\nGet Result: ")
try:
result = cb_coll.get(key)
print(result.content_as[str])
except Exception as e:
print(e)

query for new document by callsign

def lookup_by_callsign(cs):
print("\nLookup Result: ")
try:
sql_query = ‘SELECT VALUE name FROM travel-sample.inventory.airline WHERE callsign = $1’
row_iter = cluster.query(
sql_query,
QueryOptions(positional_parameters=[cs]))
for row in row_iter:
print(row)
except Exception as e:
print(e)

airline = {
“type”: “airline”,
“id”: 8091,
“callsign”: “CBS”,
“iata”: None,
“icao”: None,
“name”: “Couchbase Airways”,
}

upsert_document(airline)

get_airline_by_key(“airline_8091”)

lookup_by_callsign(“CBS”)

with the output:

/Users/jonathandeissler/Documents/BDEA/CA_3/pc_proj/bin/python /Users/jonathandeissler/PycharmProjects/pythonProject4/connection_test.py

Upsert CAS:
<ec=13, category=couchbase.common, message=ambiguous_timeout, context=KeyValueErrorContext:{‘key’: ‘airline_8091’, ‘bucket_name’: ‘travel-sample’, ‘scope_name’: ‘inventory’, ‘collection_name’: ‘airline’, ‘opaque’: 0}, C Source=/private/var/folders/j4/yf0f7md57c9_lv4z09kyz7nh0000gn/T/pip-install-0e_qclvl/couchbase_d1c1ac9f7e8147eaa72db4328fdd892f/src/kv_ops.cxx:601>

Get Result:
<ec=14, category=couchbase.common, message=unambiguous_timeout, context=KeyValueErrorContext:{‘key’: ‘airline_8091’, ‘bucket_name’: ‘travel-sample’, ‘scope_name’: ‘inventory’, ‘collection_name’: ‘airline’, ‘opaque’: 0}, C Source=/private/var/folders/j4/yf0f7md57c9_lv4z09kyz7nh0000gn/T/pip-install-0e_qclvl/couchbase_d1c1ac9f7e8147eaa72db4328fdd892f/src/kv_ops.cxx:209>

Lookup Result:
<ec=13, category=couchbase.common, message=ambiguous_timeout, context=QueryErrorContext({‘last_dispatched_to’: ‘’, ‘last_dispatched_from’: ‘’, ‘retry_attempts’: 0, ‘client_context_id’: ‘3277b07a-8a12-4b7c-8afe-ebec390386af’, ‘method’: ‘POST’, ‘path’: ‘/query/service’, ‘http_status’: 0, ‘http_body’: ‘’, ‘first_error_code’: 0, ‘first_error_message’: ‘’, ‘statement’: ‘SELECT VALUE name FROM travel-sample.inventory.airline WHERE callsign = $1’, ‘parameters’: ‘{“args”:[“CBS”],“client_context_id”:“3277b07a-8a12-4b7c-8afe-ebec390386af”,“metrics”:false,“statement”:“SELECT VALUE name FROM travel-sample.inventory.airline WHERE callsign = $1”,“timeout”:“74500ms”}’, ‘context_type’: ‘QueryErrorContext’}), C Source=/private/var/folders/j4/yf0f7md57c9_lv4z09kyz7nh0000gn/T/pip-install-0e_qclvl/couchbase_d1c1ac9f7e8147eaa72db4328fdd892f/src/n1ql.cxx:308>

Process finished with exit code 0

Hey @Jonathan_Deissler, hope you’re having fun with Couchbase so far!

If you’re running a multi-node cluster inside docker, you would need to use the Alternate Addresses feature when you’re creating NAT ports to the host system. While it definitely works for that (we test it regularly), it’s a bit complex if you’re using it on your desktop.

Single-node Docker is straightforward because the hostnames don’t change.

If you really need multiple nodes, might I suggest that you automate your run to do so from the same Docker environment? Then all of the IPs/Ports will be consistent rather than NAT’d to various ports.

Good luck!