Skip to content

Deploying a Couchbase Database

Introduction

Couchbase Server is an award-winning, distributed NoSQL cloud database that delivers unmatched versatility, performance, scalability, and financial value for all of your cloud, mobile, AI, and edge computing applications. Developed by Couchbase Inc. and evolved from CouchDB and Membase, Couchbase combines the best of both document-oriented and key-value database architectures.

Couchbase excels at:

  • Multi-Model Architecture: Native support for key-value, document, full-text search, eventing, analytics, and mobile sync
  • Memory-First Architecture: Ultra-fast data access with built-in caching layer for sub-millisecond latency
  • SQL++ Query Language: Powerful SQL-like query language (formerly N1QL) that’s familiar to SQL developers
  • Distributed Architecture: Built-in clustering with automatic sharding and replication across multiple nodes
  • Mobile & Edge Sync: Couchbase Lite and Sync Gateway for seamless mobile and edge computing
  • ACID Transactions: Full ACID transaction support across distributed documents
  • High Availability: Automatic failover with cross-datacenter replication (XDCR)
  • Flexible JSON: Native JSON document storage with dynamic schema evolution
  • Integrated Full-Text Search: Built-in full-text search engine powered by Bleve
  • Real-Time Analytics: Massively parallel processing (MPP) analytics without ETL

Common use cases include mobile applications, personalization engines, e-commerce platforms, gaming leaderboards, session stores, user profiles, content management systems, IoT data management, real-time analytics, and edge computing applications.

This comprehensive guide walks you through deploying Couchbase Server on Klutch.sh using Docker, including detailed installation steps, sample configurations, connection examples, and production-ready best practices for persistent storage and security.

Prerequisites

Before you begin, ensure you have the following:


Installation and Setup

Step 1: Create Your Project Directory

First, create a new directory for your Couchbase deployment project:

Terminal window
mkdir couchbase-klutch
cd couchbase-klutch
git init

Step 2: Create the Dockerfile

Create a Dockerfile in your project root directory. This will define your Couchbase container configuration:

FROM couchbase:enterprise-7.6.0
# Expose Couchbase ports
# 8091-8096: Web Console, API, and various services
# 11210: Data Service
# 11207: Data Service (SSL)
# 18091-18096: Internal services
EXPOSE 8091 8092 8093 8094 8095 8096 11210 11207 18091 18092 18093 18094 18095 18096
# Set environment variables for automatic setup
ENV COUCHBASE_ADMINISTRATOR_USERNAME=Administrator
ENV COUCHBASE_ADMINISTRATOR_PASSWORD=password
ENV COUCHBASE_BUCKET=default
ENV COUCHBASE_BUCKET_RAMSIZE=256
# Create a script to initialize Couchbase
COPY init-couchbase.sh /opt/couchbase/init/
RUN chmod +x /opt/couchbase/init/init-couchbase.sh
# Start Couchbase and run initialization
CMD ["/opt/couchbase/init/init-couchbase.sh"]

Note: Couchbase Enterprise 7.6.0 is the latest version with advanced features. For the community edition, use FROM couchbase:community-7.6.0 instead.

Step 3: Create the Initialization Script

Create a file named init-couchbase.sh that will configure Couchbase automatically on first startup:

#!/bin/bash
set -e
# Start Couchbase Server in the background
/entrypoint.sh couchbase-server &
# Wait for Couchbase to be ready
echo "Waiting for Couchbase Server to start..."
until curl -s http://localhost:8091/pools > /dev/null 2>&1; do
sleep 2
done
echo "Couchbase Server is up. Checking if already initialized..."
# Check if cluster is already initialized
if curl -s http://localhost:8091/pools/default | grep -q "Bucket"; then
echo "Cluster already initialized. Skipping setup."
else
echo "Initializing Couchbase cluster..."
# Initialize the cluster
couchbase-cli cluster-init \
--cluster localhost:8091 \
--cluster-username ${COUCHBASE_ADMINISTRATOR_USERNAME} \
--cluster-password ${COUCHBASE_ADMINISTRATOR_PASSWORD} \
--cluster-ramsize ${COUCHBASE_RAMSIZE:-1024} \
--cluster-index-ramsize ${COUCHBASE_INDEX_RAMSIZE:-256} \
--cluster-fts-ramsize ${COUCHBASE_FTS_RAMSIZE:-256} \
--cluster-eventing-ramsize ${COUCHBASE_EVENTING_RAMSIZE:-256} \
--cluster-analytics-ramsize ${COUCHBASE_ANALYTICS_RAMSIZE:-1024} \
--services data,index,query,fts,eventing,analytics \
--index-storage-setting default
echo "Cluster initialized successfully."
# Create default bucket if specified
if [ ! -z "$COUCHBASE_BUCKET" ]; then
echo "Creating bucket: $COUCHBASE_BUCKET"
couchbase-cli bucket-create \
--cluster localhost:8091 \
--username ${COUCHBASE_ADMINISTRATOR_USERNAME} \
--password ${COUCHBASE_ADMINISTRATOR_PASSWORD} \
--bucket ${COUCHBASE_BUCKET} \
--bucket-type couchbase \
--bucket-ramsize ${COUCHBASE_BUCKET_RAMSIZE:-256} \
--bucket-replica 0 \
--wait
echo "Bucket created successfully."
fi
# Create a primary index on the default bucket for easy querying
if [ ! -z "$COUCHBASE_BUCKET" ]; then
echo "Creating primary index..."
sleep 5 # Wait for bucket to be fully ready
curl -s -u ${COUCHBASE_ADMINISTRATOR_USERNAME}:${COUCHBASE_ADMINISTRATOR_PASSWORD} \
-d "statement=CREATE PRIMARY INDEX ON \`${COUCHBASE_BUCKET}\`" \
http://localhost:8093/query > /dev/null
echo "Primary index created."
fi
fi
echo "Couchbase initialization complete."
# Keep the container running
wait

Step 4: (Optional) Create a Sample Data Script

You can create a script to populate your Couchbase bucket with sample data. Create a file named sample-data.sh:

#!/bin/bash
# Sample data insertion script
# Run this after Couchbase is fully initialized
COUCHBASE_HOST="localhost:8091"
COUCHBASE_USER="${COUCHBASE_ADMINISTRATOR_USERNAME:-Administrator}"
COUCHBASE_PASS="${COUCHBASE_ADMINISTRATOR_PASSWORD:-password}"
BUCKET="${COUCHBASE_BUCKET:-default}"
# Insert sample user documents
curl -s -u ${COUCHBASE_USER}:${COUCHBASE_PASS} \
-X POST http://${COUCHBASE_HOST}/query/service \
-d "statement=INSERT INTO \`${BUCKET}\` (KEY, VALUE) VALUES ('user::1', {'type':'user','username':'johndoe','email':'john@example.com','firstName':'John','lastName':'Doe','createdAt':'$(date -u +%Y-%m-%dT%H:%M:%SZ)'})"
curl -s -u ${COUCHBASE_USER}:${COUCHBASE_PASS} \
-X POST http://${COUCHBASE_HOST}/query/service \
-d "statement=INSERT INTO \`${BUCKET}\` (KEY, VALUE) VALUES ('user::2', {'type':'user','username':'janedoe','email':'jane@example.com','firstName':'Jane','lastName':'Doe','createdAt':'$(date -u +%Y-%m-%dT%H:%M:%SZ)'})"
# Insert sample product documents
curl -s -u ${COUCHBASE_USER}:${COUCHBASE_PASS} \
-X POST http://${COUCHBASE_HOST}/query/service \
-d "statement=INSERT INTO \`${BUCKET}\` (KEY, VALUE) VALUES ('product::1', {'type':'product','name':'Laptop','category':'Electronics','price':999.99,'stock':50,'description':'High-performance laptop'})"
curl -s -u ${COUCHBASE_USER}:${COUCHBASE_PASS} \
-X POST http://${COUCHBASE_HOST}/query/service \
-d "statement=INSERT INTO \`${BUCKET}\` (KEY, VALUE) VALUES ('product::2', {'type':'product','name':'Smartphone','category':'Electronics','price':699.99,'stock':100,'description':'Latest model smartphone'})"
echo "Sample data inserted successfully!"

Step 5: Test Locally (Optional)

Before deploying to Klutch.sh, you can test your Couchbase setup locally:

Terminal window
# Build the Docker image
docker build -t my-couchbase .
# Run the container with persistent volume
docker run -d \
--name couchbase-test \
-p 8091-8096:8091-8096 \
-p 11210:11210 \
-v couchbase-data:/opt/couchbase/var \
-e COUCHBASE_ADMINISTRATOR_USERNAME=Administrator \
-e COUCHBASE_ADMINISTRATOR_PASSWORD=SuperSecurePassword123! \
-e COUCHBASE_BUCKET=mybucket \
-e COUCHBASE_BUCKET_RAMSIZE=512 \
my-couchbase
# Wait for initialization (check logs)
docker logs -f couchbase-test
# Once ready, open web console at http://localhost:8091
# Login with Administrator / SuperSecurePassword123!
# Test CLI access
docker exec -it couchbase-test couchbase-cli server-list \
-c localhost:8091 \
-u Administrator \
-p SuperSecurePassword123!
# Stop and remove the test container when done
docker stop couchbase-test
docker rm couchbase-test
docker volume rm couchbase-data

Step 6: Push to GitHub

Commit your Dockerfile and configuration files to your GitHub repository:

Terminal window
git add Dockerfile init-couchbase.sh sample-data.sh
git commit -m "Add Couchbase Dockerfile and initialization scripts"
git remote add origin https://github.com/yourusername/couchbase-klutch.git
git push -u origin main

Connecting to Couchbase

Once deployed, you can connect to your Couchbase Server from any application using the Couchbase SDK. Since Klutch.sh routes TCP traffic through port 8000, you’ll need to configure your connection accordingly.

Connection Details

Web Console Access:

  • URL: http://example-app.klutch.sh:8000
  • Username: Administrator (or your custom username)
  • Password: Your configured password

Connection String:

couchbase://example-app.klutch.sh:8000

Replace example-app.klutch.sh with your actual Klutch.sh app URL.

Example Connection Code

Node.js (using couchbase SDK):

const couchbase = require('couchbase');
async function connectToCouchbase() {
// Connect to the cluster
const cluster = await couchbase.connect('couchbase://example-app.klutch.sh:8000', {
username: 'Administrator',
password: 'your-password',
// Configure timeout settings
timeouts: {
kvTimeout: 10000,
queryTimeout: 75000
}
});
// Get a bucket reference
const bucket = cluster.bucket('mybucket');
const collection = bucket.defaultCollection();
// Insert a document
await collection.upsert('user::1', {
type: 'user',
username: 'johndoe',
email: 'john@example.com',
firstName: 'John',
lastName: 'Doe',
createdAt: new Date().toISOString()
});
console.log('Document inserted successfully');
// Retrieve a document
const result = await collection.get('user::1');
console.log('Retrieved document:', result.content);
// Query using SQL++
const query = 'SELECT * FROM `mybucket` WHERE type = $type LIMIT 10';
const queryResult = await cluster.query(query, { parameters: { type: 'user' } });
for await (const row of queryResult.rows) {
console.log('User:', row);
}
// Close the connection
await cluster.close();
}
connectToCouchbase().catch(console.error);

Python (using couchbase SDK):

from couchbase.cluster import Cluster
from couchbase.options import ClusterOptions
from couchbase.auth import PasswordAuthenticator
from datetime import datetime, timedelta
# Connect to cluster
auth = PasswordAuthenticator('Administrator', 'your-password')
cluster = Cluster('couchbase://example-app.klutch.sh:8000', ClusterOptions(auth))
# Wait for cluster to be ready
cluster.wait_until_ready(timedelta(seconds=5))
# Get bucket and collection
bucket = cluster.bucket('mybucket')
collection = bucket.default_collection()
# Insert a document
user_doc = {
'type': 'user',
'username': 'janedoe',
'email': 'jane@example.com',
'firstName': 'Jane',
'lastName': 'Doe',
'createdAt': datetime.utcnow().isoformat()
}
collection.upsert('user::2', user_doc)
print('Document inserted successfully')
# Retrieve a document
result = collection.get('user::2')
print('Retrieved document:', result.content_as[dict])
# Query using SQL++
query = "SELECT * FROM `mybucket` WHERE type = 'user' LIMIT 10"
result = cluster.query(query)
for row in result:
print('User:', row)

Java (using couchbase SDK):

import com.couchbase.client.java.*;
import com.couchbase.client.java.json.JsonObject;
import com.couchbase.client.java.query.QueryResult;
import java.time.Duration;
public class CouchbaseConnection {
public static void main(String[] args) {
// Connect to cluster
Cluster cluster = Cluster.connect(
"couchbase://example-app.klutch.sh:8000",
"Administrator",
"your-password"
);
// Get bucket and collection
Bucket bucket = cluster.bucket("mybucket");
bucket.waitUntilReady(Duration.ofSeconds(10));
Collection collection = bucket.defaultCollection();
// Insert a document
JsonObject user = JsonObject.create()
.put("type", "user")
.put("username", "javauser")
.put("email", "java@example.com")
.put("firstName", "Java")
.put("lastName", "Developer");
collection.upsert("user::3", user);
System.out.println("Document inserted successfully");
// Retrieve a document
JsonObject doc = collection.get("user::3").contentAsObject();
System.out.println("Retrieved document: " + doc);
// Query using SQL++
QueryResult result = cluster.query(
"SELECT * FROM `mybucket` WHERE type = 'user' LIMIT 10"
);
result.rowsAsObject().forEach(row ->
System.out.println("User: " + row)
);
cluster.disconnect();
}
}

Go (using gocb SDK):

package main
import (
"fmt"
"log"
"time"
"github.com/couchbase/gocb/v2"
)
type User struct {
Type string `json:"type"`
Username string `json:"username"`
Email string `json:"email"`
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
CreatedAt time.Time `json:"createdAt"`
}
func main() {
// Connect to cluster
cluster, err := gocb.Connect(
"couchbase://example-app.klutch.sh:8000",
gocb.ClusterOptions{
Username: "Administrator",
Password: "your-password",
},
)
if err != nil {
log.Fatal(err)
}
defer cluster.Close(nil)
// Get bucket and collection
bucket := cluster.Bucket("mybucket")
err = bucket.WaitUntilReady(5*time.Second, nil)
if err != nil {
log.Fatal(err)
}
collection := bucket.DefaultCollection()
// Insert a document
user := User{
Type: "user",
Username: "gouser",
Email: "go@example.com",
FirstName: "Go",
LastName: "Developer",
CreatedAt: time.Now(),
}
_, err = collection.Upsert("user::4", user, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("Document inserted successfully")
// Retrieve a document
getResult, err := collection.Get("user::4", nil)
if err != nil {
log.Fatal(err)
}
var retrievedUser User
err = getResult.Content(&retrievedUser)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Retrieved document: %+v\n", retrievedUser)
// Query using SQL++
rows, err := cluster.Query(
"SELECT * FROM `mybucket` WHERE type = 'user' LIMIT 10",
nil,
)
if err != nil {
log.Fatal(err)
}
for rows.Next() {
var result interface{}
err := rows.Row(&result)
if err != nil {
log.Fatal(err)
}
fmt.Printf("User: %v\n", result)
}
}

PHP (using couchbase extension):

<?php
use Couchbase\ClusterOptions;
use Couchbase\Cluster;
// Connect to cluster
$options = new ClusterOptions();
$options->credentials('Administrator', 'your-password');
$cluster = new Cluster('couchbase://example-app.klutch.sh:8000', $options);
// Get bucket and collection
$bucket = $cluster->bucket('mybucket');
$collection = $bucket->defaultCollection();
// Insert a document
$user = [
'type' => 'user',
'username' => 'phpuser',
'email' => 'php@example.com',
'firstName' => 'PHP',
'lastName' => 'Developer',
'createdAt' => date('c')
];
$collection->upsert('user::5', $user);
echo "Document inserted successfully\n";
// Retrieve a document
$result = $collection->get('user::5');
print_r($result->content());
// Query using SQL++
$query = "SELECT * FROM `mybucket` WHERE type = 'user' LIMIT 10";
$result = $cluster->query($query);
foreach ($result->rows() as $row) {
print_r($row);
}
?>

C# / .NET (using CouchbaseNetClient):

using System;
using System.Threading.Tasks;
using Couchbase;
using Couchbase.KeyValue;
class Program
{
static async Task Main(string[] args)
{
// Connect to cluster
var cluster = await Cluster.ConnectAsync(
"couchbase://example-app.klutch.sh:8000",
"Administrator",
"your-password"
);
// Get bucket and collection
var bucket = await cluster.BucketAsync("mybucket");
var collection = bucket.DefaultCollection();
// Insert a document
var user = new
{
type = "user",
username = "csharpuser",
email = "csharp@example.com",
firstName = "CSharp",
lastName = "Developer",
createdAt = DateTime.UtcNow
};
await collection.UpsertAsync("user::6", user);
Console.WriteLine("Document inserted successfully");
// Retrieve a document
var result = await collection.GetAsync("user::6");
var retrievedUser = result.ContentAs<dynamic>();
Console.WriteLine($"Retrieved document: {retrievedUser}");
// Query using SQL++
var queryResult = await cluster.QueryAsync<dynamic>(
"SELECT * FROM `mybucket` WHERE type = 'user' LIMIT 10"
);
await foreach (var row in queryResult)
{
Console.WriteLine($"User: {row}");
}
await cluster.DisposeAsync();
}
}

Deploying to Klutch.sh

Now that your Couchbase project is ready and pushed to GitHub, follow these steps to deploy it on Klutch.sh with persistent storage.

Deployment Steps

    1. Log in to Klutch.sh

      Navigate to klutch.sh/app and sign in to your account.

    2. Create a New Project

      Go to Create Project and give your project a meaningful name (e.g., “Couchbase Database”).

    3. Create a New App

      Navigate to Create App and configure the following settings:

    4. Select Your Repository

      • Choose GitHub as your Git source
      • Select the repository containing your Dockerfile
      • Choose the branch you want to deploy (usually main or master)
    5. Configure Traffic Type

      • Traffic Type: Select TCP (Couchbase requires TCP traffic for database connections and web console access)
      • Internal Port: Set to 8091 (the default Couchbase web console and API port)
    6. Set Environment Variables

      Add the following environment variables for your Couchbase configuration:

      • COUCHBASE_ADMINISTRATOR_USERNAME: The Couchbase admin username (e.g., Administrator)
      • COUCHBASE_ADMINISTRATOR_PASSWORD: A strong password for the admin user (use a secure password generator - minimum 6 characters)
      • COUCHBASE_BUCKET: The name of your default bucket (e.g., mybucket)
      • COUCHBASE_BUCKET_RAMSIZE: RAM allocated to the bucket in MB (e.g., 512)
      • COUCHBASE_RAMSIZE: Total RAM for data service in MB (e.g., 1024)
      • COUCHBASE_INDEX_RAMSIZE: RAM for index service in MB (e.g., 256)
      • COUCHBASE_FTS_RAMSIZE: RAM for full-text search service in MB (e.g., 256)
      • COUCHBASE_EVENTING_RAMSIZE: RAM for eventing service in MB (e.g., 256)
      • COUCHBASE_ANALYTICS_RAMSIZE: RAM for analytics service in MB (e.g., 1024)

      Security Note: Always use strong, unique passwords for production databases. The total RAM allocated should not exceed your container’s available memory. A minimum of 4GB RAM is recommended for running all services.

    7. Attach a Persistent Volume

      This is critical for ensuring your Couchbase data persists across deployments and restarts:

      • In the Volumes section, click “Add Volume”
      • Mount Path: Enter /opt/couchbase/var (this is where Couchbase stores all database files, indexes, and configurations)
      • Size: Choose an appropriate size based on your expected data volume (minimum 10GB recommended, 20GB+ for production workloads)

      Important: Couchbase requires persistent storage to maintain your data, indexes, and configuration between container restarts. Without a volume, all data will be lost when the container restarts.

    8. Configure Additional Settings

      • Region: Select the region closest to your users for optimal latency
      • Compute Resources: Choose CPU and memory based on your workload:
        • Minimum: 2 CPU cores, 4GB RAM (for testing)
        • Recommended: 4+ CPU cores, 8GB+ RAM (for production with all services)
        • Consider your total RAM allocation across all Couchbase services
      • Instances: Start with 1 instance (single-node deployment for simplicity)
    9. Deploy Your Database

      Click “Create” to start the deployment. Klutch.sh will:

      • Automatically detect your Dockerfile in the repository root
      • Build the Docker image
      • Attach the persistent volume
      • Start your Couchbase container
      • Execute the initialization script
      • Configure the cluster, create buckets, and set up indexes
      • Assign a URL for external connections
    10. Access Your Database

      Once deployment is complete, you’ll receive a URL like example-app.klutch.sh. You can:

      • Access Web Console: Navigate to http://example-app.klutch.sh:8000 in your browser
      • Connect via SDK: Use connection string couchbase://example-app.klutch.sh:8000

      Login to the web console with your administrator credentials to monitor your cluster, create additional buckets, configure indexes, and manage your data.


Production Best Practices

Security Recommendations

  • Strong Authentication: Always use strong passwords with a mix of uppercase, lowercase, numbers, and special characters (minimum 6 characters, but 12+ recommended)
  • Least Privilege Access: Create application-specific users with limited permissions instead of using the Administrator account
  • Role-Based Access Control (RBAC): Use Couchbase’s built-in RBAC to grant minimum necessary permissions
  • Secure Connections: Consider configuring SSL/TLS for encrypted connections in production
  • Network Security: Couchbase is accessible through Klutch.sh’s secure network by default
  • Regular Updates: Keep your Couchbase version up to date with security patches
  • Audit Logging: Enable audit logging to track access and changes
  • Secrets Management: Store credentials as environment variables, never hardcode them
  • IP Allowlisting: Use Couchbase’s IP allowlist feature to restrict access to known clients

Performance Optimization

Memory Management:

  • Allocate sufficient RAM to each service based on your workload
  • Data service should get 50-60% of total available RAM
  • Index service needs memory proportional to index size
  • Monitor memory usage and adjust allocations as needed
  • Use memory-optimized storage mode for smaller datasets

Indexing Strategy:

  • Create covering indexes for frequently queried fields
  • Use partial indexes to reduce memory footprint
  • Monitor index performance with query plan analysis
  • Consider memory-optimized indexes for frequently accessed data
  • Use GSI (Global Secondary Indexes) for scalable indexing

Query Optimization:

  • Use prepared statements for repeated queries
  • Add WHERE clauses to reduce document scanning
  • Utilize covering indexes to avoid document fetches
  • Use EXPLAIN to analyze query execution plans
  • Implement appropriate query timeouts

Data Modeling:

// Good: Embedded document for 1-to-few relationships
{
"type": "user",
"id": "user::1",
"name": "John Doe",
"addresses": [
{ "type": "home", "street": "123 Main St", "city": "Boston" },
{ "type": "work", "street": "456 Tech Ave", "city": "San Francisco" }
]
}
// Good: Referenced documents for 1-to-many relationships
// User document
{ "type": "user", "id": "user::1", "name": "John Doe" }
// Order documents (separate)
{ "type": "order", "id": "order::101", "userId": "user::1", "total": 99.99 }
{ "type": "order", "id": "order::102", "userId": "user::1", "total": 149.99 }

Connection Pooling:

  • Use SDK’s built-in connection pooling
  • Configure appropriate pool sizes based on concurrency
  • Reuse cluster connections across requests
  • Set appropriate timeout values

Backup and Recovery Strategy

Using cbbackupmgr (Recommended):

Terminal window
# Initialize backup repository
docker exec couchbase-container cbbackupmgr config \
--archive /backup/archive \
--repo my-backup-repo
# Create a backup
docker exec couchbase-container cbbackupmgr backup \
--archive /backup/archive \
--repo my-backup-repo \
--cluster couchbase://localhost \
--username Administrator \
--password your-password
# Restore from backup
docker exec couchbase-container cbbackupmgr restore \
--archive /backup/archive \
--repo my-backup-repo \
--cluster couchbase://localhost \
--username Administrator \
--password your-password

Backup Strategy:

  • Implement automated daily backups
  • Use incremental backups to reduce storage and time
  • Store backups in a separate persistent volume or external storage
  • Test restore procedures regularly
  • Maintain multiple retention periods (daily for 7 days, weekly for 4 weeks, monthly for 12 months)
  • Document your backup and recovery procedures

Data Durability:

  • Configure appropriate replication levels (when using multi-node clusters)
  • Use persistence settings: persistTo and replicateTo for critical writes
  • Enable cross-datacenter replication (XDCR) for disaster recovery
  • Consider using auto-failover in multi-node deployments

Monitoring and Observability

Key Metrics to Monitor:

  • Cluster Health: Node status, memory usage, disk usage
  • Operations Performance: Operations per second, latency percentiles
  • Query Performance: Query response times, slow queries
  • Memory Usage: Per-service memory consumption, cache hit ratios
  • Disk I/O: Read/write operations, disk queue depth
  • Network: Bandwidth usage, connection counts
  • Index Health: Index memory usage, index build times
  • Replication Lag: XDCR replication delay (if applicable)

Using Couchbase Web Console:

  • Navigate to the Web Console at http://example-app.klutch.sh:8000
  • Monitor real-time statistics in the Dashboard
  • Review Server Statistics for detailed metrics
  • Analyze Query Workload for slow queries
  • Check Bucket Statistics for bucket-level metrics

Using REST API for Monitoring:

Terminal window
# Get cluster stats
curl -u Administrator:password \
http://example-app.klutch.sh:8000/pools/default
# Get bucket stats
curl -u Administrator:password \
http://example-app.klutch.sh:8000/pools/default/buckets/mybucket/stats
# Get node info
curl -u Administrator:password \
http://example-app.klutch.sh:8000/pools/nodes

Query Performance Analysis

// Use EXPLAIN to understand query execution
const query = 'SELECT * FROM `mybucket` WHERE type = "user" AND email = $email';
const explainQuery = `EXPLAIN ${query}`;
const result = await cluster.query(explainQuery, {
parameters: { email: 'user@example.com' }
});
// Review the execution plan to identify:
// - Index usage (or lack thereof)
// - Number of documents scanned
// - Query cost estimates

Scaling Considerations

Vertical Scaling:

  • Increase CPU and RAM resources in Klutch.sh dashboard
  • Adjust service-specific RAM allocations via environment variables
  • Monitor resource utilization before scaling

Horizontal Scaling (Multi-Node):

  • Couchbase excels at horizontal scaling across multiple nodes
  • Add nodes through the Web Console or CLI
  • Configure replication and auto-failover for high availability
  • Use consistent hashing for automatic data distribution
  • Deploy additional Klutch.sh instances and cluster them together

Service-Specific Scaling:

  • Run different Couchbase services on different nodes
  • Allocate specialized resources for data, index, and query nodes
  • Separate analytics and eventing services for better performance

Troubleshooting

Cannot Connect to Couchbase

  • Verify you’re using the correct connection string with port 8000
  • Ensure authentication credentials (username, password) are correct
  • Check that the internal port is set to 8091 in your app configuration
  • Verify TCP traffic type is selected in Klutch.sh
  • Check Couchbase Server logs for startup errors
  • Ensure the initialization script completed successfully

Web Console Not Accessible

  • Verify the deployment is running and healthy
  • Check that port 8091 is properly exposed in the Dockerfile
  • Ensure you’re accessing http://example-app.klutch.sh:8000 (not https)
  • Review deployment logs for initialization errors
  • Verify environment variables are set correctly

Authentication Failed

  • Verify COUCHBASE_ADMINISTRATOR_USERNAME and COUCHBASE_ADMINISTRATOR_PASSWORD are set correctly
  • Ensure password meets minimum requirements (at least 6 characters)
  • Check that cluster initialization completed successfully
  • Review container logs for authentication-related errors
  • Try resetting administrator password via CLI

Database Not Persisting Data

  • Verify the persistent volume is correctly attached at /opt/couchbase/var
  • Check that the volume has sufficient space allocated
  • Ensure proper write permissions on the volume
  • Review Couchbase persistence settings
  • Check disk I/O performance and space availability

Out of Memory Errors

  • Review total RAM allocation across all services
  • Ensure total service RAM doesn’t exceed available container memory
  • Reduce RAM allocations for unused services
  • Increase container memory resources
  • Monitor memory usage in Web Console
  • Consider reducing bucket RAM quotas

Bucket Creation Failed

  • Verify sufficient RAM is available for the bucket
  • Check that RAM quota doesn’t exceed available memory
  • Ensure cluster initialization completed successfully
  • Review bucket creation parameters
  • Check for naming conflicts with existing buckets

Slow Query Performance

  • Use EXPLAIN to analyze query execution plans
  • Create appropriate indexes for your query patterns
  • Monitor slow queries in Web Console
  • Review and optimize your data model
  • Check memory availability for index service
  • Consider using covering indexes
  • Implement query result caching in your application

Disk Space Issues

  • Monitor disk usage in Web Console
  • Check volume size and available space
  • Review data compaction settings
  • Implement data lifecycle management (TTL)
  • Consider archiving old data
  • Increase volume size if needed
  • Enable automatic compaction

Cluster Initialization Hangs

  • Check available memory resources
  • Review initialization script logs
  • Verify all required environment variables are set
  • Ensure sufficient disk space is available
  • Check for port conflicts
  • Review resource constraints in container

Connection Timeout Issues

  • Increase SDK timeout settings
  • Check network latency between application and Couchbase
  • Verify cluster is healthy and responsive
  • Review connection pool settings
  • Monitor active connection counts
  • Check for resource exhaustion (CPU, memory)

Advanced Features

N1QL / SQL++ Query Language

Couchbase’s SQL++ (formerly N1QL) provides powerful querying capabilities:

-- Complex JOIN query
SELECT u.username, u.email, o.id AS orderId, o.total
FROM `mybucket` u
JOIN `mybucket` o ON KEYS u.orders
WHERE u.type = "user" AND o.type = "order" AND o.total > 100
ORDER BY o.total DESC
LIMIT 10;
-- Aggregation with GROUP BY
SELECT category, COUNT(*) AS productCount, AVG(price) AS avgPrice
FROM `mybucket`
WHERE type = "product"
GROUP BY category
HAVING COUNT(*) > 5
ORDER BY avgPrice DESC;
-- Subqueries
SELECT *
FROM `mybucket` u
WHERE u.type = "user"
AND u.id IN (
SELECT DISTINCT o.userId
FROM `mybucket` o
WHERE o.type = "order" AND o.total > 500
);
-- Array operations
SELECT username, ARRAY_LENGTH(orders) AS orderCount
FROM `mybucket`
WHERE type = "user" AND ARRAY_LENGTH(orders) > 0;

Create and use full-text search indexes:

// Create FTS index via REST API
const createFTSIndex = async () => {
const indexDef = {
type: 'fulltext-index',
name: 'products-fts',
sourceType: 'couchbase',
sourceName: 'mybucket',
planParams: {
maxPartitionsPerPIndex: 1024
},
params: {
mapping: {
types: {
product: {
enabled: true,
dynamic: false,
properties: {
name: { enabled: true, dynamic: false },
description: { enabled: true, dynamic: false },
category: { enabled: true, dynamic: false }
}
}
}
}
}
};
// Create via REST API
// PUT http://example-app.klutch.sh:8000/api/index/products-fts
};
// Query FTS index
const searchProducts = async (searchTerm) => {
const searchResult = await cluster.searchQuery(
'products-fts',
couchbase.SearchQuery.match(searchTerm),
{ limit: 10 }
);
for (const hit of searchResult.rows) {
console.log('Match:', hit.id, 'Score:', hit.score);
}
};

Eventing Functions

Create serverless functions that react to data changes:

// Example eventing function (deployed via Web Console)
function OnUpdate(doc, meta) {
// Trigger when a new order is created
if (doc.type === 'order' && doc.status === 'pending') {
// Calculate order total
var total = 0;
for (var i = 0; i < doc.items.length; i++) {
total += doc.items[i].price * doc.items[i].quantity;
}
// Update the order with calculated total
doc.total = total;
doc.processedAt = new Date().toISOString();
// Write back to bucket
mybucket[meta.id] = doc;
// Log for monitoring
log('Processed order:', meta.id, 'Total:', total);
}
}

Analytics Service

Run complex analytical queries without impacting operational workload:

-- Create analytics collection
CREATE DATASET orders_analytics ON `mybucket` WHERE type = "order";
-- Connect dataset
CONNECT LINK Local;
-- Run analytical query
SELECT
DATE_TRUNC_STR(createdAt, 'month') AS month,
COUNT(*) AS orderCount,
SUM(total) AS revenue,
AVG(total) AS avgOrderValue
FROM orders_analytics
WHERE createdAt >= "2024-01-01"
GROUP BY DATE_TRUNC_STR(createdAt, 'month')
ORDER BY month;

Sub-Document Operations

Efficiently update parts of documents:

// Update specific fields without retrieving entire document
await collection.mutateIn('user::1', [
couchbase.MutateInSpec.upsert('profile.status', 'active'),
couchbase.MutateInSpec.increment('profile.loginCount', 1),
couchbase.MutateInSpec.arrayAppend('profile.tags', 'premium')
]);
// Retrieve specific fields only
const result = await collection.lookupIn('user::1', [
couchbase.LookupInSpec.get('email'),
couchbase.LookupInSpec.get('profile.status')
]);
console.log('Email:', result.content[0].value);
console.log('Status:', result.content[1].value);

Transactions

ACID transactions across multiple documents:

const transactions = cluster.transactions();
try {
await transactions.run(async (attemptContext) => {
// Get documents
const accountA = await attemptContext.get(collection, 'account::A');
const accountB = await attemptContext.get(collection, 'account::B');
// Validate
if (accountA.content.balance < 100) {
throw new Error('Insufficient funds');
}
// Update documents atomically
await attemptContext.replace(accountA, {
...accountA.content,
balance: accountA.content.balance - 100
});
await attemptContext.replace(accountB, {
...accountB.content,
balance: accountB.content.balance + 100
});
// Create transaction record
await attemptContext.insert(collection, 'transaction::' + Date.now(), {
type: 'transfer',
from: 'account::A',
to: 'account::B',
amount: 100,
timestamp: new Date().toISOString()
});
});
console.log('Transaction completed successfully');
} catch (error) {
console.error('Transaction failed:', error);
}

Additional Resources


Conclusion

Deploying Couchbase Server to Klutch.sh with Docker provides a powerful, distributed NoSQL database solution that combines the benefits of key-value stores, document databases, and SQL-like query capabilities. By following this guide, you’ve set up a production-ready Couchbase deployment with proper authentication, persistent storage, automatic initialization, and best practices for security and performance. Your Couchbase instance is now ready to power your applications with high-performance, scalable data storage, full-text search, real-time analytics, and mobile synchronization capabilities.