【问题标题】:How can I run cypher scripts on startup of a neo4j docker container?如何在 neo4j docker 容器启动时运行密码脚本?
【发布时间】:2018-06-29 15:32:02
【问题描述】:

背景

我之前在 Windows 上安装了 neo4j 和一个 PowerShell 脚本来运行一些迁移。每次都会从这些迁移脚本和导入文件夹中的一些 CSV 重新创建数据库。 .NET WebAPI 与 neo4j db 对话。

目标

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

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

问题

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

我尝试过的

  • EXTENSION_SCRIPT 环境变量。这在流程中执行得太早了。
  • 使用我自己的 ENTRYPOINT -- 发现这似乎取代了 neo4j 容器的入口点
  • 使用我自己的 CMD -- 同样,这似乎取代了
  • docker-compose 移动到dockerfile 并复制neo4j 入口点文件以对其进行修改。这似乎遇到了我正在研究的错误invalid optionn/bash: - 的问题,但这是我的第一次尝试。

问题

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

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

脚本

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的相关sn-p:

  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

【问题讨论】:

标签: bash docker neo4j docker-compose


【解决方案1】:

我遇到了同样的问题,我想在启动时创建一些索引,并且能够根据文档 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"]

包装器.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

创建索引.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】:

    意识到我已经解决了这个问题——有点——并想在这里发布我当前的工作解决方案。不打算将我自己的答案标记为解决方案,因为我相信这里的另一个解决方案也是可行的,我不想完全相信。

    整体组件有:

    • 一个 docker-compose 文件,其中包含是否运行迁移以及等待多长时间的环境变量
    • Dockerfile 用于我的包含 Neo4j 客户端的 WebAPI 项目
    • 用于运行迁移的 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-shellneo4j 实用程序:

    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 的容器上运行,循环遍历迁移文件夹中的任何密码查询,并针对 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
    

    最终结果

    • DB 容器首先启动
    • API 依赖于 Neo4j,因此它会在配置的时间内等待该容器启动
    • API 然后运行所有迁移

    进一步的步骤

    我最终不得不把它放在一边,但对我来说,接下来的步骤是弄清楚如何完全在 Neo4j 容器中获取 Dockerfile/迁移/入口点,我想我可以用如果我没有采用这种对我来说效果很好的方法,那就更麻烦了。

    【讨论】:

      【解决方案3】:

      我创建了一个 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
      

      【讨论】:

      • @SeanKilleen 很高兴你喜欢它......我花了几个小时试图了解导致错误的原因,直到我查看了你的包装器实现......我已经打开票 github.com/neo4j/docker-neo4j/issues/275 时发现的错误将 cyper_shell 直接与 -F 文件一起使用。在这种情况下,感谢您提出第一个想法!
      猜你喜欢
      • 1970-01-01
      • 2018-05-20
      • 1970-01-01
      • 2018-05-16
      • 1970-01-01
      • 1970-01-01
      • 2021-12-13
      • 2019-04-22
      • 2019-01-15
      相关资源
      最近更新 更多