Use this pattern for local development, staging, or production environments. This setup includes security best practices and production-ready configurations.
couchdb:3sudo mkdir -p /opt/couchdb
cd /opt/couchdb
compose.yaml (Production-Ready)services:
couchdb:
image: couchdb:3.5.1 # Pin to specific version
restart: unless-stopped
ports:
- "127.0.0.1:5984:5984" # Bind to localhost only
environment:
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=your_secure_password_here
- NODENAME=couchdb1@127.0.0.1 # For clustering
volumes:
- ./data:/opt/couchdb/data
- ./config:/opt/couchdb/etc/local.d # For custom configs
networks:
- couchdb-net
healthcheck:
test: ["CMD", "curl", "-f", "http://admin:your_secure_password_here@localhost:5984/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
ulimits:
nofile:
soft: 65536
hard: 65536
deploy:
resources:
limits:
memory: 2G
reservations:
memory: 512M
networks:
couchdb-net:
driver: bridge
For better security, use an environment file:
# Create .env file
cat > .env << EOF
COUCHDB_USER=admin
COUCHDB_PASSWORD=your_very_secure_password_here
EOF
And update the compose file:
services:
couchdb:
image: couchdb:3.5.1
restart: unless-stopped
ports:
- "127.0.0.1:5984:5984"
env_file:
- .env
volumes:
- ./data:/opt/couchdb/data
- ./config:/opt/couchdb/etc/local.d
networks:
- couchdb-net
healthcheck:
test: ["CMD", "curl", "-f", "http://admin:your_very_secure_password_here@localhost:5984/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
networks:
couchdb-net:
driver: bridge
Create a custom configuration file in ./config/10-security.ini:
[chttpd]
require_valid_user = true
bind_address = 0.0.0.0 ; Container binds to all interfaces internally
[chttpd_auth]
require_valid_user = true
authentication_db = _users
timeout = 600
[couchdb]
single_node = true
[log]
level = info
# Pull the latest image
docker compose pull
# Start the service
docker compose up -d
# Check status
docker compose ps
# View logs
docker compose logs -f couchdb
For clustered deployments, use multiple services:
version: '3.8'
services:
couchdb1:
image: couchdb:3.5.1
restart: unless-stopped
hostname: couchdb1
ports:
- "127.0.0.1:5984:5984"
environment:
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=your_secure_password
- NODENAME=couchdb1@172.20.0.10
volumes:
- couchdb1_data:/opt/couchdb/data
networks:
couchdbnet:
ipv4_address: 172.20.0.10
couchdb2:
image: couchdb:3.5.1
restart: unless-stopped
hostname: couchdb2
ports:
- "127.0.0.1:5985:5984"
environment:
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=your_secure_password
- NODENAME=couchdb2@172.20.0.11
volumes:
- couchdb2_data:/opt/couchdb/data
networks:
couchdbnet:
ipv4_address: 172.20.0.11
couchdb3:
image: couchdb:3.5.1
restart: unless-stopped
hostname: couchdb3
ports:
- "127.0.0.1:5986:5984"
environment:
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=your_secure_password
- NODENAME=couchdb3@172.20.0.12
volumes:
- couchdb3_data:/opt/couchdb/data
networks:
couchdbnet:
ipv4_address: 172.20.0.12
volumes:
couchdb1_data:
couchdb2_data:
couchdb3_data:
networks:
couchdbnet:
ipam:
config:
- subnet: 172.20.0.0/24
After starting the cluster, initialize it with:
# Join nodes to form a cluster
docker exec couchdb1 curl -X POST \
-H "Content-Type: application/json" \
-u admin:your_secure_password \
http://172.20.0.10:5984/_cluster_setup \
-d '{"action": "enable_cluster", "bind_address":"0.0.0.0", "username": "admin", "password":"your_secure_password", "node_count":"3"}'
docker exec couchdb1 curl -X POST \
-H "Content-Type: application/json" \
-u admin:your_secure_password \
http://172.20.0.10:5984/_cluster_setup \
-d '{"action": "add_node", "host":"couchdb2", "port":5984, "username": "admin", "password":"your_secure_password"}'
docker exec couchdb1 curl -X POST \
-H "Content-Type: application/json" \
-u admin:your_secure_password \
http://172.20.0.10:5984/_cluster_setup \
-d '{"action": "add_node", "host":"couchdb3", "port":5984, "username": "admin", "password":"your_secure_password"}'
# Finalize cluster setup
docker exec couchdb1 curl -X POST \
-H "Content-Type: application/json" \
-u admin:your_secure_password \
http://172.20.0.10:5984/_cluster_setup \
-d '{"action": "finish_cluster"}'
# Check cluster status
docker exec couchdb1 curl -u admin:your_secure_password http://127.0.0.1:5984/_membership
# View database stats
docker exec couchdb1 curl -u admin:your_secure_password http://127.0.0.1:5984/_stats
# Check active tasks
docker exec couchdb1 curl -u admin:your_secure_password http://127.0.0.1:5984/_active_tasks
# Backup container volumes
docker run --rm -v couchdb_data:/data -v $(pwd):/backup alpine tar czf /backup/couchdb-backup-$(date +%Y%m%d-%H%M%S).tar.gz -C /data .
# Restore backup
docker run --rm -v couchdb_data:/data -v $(pwd):/backup alpine sh -c "cd /data && tar xzf /backup/BACKUP_FILE.tar.gz"
couchdb:3.5.1)