Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I run cypher scripts on startup of a neo4j docker container?

Background

I previously had neo4j installed on Windows and a PowerShell script to run some migrations. The DB is recreated every time from these migration scripts & some CSVs in the import folder. A .NET WebAPI talks to the neo4j db.

Goal

I decided to Dockerize this setup so that I can collaborate cross-platform with folks and they don't have to directly install / configure neo4j.

I've got most of the neo4j docker container set up -- volumes, appropriate files copied, etc. and it starts up.

Problem

No matter what, I can't seem to find a good way to insert or execute a script that will loop through the folder and execute the cypher queries. I know this will probably have to be a bash script that uses the neo4j CLI and I'm fine with that, but I can't find a good spot to make it happen.

What I've tried

  • the EXTENSION_SCRIPT env variable. That executes way too early in the process.
  • Using my own ENTRYPOINT -- discovered that this appears to supersede the neo4j container's entrypoint
  • Using my own CMD -- similarly, this appears to supersede
  • Moving from docker-compose to dockerfile and copying the neo4j entrypoint file to modify it. This appears to run into an issue with an error invalid optionn/bash: - that I'm in the process of researching, but this is my first go of things.

Question

How can I run one or more cypher queries after Neo4j is started? Is there a provision in either neo4j or docker to allow for this? I haven't been able to find any leads in the documentation.

Or, is this really not the recommended way to go? Should I be running these migrations on demand by entering the container and running a bash script manually that works with the CLI?

The Scripts

Dockerfile:

FROM neo4j:3.3.1

COPY ./data/import/migrations/scripts /scripts

ENV NEO4J_AUTH=none

ENTRYPOINT ["/scripts/docker-neo4j-entrypoint.sh"]
CMD ["neo4j"]

Relevant snippet from docker-compose:

  neo4j:
    container_name: 'app-db'
    build:
      context: .
      dockerfile: DOCKERFILE_DB
    volumes:
      - ./data/CSVs:/import
      - ./data/import/migrations:/import/migrations
    ports: 
      - "7687:7687" # bolt protocol
      - "7474:7474" # http protocol
      - "7473:7473" # https protocol
    networks:
      - app-network
like image 276
SeanKilleen Avatar asked Jan 20 '18 14:01

SeanKilleen


People also ask

Which command can be used to start a docker container from an image?

To run an image inside of a container, we use the docker run command. The docker run command requires one parameter and that is the image name. Let's start our image and make sure it is running correctly.

What is TTY mode docker?

The -t (or --tty) flag tells Docker to allocate a virtual terminal session within the container. This is commonly used with the -i (or --interactive) option, which keeps STDIN open even if running in detached mode (more about that later).

Can I run Neo4j in a docker container?

You now have a workable Neo4j Docker container with mapped file system directories and customized neo4j.conf configuration file

How do I run Cypher within a Neo4j container?

To run any Cypher against our database within the container, we can use either Neo4j Browser or the Cypher shell tool. If already familiar with Neo4j Browser, it works the same as with other Neo4j instances. First, ensure the database is running, then open a browser window and enter the url localhost:7474.

What is the best way to import data into Neo4j?

LOAD CSV in the Neo4j Desktop browser UI is great. But for testing purposes, since you can only run one query at a time, creating multi-query scripts with .cypher file extension and then running them on the command line can really speed up the process of running your tests and streamlining data imports.

What is testneo4j in Docker?

The docker run command creates and starts a container. On the next line, --name testneo4j defines the name we want to use for the container as testneo4j . This avoids us having to reference the container by its generic id, making our container easier to reference and to remember.


1 Answers

I faced the same issue, where I wanted to create some indexes at startup, and was able to resolve it based on the documentation here to create a wrapper script, and an indexes script that just sleeps until neo4j is back up, like so:

Dockerfile

FROM neo4j:latest

ENV NEO4J_AUTH=neo4j/password

RUN apk add --no-cache --quiet procps

COPY create-indexes.sh create-indexes.sh
COPY wrapper.sh wrapper.sh

ENTRYPOINT ["./wrapper.sh"]

wrapper.sh:

#!/bin/bash

# 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
./create-indexes.sh

# 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

create-indexes.sh

#!/bin/bash

until cypher-shell -u neo4j -p shaun123 'CREATE INDEX ON :Page(url);'
do
  echo "create page index failed, sleeping"
  sleep 10
done

until cypher-shell -u neo4j -p shaun123 'CREATE INDEX ON :Visited(url);'
do
  echo "create visited index failed, sleeping"
  sleep 10
done

until cypher-shell -u neo4j -p shaun123 'CREATE INDEX ON :Anchor(url);'
do
  echo "create anchor index failed, sleeping"
  sleep 10
done

I also opened this as an issue here, which I've copied my answer into and since closed.

like image 92
javamonkey79 Avatar answered Sep 16 '22 15:09

javamonkey79