javaspring-bootdockercouchbase

Docker Connection Issue for Spring Boot with Couchbase


I want to run my app as Spring Boot with Couchbase in local and on Docker

Here is .env shown below

COUCHBASE_USERNAME=Administrator
COUCHBASE_PASSWORD=123456
COUCHBASE_BUCKET=todo_list
COUCHBASE_HOST=127.0.0.1

Here is application.yml file

spring:
  application:
    name: todowithcouchbase
  config:
    import: optional:file:.env[.properties]
  couchbase:
    connection-string: couchbase://${COUCHBASE_HOST:127.0.0.1}
    username: ${COUCHBASE_USERNAME:Administrator}
    password: ${COUCHBASE_PASSWORD:123456}
    bucket: ${COUCHBASE_BUCKET:todo_list}
    scopes:
      user-scope: user-scope
      task-scope: task-scope
      invalid-token-scope : invalid-token-scope
      log-scope: log-scope
    collections:
      user-collection: user-collection
      task-collection: task-collection
      invalid-token-collection: invalid-token-collection
      log-collection : log-collection


  data:
    couchbase:
      auto-index: true

server:
  shutdown: graceful
  port: 2323

# SWAGGER
springdoc:
  api-docs:
    enabled: true
  show-actuator: true

Here is the docker-compose.yml file shown below

version: '3.9'
services:
  couchbase:
    image: couchbase:latest
    container_name: couchbase
    ports:
      - "8091:8091"
      - "8092:8092"
      - "8093:8093"
      - "8094:8094"
      - "11210:11210"
    environment:
      COUCHBASE_ADMINISTRATOR_USERNAME: ${COUCHBASE_USERNAME:-Administrator}
      COUCHBASE_ADMINISTRATOR_PASSWORD: ${COUCHBASE_PASSWORD:-123456}
      COUCHBASE_BUCKET: ${COUCHBASE_BUCKET:-todo_list}
      COUCHBASE_AUTO_INDEX: true
    volumes:
      - ~/couchbase/node1:/opt/couchbase/var
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8091/ui/index.html"]
      interval: 30s
      timeout: 10s
      retries: 5
    networks:
      - todowithcouchbase_network

  todowithcouchbase:
    image: 'todowithcouchbase:latest'
    build:
      context: .
      dockerfile: Dockerfile
    container_name: todowithcouchbase
    # restart: on-failure
    ports:
      - "2323:2323"
    depends_on:
      couchbase:
        condition: service_healthy
    env_file:
      - .env  # Use the .env file for environment variables
    environment:
      COUCHBASE_BUCKET: ${COUCHBASE_BUCKET:-todo_list}
      COUCHBASE_USER: ${COUCHBASE_USERNAME:-Administrator}
      COUCHBASE_PASSWORD: ${COUCHBASE_PASSWORD:-123456}
      COUCHBASE_HOST: couchbase
    networks:
      - todowithcouchbase_network

networks:
  todowithcouchbase_network:
    driver: bridge

I have no issue to run it in local. When I ran docker-compose up -d, I got this error shown below.

DNS SRV lookup failed (name not found). This is expected if the there is no DNS SRV record associated with the hostname in the connection string. Will now try to bootstrap directly from the given hostname. To suppress this message, specify an IP address instead of a hostname (for example: 127.0.0.1 instead of localhost), specify more than one hostname, or set the `io.enableDnsSrv` client setting to false.

Connect attempt 1 failed because of AuthenticationFailureException: Authentication Failure - Potential causes: invalid credentials or if LDAP is enabled ensure PLAIN SASL mechanism is exclusively used on the PasswordAuthenticator (insecure) or TLS is used (recommended) {"bucket":"todo_list","circuitBreaker":"DISABLED","coreId":"0x1450b18f00000001","remote":"couchbase:11210","status":"UNKNOWN","type":"KV","xerror":{"ref":"b96586b3-65ae-4b33-9d5e-abb73869e6f9"}} {"bucket":"todo_list","circuitBreaker":"DISABLED","coreId":"0x1450b18f00000001","remote":"couchbase:11210","type":"KV"}

...

Connect attempt 25 failed because of AuthenticationFailureException: Authentication Failure - Potential causes: invalid credentials or if LDAP is enabled ensure PLAIN SASL mechanism is exclusively used on the PasswordAuthenticator (insecure) or TLS is used (recommended) {"bucket":"todo_list","circuitBreaker":"DISABLED","coreId":"0x1450b18f00000001","remote":"couchbase:11210","status":"UNKNOWN","type":"KV","xerror":{"ref":"b2f299fc-1e0b-497c-9d87-34be7eebbcc3"}} {"bucket":"todo_list","circuitBreaker":"DISABLED","coreId":"0x1450b18f00000001","remote":"couchbase:11210","type":"KV"}

ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'couchbaseBucket' defined in class path resource [com/example/todowithcouchbase/common/config/CouchbaseConfig.class]: Failed to instantiate [com.couchbase.client.java.Bucket]: Factory method 'couchbaseBucket' threw exception with message: CoreHttpRequest, Reason: TIMEOUT {"cancelled":true,"completed":true,"coreId":"0x1450b18f00000001","idempotent":true,"reason":"TIMEOUT","requestId":5,"requestType":"CoreHttpRequest","retried":156,"retryReasons":["AUTHENTICATION_ERROR"],"service":{"method":"GET","path":"/pools/default/buckets/","type":"mgmt"},"timeoutMs":75000,"timings":{"totalMicros":75006648}}

How can I fix the issue ?


Solution

  • Here is my solution shown below.

    1 ) Revise docker-compose.yml file shown below with defining some sh file to create bucket, collection and index after starting couchbase and configuring its service

    version: '3.9'
    services:
      couchbase:
        image: couchbase:latest
        container_name: couchbase
        ports:
          - "8091:8091"
          - "8097:8097"
          - "9123:9123"
          - "11207:11207"
          - "11210:11210"
          - "11280:11280"
          - "18091:18091"
          - "18097:18097"
        environment:
          COUCHBASE_ADMINISTRATOR_USERNAME: ${COUCHBASE_USERNAME:-Administrator}
          COUCHBASE_ADMINISTRATOR_PASSWORD: ${COUCHBASE_PASSWORD:-123456}
          COUCHBASE_BUCKET: ${COUCHBASE_BUCKET:-todo_list}
          COUCHBASE_AUTO_INDEX: true
        volumes:
          - ~/couchbase/node1:/opt/couchbase/var
          - ./scripts:/opt/couchbase/scripts
        command: >
          /bin/bash -c "
          /entrypoint.sh couchbase-server &
          
          chmod +x /opt/couchbase/scripts/setup-couchbase.sh &&
          /opt/couchbase/scripts/setup-couchbase.sh &&
          
          chmod +x /opt/couchbase/scripts/create-cluster.sh &&
          /opt/couchbase/scripts/create-cluster.sh &&
          
          chmod +x /opt/couchbase/scripts/configure-service.sh &&
          /opt/couchbase/scripts/configure-service.sh &&
          
          chmod +x /opt/couchbase/scripts/create-scopes.sh &&
          /opt/couchbase/scripts/create-scopes.sh &&
          
          chmod +x /opt/couchbase/scripts/create-indexes.sh &&
          /opt/couchbase/scripts/create-indexes.sh &&
          
          chmod +x /opt/couchbase/scripts/create-collections.sh &&
          /opt/couchbase/scripts/create-collections.sh &&
          
          echo 'Setup complete. Keeping container running...' &&
          tail -f /dev/null
          "
        healthcheck:
          test: [ "CMD", "curl", "-f", "http://localhost:8091/ui/index.html" ]
          interval: 30s
          timeout: 10s
          retries: 5
        networks:
          - todowithcouchbase_network
    
      todowithcouchbase:
        image: 'todowithcouchbase:latest'
        build:
          context: .
          dockerfile: Dockerfile
        container_name: todowithcouchbase
        # restart: on-failure
        ports:
          - "2323:2323"
        depends_on:
          couchbase:
            condition: service_healthy
        env_file:
          - .env  # Use the .env file for environment variables
        environment:
          COUCHBASE_BUCKET: ${COUCHBASE_BUCKET:-todo_list}
          COUCHBASE_USER: ${COUCHBASE_USERNAME:-Administrator}
          COUCHBASE_PASSWORD: ${COUCHBASE_PASSWORD:-123456}
          COUCHBASE_HOST: couchbase
        networks:
          - todowithcouchbase_network
    
    networks:
      todowithcouchbase_network:
        driver: bridge
    

    2 ) Here is setup_couchbase.sh file shown below to start couchbase

    #!/bin/bash
    
    # Function to check Couchbase readiness
    wait_for_couchbase() {
      echo "Waiting for Couchbase to start on port 8091..."
      until curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8091/ui/index.html | grep -q "200"; do
        sleep 5
        echo "Still waiting for Couchbase..."
      done
      echo "Couchbase is ready!"
    }
    
    # Wait for Couchbase to start
    wait_for_couchbase
    

    3 ) Here is create-cluster.sh to create a cluster inside couchbase

    #!/bin/bash
    set -e
    
    COUCHBASE_HOST=${COUCHBASE_HOST:-127.0.0.1}
    COUCHBASE_ADMINISTRATOR_USERNAME=${COUCHBASE_ADMINISTRATOR_USERNAME:-Administrator}
    COUCHBASE_ADMINISTRATOR_PASSWORD=${COUCHBASE_ADMINISTRATOR_PASSWORD:-123456}
    MEMORY_QUOTA_MB=${MEMORY_QUOTA_MB:-256}
    INDEX_MEMORY_QUOTA_MB=${INDEX_MEMORY_QUOTA_MB:-256}
    
    echo "Starting Couchbase cluster setup process..."
    
    # Wait for Couchbase Server to be ready
    echo "Waiting for Couchbase Server..."
    until curl -s -o /dev/null -w "%{http_code}" http://$COUCHBASE_HOST:8091 > /dev/null; do
      echo "Couchbase Server is not ready yet. Retrying in 5 seconds..."
      sleep 5
    done
    echo "Couchbase Server is ready."
    
    # Configure the cluster
    echo "Setting up Couchbase cluster with memory quota..."
    curl -s -u $COUCHBASE_ADMINISTRATOR_USERNAME:$COUCHBASE_ADMINISTRATOR_PASSWORD \
      -X POST http://$COUCHBASE_HOST:8091/pools/default \
      -d memoryQuota=$MEMORY_QUOTA_MB \
      -d indexMemoryQuota=$INDEX_MEMORY_QUOTA_MB \
      && echo "Cluster setup completed successfully."
    
    echo "Couchbase cluster setup process complete!"
    

    4 ) Here is configure-service.sh to configure the service inside couchbase

    #!/bin/bash
    set -e
    
    COUCHBASE_HOST=${COUCHBASE_HOST:-127.0.0.1}
    COUCHBASE_ADMINISTRATOR_USERNAME=${COUCHBASE_ADMINISTRATOR_USERNAME:-Administrator}
    COUCHBASE_ADMINISTRATOR_PASSWORD=${COUCHBASE_ADMINISTRATOR_PASSWORD:-123456}
    
    echo "Starting Couchbase service configuration..."
    
    # Wait for Couchbase Server to be ready
    echo "Waiting for Couchbase Server..."
    until curl -s -o /dev/null -w "%{http_code}" http://$COUCHBASE_HOST:8091 > /dev/null; do
      echo "Couchbase Server is not ready yet. Retrying in 5 seconds..."
      sleep 5
    done
    echo "Couchbase Server is ready."
    
    # Configure services
    echo "Configuring Couchbase services..."
    curl -s -X POST http://$COUCHBASE_HOST:8091/node/controller/setupServices \
      -d "services=kv%2Cn1ql%2Cindex" \
      && echo "Services configured successfully."
    
    # Configure administrator settings
    echo "Configuring Couchbase administrator settings..."
    curl -s -X POST http://$COUCHBASE_HOST:8091/settings/web \
      -d "port=8091" \
      -d "username=$COUCHBASE_ADMINISTRATOR_USERNAME" \
      -d "password=$COUCHBASE_ADMINISTRATOR_PASSWORD" \
      && echo "Administrator settings configured successfully."
    
    echo "Couchbase service configuration complete!"
    

    5 ) Here is create-scopes.sh to create scopes inside couchbase

    #!/bin/bash
    set -e
    
    COUCHBASE_HOST=${COUCHBASE_HOST:-127.0.0.1}
    COUCHBASE_ADMINISTRATOR_USERNAME=${COUCHBASE_ADMINISTRATOR_USERNAME:-Administrator}
    COUCHBASE_ADMINISTRATOR_PASSWORD=${COUCHBASE_ADMINISTRATOR_PASSWORD:-123456}
    COUCHBASE_BUCKET=${COUCHBASE_BUCKET:-todo_list}
    
    # Define scopes to be created
    SCOPES=(
      "user-scope"
      "task-scope"
      "invalid-token-scope"
      "log-scope"
    )
    
    echo "Starting Couchbase scopes setup process..."
    
    # Wait for Couchbase Query Service to be ready
    echo "Waiting for Couchbase Query Service..."
    until curl -s http://$COUCHBASE_HOST:8093/admin/ping > /dev/null; do
      echo "Query Service is not ready yet. Retrying in 5 seconds..."
      sleep 5
    done
    echo "Query Service is ready."
    
    # Iterate over the scopes
    for SCOPE in "${SCOPES[@]}"; do
      echo "Creating scope '$SCOPE'..."
      curl -s -u $COUCHBASE_ADMINISTRATOR_USERNAME:$COUCHBASE_ADMINISTRATOR_PASSWORD \
        -X POST http://$COUCHBASE_HOST:8093/query/service \
        -d "statement=CREATE SCOPE \`${COUCHBASE_BUCKET}\`.\`${SCOPE}\`" \
        && echo "Scope '$SCOPE' created successfully."
    done
    
    echo "Couchbase scopes setup process complete!"
    

    6 ) Here is create-indexes.sh to create indexes inside couchbase

    #!/bin/bash
    set -e
    
    COUCHBASE_HOST=${COUCHBASE_HOST:-127.0.0.1}
    COUCHBASE_USERNAME=${COUCHBASE_USERNAME:-Administrator}
    COUCHBASE_PASSWORD=${COUCHBASE_PASSWORD:-123456}
    COUCHBASE_BUCKET=${COUCHBASE_BUCKET:-todo_list}
    INDEXER_STORAGE_MODE=${INDEXER_STORAGE_MODE:-plasma}
    
    INDEXES=(
      "CREATE PRIMARY INDEX \`primary_index\` ON \`${COUCHBASE_BUCKET}\`"
    )
    
    echo "Starting Couchbase index setup process..."
    
    # Wait for Couchbase Query Service to be ready
    echo "Waiting for Couchbase Query Service..."
    until curl -s http://$COUCHBASE_HOST:8093/admin/ping > /dev/null; do
      echo "Query Service is not ready yet. Retrying in 5 seconds..."
      sleep 5
    done
    
    # Set Indexer Storage Mode
    echo "Setting indexer storage mode to $INDEXER_STORAGE_MODE..."
    curl -s -u "$COUCHBASE_USERNAME:$COUCHBASE_PASSWORD" \
      -X POST http://$COUCHBASE_HOST:8091/settings/indexes \
      -d "storageMode=$INDEXER_STORAGE_MODE" \
      && echo "Indexer storage mode set successfully."
    
    # Create indexes
    for INDEX_QUERY in "${INDEXES[@]}"; do
      echo "Creating index: $INDEX_QUERY"
      cbq -e http://$COUCHBASE_HOST:8093 \
        -u "$COUCHBASE_USERNAME" \
        -p "$COUCHBASE_PASSWORD" \
        --script="$INDEX_QUERY"
      echo "Index created successfully: $INDEX_QUERY"
    done
    
    echo "Couchbase index setup complete!"
    

    7 ) Here is create-collections.sh to create collections inside couchbase

    #!/bin/bash
    set -e
    
    COUCHBASE_HOST=${COUCHBASE_HOST:-127.0.0.1}
    COUCHBASE_ADMINISTRATOR_USERNAME=${COUCHBASE_ADMINISTRATOR_USERNAME:-Administrator}
    COUCHBASE_ADMINISTRATOR_PASSWORD=${COUCHBASE_ADMINISTRATOR_PASSWORD:-123456}
    COUCHBASE_BUCKET=${COUCHBASE_BUCKET:-todo_list}
    
    # Define collections to be created
    declare -A COLLECTIONS=(
      ["user-scope"]="user-collection"
      ["task-scope"]="task-collection"
      ["invalid-token-scope"]="invalid-token-collection"
      ["log-scope"]="log-collection"
    )
    
    echo "Starting Couchbase collections setup process..."
    
    # Wait for Couchbase Query Service to be ready
    echo "Waiting for Couchbase Query Service..."
    until curl -s http://$COUCHBASE_HOST:8093/admin/ping > /dev/null; do
      echo "Query Service is not ready yet. Retrying in 5 seconds..."
      sleep 5
    done
    echo "Query Service is ready."
    
    # Iterate over the scopes and collections
    for SCOPE in "${!COLLECTIONS[@]}"; do
      COLLECTION=${COLLECTIONS[$SCOPE]}
      echo "Creating collection '$COLLECTION' in scope '$SCOPE'..."
      curl -s -u $COUCHBASE_ADMINISTRATOR_USERNAME:$COUCHBASE_ADMINISTRATOR_PASSWORD \
        -X POST http://$COUCHBASE_HOST:8093/query/service \
        -d "statement=CREATE COLLECTION \`${COUCHBASE_BUCKET}\`.\`${SCOPE}\`.\`${COLLECTION}\`" \
        && echo "Collection '$COLLECTION' in scope '$SCOPE' created successfully."
    done
    
    echo "Couchbase collections setup process complete!"