Although the number of people using Neo4j has increased, it is still unrecognized. Since there is Neo4j Desktop on Windows, it is not inconvenient to use, but if you create a simple application and distribute it to the team, it will take a lot of space to create an image, so it is easier to use Docker. Especially when doing remote work like now. So, when I tried to distribute it as a set with the application with docker-compose, there was not much docker information of neo4j, so I checked it ~~ I will post what worked in various ways as a reminder.
https://github.com/MichitoIchimaru/neo4j_docker-compose
Folder
│ docker-compose.yml
├─ docker
│ └─neo4j
│ Dockerfile
│ background.sh
│ init.sh
│ init.cypher
└─volumes
└─neo4j
└─plugins
apoc.jar
docker-compose.yml
docker-compose.yml
version: "3"
networks:
app_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.30.0.0/24
services:
neo4j:
container_name: neo4j
build: ./docker/neo4j
volumes:
- ./volumes/neo4j/data:/data
- ./volumes/neo4j/plugins:/plugins
- ./volumes/neo4j/logs:/logs
- ./volumes/neo4j/import:/import
- ./volumes/neo4j/init:/init
ports:
- "7474:7474"
- "7687:7687"
environment:
# - NEO4JLABS_PLUGINS=["apoc"]
- NEO4J_apoc_export_file_enabled=true
- NEO4J_apoc_import_file_enabled=true
- NEO4J_apoc_uuid_enabled=true
- NEO4J_dbms_security_procedures_unrestricted=apoc.*
- NEO4J_dbms_security_procedures_whitelist=apoc.*
- NEO4J_dbms_memory_heap_initial__size=512m
- NEO4J_dbms_memory_heap_max__size=2G
- NEO4J_dbms_default__listen__address=0.0.0.0
- NEO4J_dbms_connector_bolt_listen__address=:7687
- NEO4J_dbms_connector_http_listen__address=:7474
- NEO4J_dbms_connector_bolt_advertised__address=:7687
- NEO4J_dbms_connector_http_advertised__address=:7474
- NEO4J_dbms_allow__upgrade=true
- NEO4J_dbms_default__database=neo4j
- NEO4J_AUTH=neo4j/p@ssw0rd
- EXTENSION_SCRIPT=/tmp/background.sh
restart: unless-stopped
networks:
app_net:
ipv4_address: 172.30.0.3
# - NEO4JLABS_PLUGINS=["apoc"]
If you uncomment this part, apoc.jar will be automatically downloaded from the Internet. This time, apoc.jar is stored in the volumes / neo4j / plugins folder from the beginning, so it is not necessary to download it, so I commented it out. Downloading apoc.jar takes a lot of time, so using the one downloaded in advance can shorten the startup time. However, there is one benefit to enabling this feature. This time, neo4j: 4.1.3 (latest as of 2020/10/15 is 4.1.3) is used for Neo4j Docker image, but since there is a version of apoc.jar corresponding to neo4j version, it is combined. It may not work depending on the version. If you uncomment this, apoc.jar corresponding to the Neo4j image you are using will be automatically identified and installed.
- NEO4J_AUTH=neo4j/p@ssw0rd
Set neo4j password
- EXTENSION_SCRIPT=/tmp/background.sh
I didn't understand this EXTENSION_SCRIPT. The Neo4j manual doesn't say what it's used for, and other people's articles say it's a script that runs after Neo4j starts. Looking at the actual behavior, it seems that it is executed before Neo4j is started rather than after it is started. Moreover, it seems that Neo4j will not start unless this script ends normally. Therefore, this time, init.sh is executed (with &) in background.sh. Then Neo4j will start up safely, and init.sh will wait for Neo4j to start up in the background and set up the initial data. By the way, running init.sh with & in EXTENSION_SCRIPT didn't work.
Dockerfile
FROM neo4j:4.1.3
RUN apt-get update
RUN apt-get install -y curl
COPY init.cypher /tmp/init.cypher
COPY background.sh /tmp/background.sh
COPY init.sh /tmp/init.sh
RUN chmod -v +x /tmp/background.sh
RUN chmod -v +x /tmp/init.sh
When the neo4j image is deployed, the package list of apt-get is empty, so the package cannot be installed unless apt-get update is executed once. Here, curl is installed to check the startup of Neo4j (check if Cypher can be executed). If you are in a Proxy environment, add ʻENV http_proxy http: // hogehoge` etc. here and it should work.
background.sh
background.sh
#!/bin/bash
/tmp/init.sh &
As explained above, a shell that you just want to specify EXTENSION_SCRIPT and run init.sh in the background. This is init.sh, and I feel that background.sh is more correct than init.sh, which will be described later.
init.sh
init.sh
#!/bin/bash
if [ -f /init/done ]; then
echo "The initialization process is already completed." >> /init/setup.log
exit 1
fi
COUNT=1
while [ $COUNT -lt 20 ]; do
status_code=$(curl --write-out %{http_code} --silent --output /dev/null localhost:7474)
if [[ "$status_code" = 200 ]] ; then
touch /init/done
cypher-shell -u neo4j -p p@ssw0rd -f /tmp/init.cypher
echo "The initialization process is complete." >> /init/setup.log
exit 1
else
echo "The neo4j service has not started yet. [$COUNT]" >> /init/setup.log
fi
COUNT=$(expr $COUNT + 1)
sleep 10s
done
exit 0
This shell is a script for inputting initial data to the started Neo4j. However, since this script is executed every time docker-compose is executed, a file called / init / done is created when it is executed for the first time, and if that file exists, it ends without doing anything.
if [ -f /init/done ]; then
echo "The initialization process is already completed." >> /init/setup.log
exit 1
fi
Check the existence of / init / done in this part, and if there is, end, if not, perform subsequent processing.
while [ $COUNT -lt 20 ]; do
Retry 20 times (strictly 19 times with this code) until Neo4j starts.
status_code=$(curl --write-out %{http_code} --silent --output /dev/null localhost:7474)
Access http: // localhost: 7474 with curl and get the HTTP response code.
if [[ "$status_code" = 200 ]] ; then
touch /init/done
cypher-shell -u neo4j -p p@ssw0rd -f /tmp/init.cypher
echo "The initialization process is complete." >> /init/setup.log
exit 1
else
echo "The neo4j service has not started yet. [$COUNT]" >> /init/setup.log
fi
If the result of curl is 200, create / init / done and execute /tmp/init.cypher with the cypher-shell command. If it is not 200, do nothing and retry.
COUNT=$(expr $COUNT + 1)
sleep 10s
Count up and sleep for 10 seconds. By the way, ((COUNT ++))
was not available for counting up in Neo4j images.
init.cypher
MATCH (n) return n;
Initial setup Cypher. Here, all node acquisition is written as a sample, but in reality, a CREATE statement etc. is written.
If this init.sh is executed successfully, the following log will be output to setup.log under / init (volumes / neo4j / init), and a done file should be generated as well.
setup.log
The neo4j service has not started yet. [1]
The neo4j service has not started yet. [2]
The neo4j service has not started yet. [3]
The initialization process is complete.
Recommended Posts