如何在启动neo4j docker容器时运行cypher脚本?

时间:2018-01-20 14:23:37

标签: bash docker neo4j docker-compose

背景

我之前在Windows上安装了neo4j,并运行了PowerShell脚本来运行一些迁移。每次从这些迁移脚本中重新创建数据库&导入文件夹中的一些CSV。 .NET WebAPI与neo4j db进行通信。

目标

我决定对此设置进行Dockerize,以便我可以与人们进行跨平台协作,而且他们不必直接安装/配置neo4j。

我已经设置了大部分neo4j docker容器 - 卷,适当的文件被复制等等,它启动了。

问题

无论如何,我似乎无法找到一种插入或执行脚本的好方法,该脚本将遍历文件夹并执行密码查询。我知道这可能是一个使用neo4j CLI的bash脚本,我很好,但我找不到一个好的地方来实现它。

我尝试了什么

  • EXTENSION_SCRIPT env变量。这在过程中过早地执行。
  • 使用我自己的ENTRYPOINT - 发现这似乎取代了neo4j容器的入口点
  • 使用我自己的CMD - 类似地,这似乎取代
  • docker-compose移至dockerfile并复制neo4j入口点文件以进行修改。这似乎遇到了我在研究过程中遇到错误invalid optionn/bash: -的问题,但这是我的第一件事。

问题

如何在Neo4j启动后运行一个或多个cypher查询?在neo4j或docker中是否有规定允许这样做?我还没有在文档中找到任何线索。

或者,这真的不是推荐的方式吗?我是否应该通过输入容器并手动运行与CLI一起使用的bash脚本来按需运行这些迁移?

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"]

来自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

3 个答案:

答案 0 :(得分:1)

我创建了一个docker映像,该映像可以与在这里和github问题https://github.com/neo4j/docker-neo4j/issues/166中找到的包装器的重构版本一起使用。

图片marcellodesales/neo4j-with-cypher-seed

密码

  • 任何具有密码内容的文件都说interviews.cql
CREATE (facebook:Company {name:'Facebook'})

CREATE (clement:Candidate {name:'Clement'})
CREATE (antoine:Candidate {name:'Antoine'})
CREATE (simon:Candidate {name:'Simon'})

Docker映像

  • 将密码文件安装到卷/cyphers

利润

  • 获取装有密码的服务器
docker run --rm -ti  \
   -e "NEO4J_AUTH=none" \
   -p "7474:7474" -p "7687:7687" \
   -v $(pwd)/cypher_query.cql:/cyphers/interviews.cql \
   marcellodesales/neo4j-with-cypher-seed
  • 结果如下
$ docker run --rm -ti  \
   -e "NEO4J_AUTH=none" \
   -p "7474:7474" -p "7687:7687" \
   -v $(pwd)/cypher_query.cql:/cyphers/interviews.cql \
   marcellodesales/neo4j-with-cypher-seed
2020-09-27 16:54:00:486+0000 INFO  Wrapper: Waiting until neo4j stats at :7474 ...
Directories in use:
  home:         /var/lib/neo4j
  config:       /var/lib/neo4j/conf
  logs:         /logs
  plugins:      /var/lib/neo4j/plugins
  import:       /var/lib/neo4j/import
  data:         /var/lib/neo4j/data
  certificates: /var/lib/neo4j/certificates
  run:          /var/lib/neo4j/run
Starting Neo4j.
2020-09-27 16:54:01.394+0000 INFO  Starting...
2020-09-27 16:54:03.064+0000 INFO  ======== Neo4j 4.1.2 ========
2020-09-27 16:54:04.332+0000 INFO  Initializing system graph model for component 'security-users' with version -1 and status UNINITIALIZED
2020-09-27 16:54:04.337+0000 INFO  Setting up initial user from defaults: neo4j
2020-09-27 16:54:04.338+0000 INFO  Creating new user 'neo4j' (passwordChangeRequired=true, suspended=false)
2020-09-27 16:54:04.345+0000 INFO  Setting version for 'security-users' to 2
2020-09-27 16:54:04.349+0000 INFO  After initialization of system graph model component 'security-users' have version 2 and status CURRENT
2020-09-27 16:54:04.354+0000 INFO  Performing postInitialization step for component 'security-users' with version 2 and status CURRENT
2020-09-27 16:54:04.513+0000 INFO  Bolt enabled on 0.0.0.0:7687.
2020-09-27 16:54:05.410+0000 INFO  Remote interface available at http://localhost:7474/
2020-09-27 16:54:05.411+0000 INFO  Started.
2020-09-27 16:54:05:619+0000 INFO  Wrapper: Deleting all relations
2020-09-27 16:54:08:274+0000 INFO  Wrapper: Wrapper: Loading cyphers from '/cyphers'
2020-09-27 16:54:08:275+0000 INFO  Wrapper: Running cypher /cyphers/interviews.cql
0 rows available after 330 ms, consumed after another 0 ms
Added 17 nodes, Created 17 relationships, Set 34 properties, Added 17 labels
2020-09-27 16:54:09:695+0000 INFO  Wrapper: Finished loading all cyphers from '/cyphers'
2020-09-27 16:54:10:842+0000 INFO  Wrapper: Wrapper: Changes count 17
/docker-entrypoint.sh neo4j

enter image description here

答案 1 :(得分:0)

我遇到了同样的问题,我想在启动时创建一些索引,并且能够根据文档here对其进行解析以创建包装器脚本和一个索引脚本,该脚本一直休眠直到neo4j被备份,就像这样:

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

我也将此问题作为here一书而打开,我已将其答案复制到该问题中并自此结束。

答案 2 :(得分:0)

意识到我已经解决了这个问题-并希望在此处发布我当前的工作解决方案。我不会将自己的答案标记为解决方案,因为我认为这里的另一种解决方案也是可行的,而且我也不想全力以赴。

总体组成为:

  • 一个docker-compose文件,其环境变量为是否运行迁移以及等待多长时间
  • 我的WebAPI项目的Dockerfile,其中包括Neo4j客户端
  • 运行迁移的bash入口点脚本

docker-compose文件

在API项目上设置neo4j和环境变量。

version: '3'

services: # these are all the services that a docker app uses

  api: # this is the name of the service we're creating; it's chosen by us. Here, we're calling it "api".
    container_name: 'redacted-api' # this is the name of the container to us
    depends_on:
      - neo4j
    build:
      context: .
      dockerfile: DOCKERFILE_API
    environment:
      - SECONDS_PAUSE_BEFORE_MIGRATION=15
      - RUN_MIGRATIONS=true
    ports:
    - "5000:10901"
    networks:
      - app-network # this is a docker feature to allow you to place your various services within a virtual network so they can talk to each other. Note all the services we define here use the "app-network" network.
  neo4j:
    image: neo4j:3.3.1-enterprise
    container_name: 'redacted-db'
    environment: 
      - NEO4J_AUTH=none
      - NEO4J_dbms_security_procedures_unrestricted=apoc.*
      - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
    volumes:
      - ./data/db-files:/data
      - ./data/CSVs:/import
      - ./data/import/migrations:/import/migrations
      - ./data/plugins:/plugins
    ports: 
      #TODO: Remove these so that the API can get to them but not the host? (security)
      - "7687:7687" # bolt protocol
      - "7474:7474" # http protocol
      - "7473:7473" # https protocol
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

API Dockerfile

在我的WebAPI所安装的容器上安装cypher-shell neo4j实用程序:

FROM microsoft/dotnet:2.1-sdk

# Add the neo4j repo to the packages list
RUN wget -O - https://debian.neo4j.org/neotechnology.gpg.key | apt-key add -
RUN echo 'deb http://debian.neo4j.org/repo stable/' | tee -a /etc/apt/sources.list.d/neo4j.list

# Grab the packages list & install neo4j
RUN apt-get update && apt-get install -y \
cypher-shell

COPY . /app
WORKDIR /app/src/Redacted.API

RUN ["dotnet", "build"]

EXPOSE 10901/tcp

ENTRYPOINT ["sh", "/app/entrypoint.sh"]

入口点脚本

此操作在Web API的容器上运行,在Migrations文件夹中的所有密码查询之间循环,并针对Neo4j容器执行它们。

#!/bin/bash          


if [ "$RUN_MIGRATIONS" = "true" ] ; then
    echo "Pausing for $SECONDS_PAUSE_BEFORE_MIGRATION seconds to let Neo4j warm up"
    sleep $SECONDS_PAUSE_BEFORE_MIGRATION

    echo "Running migrations"
    for filename in /app/data/import/migrations/*.cypher; do
        echo "Attempting to run cypher: $filename" 
        contents=$( cat $filename )
        cypher-shell -a bolt://redacted-db:7687 "$contents"
    done
else
    echo "Skipping migrations because RUN_MIGRATIONS was not set to true."
fi

echo "Starting the .NET WebAPI"
dotnet run

最终结果

  • 数据库容器首先启动
  • API取决于Neo4j,因此它会等待该容器启动配置的时间
  • 然后,API运行所有迁移

进一步的步骤

我最终不得不将其搁置一旁,但是对我来说,下一步是弄清楚如何在Neo4j容器中完全获取Dockerfile / migrations /入口点,我认为我可以用一个如果我没有采用这种对我来说足够有效的方法,那就大惊小怪了。