CouchDB as a docker swarm service
Run this on your primary box to initialize the docker swarm manager:
docker swarm init --advertise-addr <ip-address>
Then use the response to register other nodes in the swarm.
Create the network so that the CouchDB nodes can communicate with each other:
docker network create \
--driver overlay \
--subnet 10.0.9.0/24 \
--opt encrypted \
couchdb-network
The following examples assume that you have the directory /home/ubuntu/common on each of the boxes in the swarm. Moreover, /home/ubuntu/common/data is a directory that will be mounted as a volume so that your CouchDB data will be persisted across restarts.
All your CouchDB nodes need the same hashed password so that user sessions can work seamlessly between nodes. You can use the couch-hash-pwd
utility to generate this hash. For example, if your password is admin
you can use:
$ sudo npm install -g couch-hash-pwd
$ couchdb-hash-pwd -p admin
You'll then want to use the outputted value as the value of COUCHDB_HASHED_PASSWORD
docker service create --replicas 2 --name couchdb --network couchdb-network \
--hostname="couchdb{{.Task.Slot}}" \
--mount type=bind,source=/home/ubuntu/common,destination=/common \
-e COUCHDB_COOKIE="mycookie" \
-e COUCHDB_USER="admin" \
-e COUCHDB_PASSWORD="admin" \
-e COUCHDB_HASHED_PASSWORD="-pbkdf2-b1eb7a68b0778a529c68d30749954e9e430417fb,4da0f8f1d98ce649a9c5a3845241ae24,10" \
-e COUCHDB_SECRET="mysecret" \
-e NODENAME="couchdb{{.Task.Slot}}" \
-e SERVICE_NAME="{{.Service.Name}}" \
-e TASK_SLOT="{{.Task.Slot}}" \
-e COUCHDB_DATA_DIR="/common/data/{{.Service.Name}}{{.Task.Slot}}" \
-p 5984:5984 \
--detach=true \
redgeoff/couchdb-service
COUCHDB_COOKIE
and COUCHDB_SECRET
should be some random string of characters--you may want to use a password generator to generate these values.
We assume /home/ubuntu/common/ssl/mydomain.crt and /home/ubuntu/common/ssl/mydomain.key are the certificate and private key for your SSL config.
docker service create --replicas 2 --name couchdb --network couchdb-network \
--hostname="couchdb{{.Task.Slot}}" \
--mount type=bind,source=/home/ubuntu/common,destination=/common \
-e COUCHDB_COOKIE="mycookie" \
-e COUCHDB_USER="admin" \
-e COUCHDB_PASSWORD="admin" \
-e COUCHDB_HASHED_PASSWORD="-pbkdf2-b1eb7a68b0778a529c68d30749954e9e430417fb,4da0f8f1d98ce649a9c5a3845241ae24,10" \
-e COUCHDB_SECRET="mysecret" \
-e NODENAME="couchdb{{.Task.Slot}}" \
-e SERVICE_NAME="{{.Service.Name}}" \
-e TASK_SLOT="{{.Task.Slot}}" \
-e COUCHDB_DATA_DIR="/common/data/{{.Service.Name}}{{.Task.Slot}}" \
-e COUCHDB_CERT_FILE="/common/ssl/mydomain.crt" \
-e COUCHDB_KEY_FILE="/common/ssl/mydomain.key" \
-e COUCHDB_CACERT_FILE="/common/ssl/mydomain.crt" \
-p 6984:6984 \
--detach=true \
redgeoff/couchdb-service
We assume /home/ubuntu/common/etc/local.ini contains any custom config, e.g.
[chttpd]
bind_address = any
[httpd]
bind_address = any
[couchdb]
max_dbs_open=1000
Then run:
docker service create --replicas 2 --name couchdb --network couchdb-network \
--hostname="couchdb{{.Task.Slot}}" \
--mount type=bind,source=/home/ubuntu/common,destination=/common \
--mount type=bind,source=/home/ubuntu/common/etc/local.ini,destination=/home/couchdb/couchdb/etc/local.d/local.ini \
-e COUCHDB_COOKIE="mycookie" \
-e COUCHDB_USER="admin" \
-e COUCHDB_PASSWORD="admin" \
-e COUCHDB_HASHED_PASSWORD="-pbkdf2-b1eb7a68b0778a529c68d30749954e9e430417fb,4da0f8f1d98ce649a9c5a3845241ae24,10" \
-e COUCHDB_SECRET="mysecret" \
-e NODENAME="couchdb{{.Task.Slot}}" \
-e SERVICE_NAME="{{.Service.Name}}" \
-e TASK_SLOT="{{.Task.Slot}}" \
-e COUCHDB_DATA_DIR="/common/data/{{.Service.Name}}{{.Task.Slot}}" \
-e COUCHDB_CERT_FILE="/common/ssl/mydomain.co.crt" \
-e COUCHDB_KEY_FILE="/common/ssl/mydomain.co.key" \
-e COUCHDB_CACERT_FILE="/common/ssl/mydomain.co.crt" \
-p 6984:6984 \
--detach=true \
redgeoff/couchdb-service
docker service scale couchdb=5
TODO: To scale down, you should spin up a new cluster and replicate all the data from the old cluster to the new cluster and then delete the old cluster. See http://docs.couchdb.org/en/2.0.0/cluster/sharding.html#reshard-no-preshard
$ docker pull redgeoff/couchdb-service
$ docker service update --detach=true --image redgeoff/couchdb-service couchdb