Merge pull request #739 from Human-Connection/206_setup_neo4j_db_constraints_on_startup

206 setup neo4j db constraints on startup
This commit is contained in:
Robert Schäfer 2019-06-05 14:11:31 +02:00 committed by GitHub
commit 610af0de7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 156 additions and 72 deletions

View File

@ -17,7 +17,8 @@ before_install:
install:
- docker-compose -f docker-compose.yml -f docker-compose.travis.yml up --build -d
- wait-on http://localhost:7474 && docker-compose exec neo4j migrate
# avoid "Database constraints have changed after this transaction started"
- wait-on http://localhost:7474
script:
# Backend

View File

@ -3,6 +3,7 @@
* [Introduction](README.md)
* [Edit this Documentation](edit-this-documentation.md)
* [Installation](installation.md)
* [Neo4J](neo4j/README.md)
* [Backend](backend/README.md)
* [GraphQL](backend/graphql.md)
* [Webapp](webapp/README.md)

View File

@ -1,8 +1,6 @@
# Backend
## Installation
{% tabs %}
{% tab title="Docker" %}
## Installation with Docker
Run the following command to install everything through docker.
@ -14,28 +12,15 @@ $ docker-compose up
# rebuild the containers for a cleanup
$ docker-compose up --build
```
Open another terminal and create unique indices with:
```bash
$ docker-compose exec neo4j migrate
```
Wait a little until your backend is up and running at [http://localhost:4000/](http://localhost:4000/).
{% endtab %}
{% tab title="Without Docker" %}
## Installation without Docker
For the local installation you need a recent version of [node](https://nodejs.org/en/)
(>= `v10.12.0`) and [Neo4J](https://neo4j.com/) along with
[Apoc](https://github.com/neo4j-contrib/neo4j-apoc-procedures) plugin installed
on your system.
(>= `v10.12.0`).
Download [Neo4j Community Edition](https://neo4j.com/download-center/#releases) and unpack the files.
Download [Neo4j Apoc](https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases) and drop the file into the `plugins` folder of the just extracted Neo4j-Server
Note that grand-stack-starter does not currently bundle a distribution of Neo4j. You can download [Neo4j Desktop](https://neo4j.com/download/) and run locally for development, spin up a [hosted Neo4j Sandbox instance](https://neo4j.com/download/), run Neo4j in one of the [many cloud options](https://neo4j.com/developer/guide-cloud-deployment/), [spin up Neo4j in a Docker container](https://neo4j.com/developer/docker/) or on Debian-based systems install [Neo4j from the Debian Repository](http://debian.neo4j.org/). Just be sure to update the Neo4j connection string and credentials accordingly in `.env`.
Start Neo4J and confirm the database is running at [http://localhost:7474](http://localhost:7474).
Now install node dependencies with [yarn](https://yarnpkg.com/en/):
Install node dependencies with [yarn](https://yarnpkg.com/en/):
```bash
$ cd backend
$ yarn install
@ -46,14 +31,8 @@ Copy Environment Variables:
# in backend/
$ cp .env.template .env
```
Configure the new files according to your needs and your local setup.
Create unique indices with:
```bash
$ ./neo4j/migrate.sh
```
Configure the new file according to your needs and your local setup. Make sure
a [local Neo4J](http://localhost:7474) instance is up and running.
Start the backend for development with:
```bash
@ -65,17 +44,12 @@ or start the backend in production environment with:
yarn run start
```
{% endtab %}
{% endtabs %}
Your backend is up and running at [http://localhost:4000/](http://localhost:4000/)
This will start the GraphQL service \(by default on localhost:4000\) where you can issue GraphQL requests or access GraphQL Playground in the browser.
This will start the GraphQL service \(by default on localhost:4000\) where you
can issue GraphQL requests or access GraphQL Playground in the browser.
![GraphQL Playground](../.gitbook/assets/graphql-playground.png)
You can access Neo4J through [http://localhost:7474/](http://localhost:7474/)
for an interactive `cypher` shell and a visualization of the graph.
#### Seed Database
@ -114,7 +88,8 @@ $ yarn run db:reset
# Testing
**Beware**: We have no multiple database setup at the moment. We clean the database after each test, running the tests will wipe out all your data!
**Beware**: We have no multiple database setup at the moment. We clean the
database after each test, running the tests will wipe out all your data!
{% tabs %}

2
neo4j/.env.template Normal file
View File

@ -0,0 +1,2 @@
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=letmein

1
neo4j/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.env

View File

@ -1,3 +1,11 @@
FROM neo4j:3.5.5
LABEL Description="Neo4J database of the Social Network Human-Connection.org with preinstalled database constraints and indices" Vendor="Human Connection gGmbH" Version="0.0.1" Maintainer="Human Connection gGmbH (developer@human-connection.org)"
ARG BUILD_COMMIT
ENV BUILD_COMMIT=$BUILD_COMMIT
RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.5.0.1/apoc-3.5.0.1-all.jar -P plugins/
COPY migrate.sh /usr/local/bin/migrate
RUN apk add --no-cache --quiet procps
COPY db_setup.sh /usr/local/bin/db_setup
COPY entrypoint.sh /docker-entrypoint-wrapper.sh
ENTRYPOINT ["/docker-entrypoint-wrapper.sh"]

64
neo4j/README.md Normal file
View File

@ -0,0 +1,64 @@
# Neo4J
Human Connection is a social network. Using a graph based database which can
model nodes and edges natively - a network - feels like an obvious choice. We
decided to use [Neo4j](https://neo4j.com/), the currently most used graph
database available. The community edition of Neo4J is Free and Open Source and
we try our best to keep our application compatible with the community edition
only.
## Installation with Docker
Run:
```bash
docker-compose up
```
You can access Neo4J through [http://localhost:7474/](http://localhost:7474/)
for an interactive cypher shell and a visualization of the graph.
## Installation without Docker
Install community edition of [Neo4J]() along with the plugin
[Apoc](https://github.com/neo4j-contrib/neo4j-apoc-procedures) on your system.
To do so, go to [releases](https://neo4j.com/download-center/#releases), choose
"Community Server", download the installation files for you operation system
and unpack the files.
Download [Neo4j Apoc](https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases)
and drop the file into the `plugins` folder of the just extracted Neo4j-Server.
### Alternatives
You can download [Neo4j Desktop](https://neo4j.com/download/) and run locally
for development, spin up a
[hosted Neo4j Sandbox instance](https://neo4j.com/download/), run Neo4j in one
of the [many cloud options](https://neo4j.com/developer/guide-cloud-deployment/),
[spin up Neo4j in a Docker container](https://neo4j.com/developer/docker/),
on Archlinux you can install [neo4j-community from AUR](https://aur.archlinux.org/packages/neo4j-community/)
or on Debian-based systems install [Neo4j from the Debian Repository](http://debian.neo4j.org/).
Just be sure to update the Neo4j connection string and credentials accordingly
in `backend/.env`.
Start Neo4J and confirm the database is running at [http://localhost:7474](http://localhost:7474).
## Database Indices and Constraints
If you are not running our dedicated Neo4J [docker image](https://hub.docker.com/r/humanconnection/neo4j),
which is the case if you setup Neo4J locally without docker, then you have to
setup unique indices and database constraints manually.
If you have `cypher-shell` available with your local installation of neo4j you
can run:
```bash
# in folder neo4j/
$ cp .env.template .env
$ ./db_setup.sh
```
Otherwise if you don't have `cypher-shell` available, simply copy the cypher
statements [from the script](./neo4j/db_setup.sh) and paste the scripts into your
database [browser frontend](http://localhost:7474).

42
neo4j/db_setup.sh Executable file
View File

@ -0,0 +1,42 @@
#!/usr/bin/env bash
ENV_FILE=$(dirname "$0")/.env
[[ -f "$ENV_FILE" ]] && source "$ENV_FILE"
if [ -z "$NEO4J_USERNAME" ] || [ -z "$NEO4J_PASSWORD" ]; then
echo "Please set NEO4J_USERNAME and NEO4J_PASSWORD environment variables."
echo "Setting up database constraints and indexes will probably fail because of authentication errors."
echo "E.g. you could \`cp .env.template .env\` unless you run the script in a docker container"
fi
until echo 'RETURN "Connection successful" as info;' | cypher-shell
do
echo "Connecting to neo4j failed, trying again..."
sleep 1
done
echo '
RETURN "Here is a list of indexes and constraints BEFORE THE SETUP:" as info;
CALL db.indexes();
' | cypher-shell
echo '
CALL db.index.fulltext.createNodeIndex("full_text_search",["Post"],["title", "content"]);
CREATE CONSTRAINT ON (p:Post) ASSERT p.id IS UNIQUE;
CREATE CONSTRAINT ON (c:Comment) ASSERT c.id IS UNIQUE;
CREATE CONSTRAINT ON (c:Category) ASSERT c.id IS UNIQUE;
CREATE CONSTRAINT ON (u:User) ASSERT u.id IS UNIQUE;
CREATE CONSTRAINT ON (o:Organization) ASSERT o.id IS UNIQUE;
CREATE CONSTRAINT ON (t:Tag) ASSERT t.id IS UNIQUE;
CREATE CONSTRAINT ON (p:Post) ASSERT p.slug IS UNIQUE;
CREATE CONSTRAINT ON (c:Category) ASSERT c.slug IS UNIQUE;
CREATE CONSTRAINT ON (u:User) ASSERT u.slug IS UNIQUE;
CREATE CONSTRAINT ON (o:Organization) ASSERT o.slug IS UNIQUE;
' | cypher-shell
echo '
RETURN "Setting up all the indexes and constraints seems to have been successful. Here is a list AFTER THE SETUP:" as info;
CALL db.indexes();
' | cypher-shell

21
neo4j/entrypoint.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash
# credits: https://github.com/javamonkey79
# https://github.com/neo4j/docker-neo4j/issues/166
# turn on bash's job control
set -m
# Start the primary process and put it in the background
/docker-entrypoint.sh neo4j &
# Start the helper process
db_setup
# the my_helper_process might need to know how to wait on the
# primary process to start before it does its work and returns
# now we bring the primary process back into the foreground
# and leave it there
fg %1

View File

@ -1,33 +0,0 @@
#!/usr/bin/env bash
# If the user has the password `neo4j` this is a strong indicator, that we are
# the initial default user. Before we can create constraints, we have to change
# the default password. This is a security feature of neo4j.
if echo ":exit" | cypher-shell --password neo4j 2> /dev/null ; then
if [[ -z "${NEO4J_PASSWORD}" ]]; then
echo "NEO4J_PASSWORD environment variable is undefined. I cannot set the initial password."
else
echo "CALL dbms.security.changePassword('${NEO4J_PASSWORD}');" | cypher-shell --password neo4j
fi
fi
set -e
echo '
CALL db.index.fulltext.createNodeIndex("full_text_search",["Post"],["title", "content"]);
CREATE CONSTRAINT ON (p:Post) ASSERT p.id IS UNIQUE;
CREATE CONSTRAINT ON (c:Comment) ASSERT c.id IS UNIQUE;
CREATE CONSTRAINT ON (c:Category) ASSERT c.id IS UNIQUE;
CREATE CONSTRAINT ON (u:User) ASSERT u.id IS UNIQUE;
CREATE CONSTRAINT ON (o:Organization) ASSERT o.id IS UNIQUE;
CREATE CONSTRAINT ON (t:Tag) ASSERT t.id IS UNIQUE;
CREATE CONSTRAINT ON (p:Post) ASSERT p.slug IS UNIQUE;
CREATE CONSTRAINT ON (c:Category) ASSERT c.slug IS UNIQUE;
CREATE CONSTRAINT ON (u:User) ASSERT u.slug IS UNIQUE;
CREATE CONSTRAINT ON (o:Organization) ASSERT o.slug IS UNIQUE;
' | cypher-shell
echo "Successfully created all indices and unique constraints:"
echo 'CALL db.indexes();' | cypher-shell

View File

@ -2,7 +2,9 @@
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT --target production -t humanconnection/nitro-backend:latest $TRAVIS_BUILD_DIR/backend
docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT --target production -t humanconnection/nitro-web:latest $TRAVIS_BUILD_DIR/webapp
docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT -t humanconnection/neo4j:latest $TRAVIS_BUILD_DIR/neo4j
docker build -t humanconnection/maintenance-worker:latest $TRAVIS_BUILD_DIR/deployment/legacy-migration/maintenance-worker
docker push humanconnection/nitro-backend:latest
docker push humanconnection/nitro-web:latest
docker push humanconnection/maintenance-worker:latest
docker push humanconnection/neo4j:latest
docker push humanconnection/maintenance-worker:latest