├── README.MD ├── docker-compose.yml ├── rethinkdb ├── Dockerfile └── start-rethinkdb-cluster.sh └── testapp ├── Dockerfile ├── app.js └── package.json /README.MD: -------------------------------------------------------------------------------- 1 | # Demonstration of how to set up a cluster for RethinkDB in Docker 2 | 3 | Start by reading about what problem I'm actually trying to solve here: https://www.heavymetalcoder.com/setting-up-a-rethinkdb-cluster-in-docker/ 4 | 5 | ## Get started 6 | 7 | 1) Make it run 8 | 9 | $:>docker-compose build && docker-compose run 10 | 11 | 2) Go into the rethink ui (http://localhost:8081), add a database called `clustertest` and a table called `importantData`. Add a document containing anything into this table. 12 | 13 | Now you can start terrorizing the system. 14 | 15 | Kill a rethink server: 16 | 17 | $:>docker-compose stop rethinkdb2 18 | 19 | You can kill two servers and the test app should continue working nicely. The app complains about not being able to access all servers in the cluster, but all DB operations are operational. 20 | 21 | If you kill three servers you have less than half a cluster, so it will go offline. 22 | 23 | Restart a rethink server: 24 | 25 | $:>docker-compose start rethinkdb2 26 | 27 | No matter how many of the server containers are down, they will all start and join the cluster. -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | 3 | services: 4 | nodeapp: 5 | build: ./testapp 6 | networks: 7 | - rethink-net 8 | environment: 9 | - 'dbservers=rethinkdb1;rethinkdb2;rethinkdb3;rethinkdb4;rethinkdb5' 10 | rethinkdb1: 11 | build: ./rethinkdb 12 | environment: 13 | - "DBCLUSTERHOSTS=rethinkdb2;rethinkdb3;rethinkdb4;rethinkdb5" 14 | - "RETHINKARGS=--server-tag primary --server-name rethinkdb1 --bind all" 15 | hostname: rethinkdb1 16 | networks: 17 | - rethink-net 18 | ports: 19 | - "8081:8080" 20 | rethinkdb2: 21 | build: ./rethinkdb 22 | environment: 23 | - "DBCLUSTERHOSTS=rethinkdb1;rethinkdb3;rethinkdb4;rethinkdb5" 24 | - "RETHINKARGS=--server-tag primary --server-name rethinkdb2 --bind all" 25 | hostname: rethinkdb2 26 | networks: 27 | - rethink-net 28 | ports: 29 | - "8082:8080" 30 | rethinkdb3: 31 | build: ./rethinkdb 32 | environment: 33 | - "DBCLUSTERHOSTS=rethinkdb1;rethinkdb2;rethinkdb4;rethinkdb5" 34 | - "RETHINKARGS=--server-tag primary --server-name rethinkdb3 --bind all" 35 | hostname: rethinkdb3 36 | networks: 37 | - rethink-net 38 | ports: 39 | - "8083:8080" 40 | rethinkdb4: 41 | build: ./rethinkdb 42 | environment: 43 | - "DBCLUSTERHOSTS=rethinkdb1;rethinkdb2;rethinkdb3;rethinkdb5" 44 | - "RETHINKARGS=--server-tag primary --server-name rethinkdb4 --bind all" 45 | hostname: rethinkdb4 46 | networks: 47 | - rethink-net 48 | ports: 49 | - "8084:8080" 50 | rethinkdb5: 51 | build: ./rethinkdb 52 | environment: 53 | - "DBCLUSTERHOSTS=rethinkdb1;rethinkdb2;rethinkdb3;rethinkdb4" 54 | - "RETHINKARGS=--server-tag primary --server-name rethinkdb5 --bind all" 55 | hostname: rethinkdb5 56 | networks: 57 | - rethink-net 58 | ports: 59 | - "8085:8080" 60 | 61 | networks: 62 | rethink-net: 63 | driver: bridge 64 | -------------------------------------------------------------------------------- /rethinkdb/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rethinkdb:2.3.5 2 | 3 | COPY ./start-rethinkdb-cluster.sh /data 4 | 5 | RUN chmod 777 /data/start-rethinkdb-cluster.sh 6 | RUN ls -al /data 7 | 8 | CMD ["bash", "-c", "/data/start-rethinkdb-cluster.sh"] 9 | -------------------------------------------------------------------------------- /rethinkdb/start-rethinkdb-cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | IFS=';'; dbHostsArray=($DBCLUSTERHOSTS); unset IFS; 3 | joinString=" " 4 | 5 | for dbHost in ${dbHostsArray[*]} 6 | do 7 | hostExists=`getent hosts $dbHost` 8 | 9 | if [ ! -z "$hostExists" ] 10 | then 11 | joinString="$joinString --join $dbHost" 12 | fi 13 | done 14 | 15 | rethinkdb $joinString $RETHINKARGS 16 | -------------------------------------------------------------------------------- /testapp/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:6.9.1 2 | 3 | # Copy package.json file to docker image. 4 | COPY package.json /app/ 5 | 6 | # Define working directory. 7 | WORKDIR /app 8 | 9 | # Install node files on docker image. 10 | RUN npm install --production 11 | 12 | # Copy application files 13 | COPY app.js /app 14 | 15 | CMD ["node", "app"] 16 | 17 | # Expose port 18 | EXPOSE 3000 19 | -------------------------------------------------------------------------------- /testapp/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | console.log('I\'m starting fresh'); 4 | 5 | const r = require('rethinkdbdash')({ 6 | servers: [{ 7 | host: 'rethinkdb1', 8 | port: 28015 9 | }, { 10 | host: 'rethinkdb2', 11 | port: 28015 12 | }, { 13 | host: 'rethinkdb3', 14 | port: 28015 15 | }, { 16 | host: 'rethinkdb4', 17 | port: 28015 18 | }, { 19 | host: 'rethinkdb5', 20 | port: 28015 21 | }], 22 | timeout: 5000 23 | }); 24 | 25 | setInterval(() => { 26 | r.db('clustertest').table('importantData') 27 | .then(result => { 28 | console.log('read', result); 29 | }); 30 | }, 10000); 31 | -------------------------------------------------------------------------------- /testapp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rethinkdb-cluster", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "dependencies": { 7 | "rethinkdbdash": "^2.3.28" 8 | }, 9 | "devDependencies": {}, 10 | "scripts": { 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "author": "", 14 | "license": "ISC" 15 | } 16 | --------------------------------------------------------------------------------