Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

Commit

Permalink
Include configuration for docker containers, SSL automation and repla…
Browse files Browse the repository at this point in the history
…ce CouchRiver with Logstash (#41)
  • Loading branch information
mofesola authored and jkleinsc committed Mar 29, 2017
1 parent ca9a2d4 commit f85a6db
Show file tree
Hide file tree
Showing 24 changed files with 1,894 additions and 47 deletions.
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
npm-debug.log
.idea
.elasticbeanstalk
21 changes: 21 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ public

rebuild.sh

data/elasticsearch/*
data/couchdb/*
data/nginx/*


hospitalrun.crt

hospitalrun.key
Expand All @@ -19,10 +24,26 @@ certificate.pem

restart.sh

cloudformation

Dockerrun.aws.json

start.sh

!conf/polyclinic/start.sh

stop.sh

newrelic_agent.log

newrelic.js

.idea

# Elastic Beanstalk Files
.elasticbeanstalk/*
!.elasticbeanstalk/*.cfg.yml
!.elasticbeanstalk/config.yml
build/*
*.old
.DS_Store
29 changes: 29 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
language: node_js
node_js:
- '6'
sudo: required
services:
- docker

env:
global:
- DOCKER_IMAGE_REPO: CURE
PROJECT_NAME: hospitalrun

before_install:
- chmod +x conf/*.sh

cache:
directories:
- "$HOME/.cache"
- "$hOME/.npm"

script:
- echo "No test scripts! Developers should create test scripts to be run here"

deploy:
- provider: script
script: "./conf/travis-deploy.sh"
skip_cleanup: true
on:
branch: master
24 changes: 24 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM node:boron
LABEL maintainer Mofesola Babalola <me@mofesola.com>

#Get required applications
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y curl

#Create App Directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

#Install Dependencies
COPY package.json /usr/src/app
RUN npm install --loglevel silent

COPY . /usr/src/app
COPY conf/entrypoint.sh .
#Setup the DB with initial user
RUN chmod +x conf/initcouch.sh entrypoint.sh
COPY config-example.js config.js

EXPOSE 3000

ENTRYPOINT ./entrypoint.sh
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ HospitalRun Server
This is the Node.js backend for HospitalRun. The intention is that this would be used in HospitalRun production deployments.
Having a Node.js backend server allows us to do the following:

Full deployment documentation is available at [HospitalRun Deployment](https://confluence.ehealthafrica.org/display/HD/)

1. Use Google OAuth for user authentication.
2. Provide a proxy for CouchDB.
3. Integrate with ElasticSearch for better search capability.
Expand All @@ -11,7 +13,13 @@ Having a Node.js backend server allows us to do the following:
* **lookup-import** - Utility to import lookup lists from the frontend.
* **merge-conflicts** - Checks for couchdb conflicts and resolves using a strategy of accepting the last change at a field level.

## Installation
## Installation with Docker
This is the preferred and advisable way of running `hospitalrun-server`
1. Clone files into your server
2. Edit the `docker-compose.yml` file and replace `www.example.com` in `DOMAIN_NAME: www.example.com` with your domain name
3. Run `docker-compose up -d` and wait a couple of minutes depending on how much bandwidth you have. Visit your domain name to see `hospitalrun in action`

## Alternative Installation
1. Make sure you have installed [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
2. Make sure you have installed [Node.js 4.x](https://nodejs.org/en/download/) https://nodejs.org/en/download/
3. Clone this repo with `git clone https://github.com/HospitalRun/hospitalrun-server`
Expand All @@ -27,7 +35,7 @@ Having a Node.js backend server allows us to do the following:
1. Download https://github.com/HospitalRun/hospitalrun-frontend/blob/master/script/initcouch.sh
2. If you have just installed CouchDB and have no admin user, simply run `initcouch.sh` with no arguements. A user `hradmin` will be created with password: `test`.
2. If you already have a CouchDB admin user, please run `initcouch.sh USER PASS`. `USER` and `PASS` are the CouchDB admin user credentials.
6. Copy the config-example.js to config.js in the folder you cloned the HospitalRun repo. If you already had a CouchDB admin user that you passed into the couch script (initcouch.sh USER PASS), then you will need to modify the couchAdminUser and couchAdminPassword values in config.js to reflect those credentials.
6. Copy the config-example.js to config.js in the folder you cloned the HospitalRun repo. If you already had a CouchDB admin user that you passed into the couch script (initcouch.sh USER PASS), then you will need to modify the couchAdminUser and couchAdminPassword values in config.js to reflect those credentials.
7. If you are on Linux distribution that uses Upstart, there is an upstart script in utils/hospitalrun.conf. By default this script assumes the server is installed at /var/app/server. This script relies on [forever](https://github.com/foreverjs/forever) which you will need to install via npm: ```npm install -g forever```
* alternatively you can run server using npm's scripts `npm start` (this is not recommended for production usage).
8. Search on the HospitalRun Server uses [elasticsearch](https://github.com/elastic/elasticsearch). You will also need the [CouchDB River Plugin for Elasticsearch](https://github.com/elastic/elasticsearch-river-couchdb) and the [JavaScript language Plugin for elasticsearch](https://github.com/elastic/elasticsearch-lang-javascript). If you are installing on a debian server you can use the following steps to setup elasticsearch and java (if needed):
Expand All @@ -50,7 +58,7 @@ Having a Node.js backend server allows us to do the following:
```
10. Start elasticsearch. On debian/ubuntu: ```service elasticsearch start```
11. Run the setup script for linking couchdb to elasticsearch. You will need to specify the username and password for the hospitalrun admin account you created with initcouch.sh in [HospitalRun/frontend](https://github.com/HospitalRun/frontend/blob/master/script/initcouch.sh):
```
/utils/elasticsearch.sh hradmin password
```
Expand Down
7 changes: 7 additions & 0 deletions conf/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
# It will generally take about 40 seconds for elasticsearch and couchdb to be ready to receive connections
echo 'Scheduling setup scripts to run in 40 seconds...'
sleep 40 && /usr/src/app/conf/initcouch.sh 2>&1 && /usr/src/app/utils/elasticsearch.sh couchadmin test 2>&1 &
echo 'Scheduling setup scripts to run in 120 seconds...'
sleep 120 && /usr/src/app/conf/initcouch.sh 2>&1 && /usr/src/app/utils/elasticsearch.sh couchadmin test 2>&1 &
npm start
20 changes: 20 additions & 0 deletions conf/initcouch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

URL="couchdb"
PORT="5984"

if [ -z "${1}" ] || [ -z "${2}" ]; then
HOST="http://$URL:$PORT"
curl -X PUT $HOST/_config/admins/couchadmin -d '"test"'
SECUREHOST="http://couchadmin:test@$URL:$PORT"
else
SECUREHOST="http://$1:$2@$URL:$PORT"
fi
curl -X PUT $SECUREHOST/_users/_security -d '{ "admins": { "names": [], "roles": ["admin"]}, "members": { "names": [], "roles": []}}'
curl -X PUT $SECUREHOST/config
curl -X PUT $SECUREHOST/config/_security -d '{ "admins": { "names": [], "roles": ["admin"]}, "members": { "names": [], "roles": []}}'
curl -X PUT $SECUREHOST/main
curl -X PUT $SECUREHOST/main/_security -d '{ "admins": { "names": [], "roles": ["admin"]}, "members": { "names": [], "roles": ["user"]}}'
curl -X PUT $SECUREHOST/_config/http/authentication_handlers -d '"{couch_httpd_oauth, oauth_authentication_handler}, {couch_httpd_auth, proxy_authentification_handler}, {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}"'
curl -X PUT $SECUREHOST/_config/couch_httpd_oauth/use_users_db -d '"true"'
curl -X PUT $SECUREHOST/_users/org.couchdb.user:hradmin -d '{"name": "hradmin", "password": "test", "roles": ["System Administrator","admin","user"], "type": "user", "userPrefix": "p1"}'
36 changes: 36 additions & 0 deletions conf/travis-deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash

set -x
set -e

TAG="${TRAVIS_TAG}"
COMMIT="${TRAVIS_COMMIT}"
BRANCH="${TRAVIS_BRANCH}"
PR="${TRAVIS_PULL_REQUEST}"


if [ -z "${TAG}" ]; then
echo "No tags, tagging as: ${COMMIT}"
TAG="${COMMIT}"
fi

export TAG=$TAG

if [ "$TRAVIS_BRANCH" == "master" ]; then
docker login -e="$DOCKER_EMAIL" -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD";

docker-compose build
docker tag "${PROJECT_NAME}:latest" "${DOCKER_IMAGE_REPO}/${PROJECT_NAME}:${TAG}"
docker push "${DOCKER_IMAGE_REPO}/${PROJECT_NAME}:${TAG}"

# Push Logstash
docker tag "${PROJECT_NAME}_logstash:latest" "${DOCKER_IMAGE_REPO}/${PROJECT_NAME}_logstash:${TAG}"
docker push "${DOCKER_IMAGE_REPO}/${PROJECT_NAME}_logstash:${TAG}"

# Push Nginx
docker tag "${PROJECT_NAME}_nginx:latest" "${DOCKER_IMAGE_REPO}/${PROJECT_NAME}_nginx:${TAG}"
docker push "${DOCKER_IMAGE_REPO}/${PROJECT_NAME}_nginx:${TAG}"


else echo "Branch is not a baseline branch. No build will be made or pushed to the repository"
fi
10 changes: 5 additions & 5 deletions config-example.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
var config = {
couchDbServer: 'localhost',
couchDbServer: 'couchdb',
couchDbPort: '5984',
couchDbUseSsl: false,
couchDbChangesSince: 'now',
couchAdminUser: 'COUCH ADMIN USER GOES HERE',
couchAdminPassword: 'COUCH ADMIN PASSWORD GOES HERE',
couchAdminUser: 'couchadmin',
couchAdminPassword: 'test',
googleClientId: 'FOR GOOGLE SSO; GOOGLE CLIENT ID GOES HERE',
googleClientSecret: 'FOR GOOGLE SSO; GOOGLE CLIENT SECRET GOES HERE',
serverPort: '3000',
Expand Down Expand Up @@ -40,7 +40,7 @@ if (config.serverPort) {

config.couchDbURL = config.getProtocol(config.couchDbUseSsl) + config.couchDbServer + ':' + config.couchDbPort;
config.couchAuthDbURL = config.getProtocol(config.couchDbUseSsl) + config.couchCredentials() + config.couchDbServer + ':' + config.couchDbPort;
config.searchURL = 'http://localhost:9200'; // ELASTIC SEARCH URL
config.searchURL = 'http://elastic:changeme@elasticsearch:9200'; // ELASTIC SEARCH URL
config.webDir = __dirname + '/public';
config.serverInfo = 'Server Information to display to users when viewing about HospitalRun';
module.exports = config;
module.exports = config;
73 changes: 73 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
version: "2.0"
services:
nginx:
build:
args:
DOMAIN_NAME: www.example.com
context: nginx/.
dockerfile: Dockerfile
links:
- hospitalrun
ports:
- "8055:80"
- "443:443"
image: hospitalrun_nginx
volumes:
- ./data/nginx/letsencrypt:/etc/letsencrypt

hospitalrun:
container_name: hospitalrun
build: .
image: hospitalrun
links:
- couchdb
- elasticsearch
- logstash
depends_on:
- couchdb
- elasticsearch
- logstash
container_name: hospitalrun

couchdb:
container_name: couchdb_hr
image: couchdb:1.6
volumes:
- ./data/couchdb:/usr/local/var/lib/couchdb
ports:
- "5985:5984"

elasticsearch:
container_name: elasticsearch_hr
image: docker.elastic.co/elasticsearch/elasticsearch:5.2.2
volumes:
- ./data/elasticsearch:/usr/share/elasticsearch/data
ports:
- "9201:9200"
environment:
- http.host=0.0.0.0
- transport.host=127.0.0.1
- cluster.name=docker-cluster
- bootstrap.memory_lock=true
- ES_JAVA_OPTS=-Xms512m -Xmx512m
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
mem_limit: 1g
cap_add:
- IPC_LOCK

logstash:
container_name: logstash_hr
build: logstash/
image: hospitalrun_logstash
volumes:
- ./logstash/pipeline/:/usr/share/logstash/pipeline/
- ./logstash/config/:/usr/share/logstash/config/
links:
- couchdb
- elasticsearch
6 changes: 6 additions & 0 deletions logstash/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM docker.elastic.co/logstash/logstash:5.2.2
LABEL maintainer Mofesola BABALOLA <me@mofesola.com>
RUN logstash-plugin update --no-verify logstash-input-couchdb_changes
RUN rm -f /usr/share/logstash/pipeline/logstash.conf
ADD pipeline/ /usr/share/logstash/pipeline/
ADD config/ /usr/share/logstash/config/
74 changes: 74 additions & 0 deletions logstash/config/jvm.options
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
## JVM configuration

# Xms represents the initial size of total heap space
# Xmx represents the maximum size of total heap space

-Xms256m
-Xmx1g

################################################################
## Expert settings
################################################################
##
## All settings below this section are considered
## expert settings. Don't tamper with them unless
## you understand what you are doing
##
################################################################

## GC configuration
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly

## optimizations

# disable calls to System#gc
-XX:+DisableExplicitGC

## Locale
# Set the locale language
#-Duser.language=en

# Set the locale country
#-Duser.country=US

# Set the locale variant, if any
#-Duser.variant=

## basic

# set the I/O temp directory
#-Djava.io.tmpdir=$HOME

# set to headless, just in case
-Djava.awt.headless=true

# ensure UTF-8 encoding by default (e.g. filenames)
-Dfile.encoding=UTF-8

# use our provided JNA always versus the system one
#-Djna.nosys=true

## heap dumps

# generate a heap dump when an allocation from the Java heap fails
# heap dumps are created in the working directory of the JVM
-XX:+HeapDumpOnOutOfMemoryError

# specify an alternative path for heap dumps
# ensure the directory exists and has sufficient space
#-XX:HeapDumpPath=${LOGSTASH_HOME}/heapdump.hprof

## GC logging
#-XX:+PrintGCDetails
#-XX:+PrintGCTimeStamps
#-XX:+PrintGCDateStamps
#-XX:+PrintClassHistogram
#-XX:+PrintTenuringDistribution
#-XX:+PrintGCApplicationStoppedTime

# log GC status to a file with time stamps
# ensure the directory exists
#-Xloggc:${LS_GC_LOG_FILE}
Loading

0 comments on commit f85a6db

Please sign in to comment.