Skip to content
This repository has been archived by the owner on Mar 7, 2018. It is now read-only.

Dockerize #167

Merged
merged 6 commits into from Nov 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions .travis.yml
Expand Up @@ -2,8 +2,7 @@ language:
node_js

node_js:
- "7"
- "6"
- "9"

install:
- npm install
Expand Down
78 changes: 22 additions & 56 deletions README.md
@@ -1,70 +1,36 @@
# fortis-services
# project-fortis-services

[![Travis CI status](https://api.travis-ci.org/CatalystCode/project-fortis-services.svg?branch=master)](https://travis-ci.org/CatalystCode/project-fortis-services)

A node-based azure web app meant to host express web services
## Overview

## Environment variables
This repository contains the services tier of the Fortis architecture, below
highlighted in red in the architecture diagram for the entire system.

```sh
ENABLE_V2=1 # switch to new Cassandra backend instead of old Postgres backend

PUBLISH_EVENTS_EVENTHUB_CONNECTION_STRING="..."
PUBLISH_EVENTS_EVENTHUB_PATH="..."
PUBLISH_EVENTS_EVENTHUB_PARTITION="..."

USER_FILES_BLOB_ACCOUNT_NAME="..."
USER_FILES_BLOB_ACCOUNT_KEY="..."

TRANSLATION_SERVICE_ACCOUNT_KEY="..."

FACEBOOK_AUTH_TOKEN="..."

FORTIS_FEATURE_SERVICE_HOST="..."
APPINSIGHTS_INSTRUMENTATIONKEY="..."

CASSANDRA_CONTACT_POINTS="..."
CASSANDRA_KEYSPACE="fortis"
CASSANDRA_USERNAME="cassandra"
CASSANDRA_PASSWORD="cassandra"
```

## Development Setup

In order to serve data from the GraphQL services, you will need to a functioning Cassandra installation.
![Overview of Fortis architecture with project-fortis-services responsibility highlighted](https://user-images.githubusercontent.com/1086421/33336486-15c13cdc-d43e-11e7-9285-c9f580c41c12.png)

### Setting Up Cassandra on Windows Linux Subsystem (Ubuntu)
This repository implements a NodeJS GraphQL server that sits in between the
Fortis data-store (Cassandra) and the Fortis frontend (React).

As a prerequisite to setting up Cassandra, you will need to make sure you have Java 8 or better setup.
## Development setup

Then follow these commands to dowloand and run your local Cassandra instance:
As per the diagram above, there are two pieces necessary to run this repository
locally: a Cassandra database and the GraphQL server. You can spin up both of
these pieces using Docker via the following command:

```sh
curl -O http://www-eu.apache.org/dist/cassandra/3.11.0/apache-cassandra-3.11.0-bin.tar.gz
tar xfz apache-cassandra-3.11.0-bin.tar.gz
sudo mv apache-cassandra-3.11.0 /opt/apache-cassandra-3.11.0

export CASSANDRA_HOME=/opt/apache-cassandra-3.11.0
export PATH=$PATH:$CASSANDRA_HOME/bin

cd /opt/apache-cassandra-3.11.0
cassandra
docker-compose up
```

### Setting Up Cassandra on Mac OS X

The easiest way to do this is to use Hombrew.
The container of the GraphQL server will wait for the Cassandra database to come
live, then set up the database schema, then insert seed data (if a link to a CQL
file is provided via the `FORTIS_CASSANDRA_SEED_DATA_URL` environment variable)
and then start the GraphQL server on port 8080.

```sh
brew install cassandra
brew services start cassandra
```
After the server started, head over to the following URLs to play with the
service:

### First Casssandra Migration

After installing a fresh copy of Cassandra, you will need to run the DDL initialization statements in:

```sh
curl -O https://raw.githubusercontent.com/CatalystCode/fortisdeploy/master/ops/storage-ddls/cassandra-setup.cql
cqlsh < cassandra-setup.cql
```
- http://localhost:8080/api/edges/graphiql
- http://localhost:8080/api/messages/graphiql
- http://localhost:8080/api/settings/graphiql
- http://localhost:8080/api/tiles/graphiql
25 changes: 25 additions & 0 deletions docker-compose.yml
@@ -0,0 +1,25 @@
version: '3'

services:

cassandra:
build:
context: .
dockerfile: docker/cassandra/Dockerfile
ports:
- 7000:7000
- 7001:7001
- 7199:7199
- 9042:9042
- 9160:9160

project_fortis_services:
build:
context: .
dockerfile: docker/project-fortis-services/Dockerfile
ports:
- 8080:80
links:
- cassandra:cassandra
environment:
- CASSANDRA_CONTACT_POINTS=cassandra
1 change: 1 addition & 0 deletions docker/cassandra/Dockerfile
@@ -0,0 +1 @@
FROM cassandra:3.11.0
41 changes: 41 additions & 0 deletions docker/project-fortis-services/Dockerfile
@@ -0,0 +1,41 @@
FROM node:9.2.0

ADD . /app
ADD docker/project-fortis-services/run-server.sh /app/run-server.sh

WORKDIR /app

RUN apt-get install -y --no-install-recommends wget ca-certificates \
&& wget -q http://www-eu.apache.org/dist/cassandra/3.11.0/apache-cassandra-3.11.0-bin.tar.gz \
&& tar xfz apache-cassandra-3.11.0-bin.tar.gz \
&& rm apache-cassandra-3.11.0-bin.tar.gz \
&& mv apache-cassandra-3.11.0 /opt/cassandra \
&& npm install

ENV ENABLE_V2=1

ENV PUBLISH_EVENTS_EVENTHUB_CONNECTION_STRING="..."
ENV PUBLISH_EVENTS_EVENTHUB_PATH="..."
ENV PUBLISH_EVENTS_EVENTHUB_PARTITION="..."
ENV USER_FILES_BLOB_ACCOUNT_NAME="..."
ENV USER_FILES_BLOB_ACCOUNT_KEY="..."
ENV TRANSLATION_SERVICE_ACCOUNT_KEY="..."
ENV FACEBOOK_AUTH_TOKEN="..."
ENV APPINSIGHTS_INSTRUMENTATIONKEY="..."

# setting up the feature service is a lengthy process so we provide a shared
# instance for convenience; if you wish to run this service locally, please
# follow the instructions at https://github.com/CatalystCode/featureService and
# then update the value of this environment variable to http://localhost:3035
ENV FORTIS_FEATURE_SERVICE_HOST="http://fortis-features.eastus.cloudapp.azure.com"

ENV CASSANDRA_CONTACT_POINTS="..."
ENV CASSANDRA_KEYSPACE="fortis"
ENV CASSANDRA_USERNAME="cassandra"
ENV CASSANDRA_PASSWORD="cassandra"

ENV FORTIS_CASSANDRA_SCHEMA_URL="https://raw.githubusercontent.com/CatalystCode/fortisdeploy/master/ops/storage-ddls/cassandra-setup.cql"
ENV FORTIS_CASSANDRA_SEED_DATA_URL=""

EXPOSE 80
CMD "/app/run-server.sh"
33 changes: 33 additions & 0 deletions docker/project-fortis-services/run-server.sh
@@ -0,0 +1,33 @@
#!/usr/bin/env sh
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance you can add a set -e so that it exists on first failure?

#!/usr/bin/env sh
set -e

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great comment. I'm usually the first one to advocate for Bash strict mode (set -euo pipefail). However, some of the commands below are expected to fail (e.g. when waiting for Cassandra to come up) so I think it's cleaner to not enable strict-mode here since otherwise we'd have to sprinkle a bunch of || true across the code which may confuse folks with less Bash experience.


cassandra_exec() {
/opt/cassandra/bin/cqlsh \
--request-timeout=3600 \
--username="$CASSANDRA_USERNAME" \
--password="$CASSANDRA_PASSWORD" \
"$CASSANDRA_CONTACT_POINTS"
}

# wait for cassandra to start
while ! cassandra_exec; do
echo "Cassandra not yet available, waiting..."
sleep 10s
done
echo "...done, Cassandra is now available"

# set up cassandra schema
if [ -n "$FORTIS_CASSANDRA_SCHEMA_URL" ]; then
echo "Got Fortis schema definition at $FORTIS_CASSANDRA_SCHEMA_URL, ingesting..."
wget -qO- "$FORTIS_CASSANDRA_SCHEMA_URL" | cassandra_exec
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent! At some point, I think we could move these DDL statements into database migrations running on this project (fortis-services).

echo "...done, Fortis schema definition is now ingested"
fi

# set up cassandra seed data
if [ -n "$FORTIS_CASSANDRA_SEED_DATA_URL" ]; then
echo "Got Fortis sample data at $FORTIS_CASSANDRA_SEED_DATA_URL, ingesting..."
wget -qO- "$FORTIS_CASSANDRA_SEED_DATA_URL" | cassandra_exec
echo "...done, Fortis sample data is now ingested"
fi

# start node server
PORT="80" npm start
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 28 additions & 11 deletions package.json
@@ -1,19 +1,36 @@
{
"name": "fortis-services",
"description": "",
"version": "1.0.0",
"author": "erik schlegel <erik.schlegel@gmail.com>",
"contributors": [],
"name": "projectfortisservices",
"description": "This repository holds all the services-tier related code for the Fortis Project: https://aka.ms/fortis-story",
"license": "MIT",
"version": "0.0.1",
"repository": {
"type": "git",
"url": "git://github.com/erikschlegel/services.git"
},
"bugs": "http://github.com/erikschlegel/services/issues",
"publishConfig": {
"registry": "https://registry.npmjs.org"
"url": "https://github.com/CatalystCode/project-fortis-services.git"
},
"maintainers": [
{
"name": "Erik Schlegel",
"email": "erisch@microsoft.com"
},
{
"name": "Stephanie Marker",
"email": "stmarker@microsoft.com"
},
{
"name": "JC Jimenez",
"email": "jcjimene@microsoft.com"
},
{
"name": "Kevin Hartman",
"email": "keha@microsoft.com"
},
{
"name": "Clemens Wolff",
"email": "clewolff@microsoft.com"
}
],
"engines": {
"node": "6.0.0"
"node": "9.2.0"
},
"dependencies": {
"applicationinsights": "^0.16.0",
Expand Down