
Running Neo4j with Docker Containers
Patrice Godard
August 23 2026
Source:vignettes/neo2R-docker.Rmd
neo2R-docker.RmdIntroduction
This vignette shows how to instantiate Docker containers running different versions of Neo4j (3.x, 4.x, 5.x, and 2025+). The main differences between the configurations are related to the APOC library and SSL setup.
Neo4j 3.x
For Neo4j 3.x, you need to manually download and configure the APOC library.
#!/bin/sh
#################################
## CONFIG according to your needs
#################################
export CONTAINER=neo4j_cont
export NJ_VERSION=3.5.30
## Ports
export NJ_HTTP_PORT=7474
export NJ_HTTPS_PORT=7473
export NJ_BOLT_PORT=7687
## Change the location of the Neo4j directory
export NJ_HOME=~/neo4j_home
## Authorization
## set to 'none' if you want to disable authorization
NJ_AUTH=neo4j/donttrustusers
## APOC download
export NJ_APOC=https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.5.0.15/apoc-3.5.0.15-all.jar
#################################
## RUN
#################################
mkdir -p $NJ_HOME
## Import and data directory
export NJ_IMPORT=$NJ_HOME/neo4jImport
mkdir -p $NJ_IMPORT
export NJ_DATA=$NJ_HOME/neo4jData
if test -e $NJ_DATA; then
echo "$NJ_DATA directory exists ==> abort - Remove it before proceeding" >&2
exit
fi
mkdir -p $NJ_DATA
## SSL
export NJ_SSL=${NJ_HOME}/ssl
mkdir -p ${NJ_SSL}/client_policy
mkdir -p ${NJ_SSL}/client_policy/revoked
mkdir -p ${NJ_SSL}/client_policy/trusted
openssl req -subj "/CN=localhost" -new -newkey rsa:2048 \
-days 365 -nodes -x509 \
-keyout ${NJ_SSL}/client_policy/private.key \
-out ${NJ_SSL}/client_policy/public.crt
chmod -R a+rwx ${NJ_SSL}
## Neo4j plugins: APOC
export NJ_PLUGINS=$NJ_HOME/neo4jPlugins
mkdir -p $NJ_PLUGINS
cd $NJ_PLUGINS
wget --no-check-certificate $NJ_APOC
cd -
docker run -d \
--name $CONTAINER \
--publish=$NJ_HTTP_PORT:7474 \
--publish=$NJ_HTTPS_PORT:7473 \
--publish=$NJ_BOLT_PORT:7687 \
--env=NEO4J_dbms_memory_heap_initial__size=2G \
--env=NEO4J_dbms_memory_heap_max__size=2G \
--env=NEO4J_dbms_memory_pagecache_size=1G \
--env=NEO4J_dbms_query__cache__size=0 \
--env=NEO4J_cypher_min__replan__interval=100000000ms \
--env=NEO4J_cypher_statistics__divergence__threshold=1 \
--env=NEO4J_dbms_security_procedures_unrestricted=apoc.\\* \
--env=NEO4J_dbms_directories_import=import \
--env NEO4J_AUTH=$NJ_AUTH \
--volume $NJ_IMPORT:/var/lib/neo4j/import \
--volume $NJ_DATA/data:/data \
--volume $NJ_PLUGINS:/plugins \
--volume=$NJ_SSL:/ssl \
--env=NEO4J_https_ssl__policy=client_policy \
--env=NEO4J_dbms_ssl_policy_client__policy_base__directory=/ssl/client_policy \
--env=NEO4J_dbms_ssl_policy_client__policy_client__auth=NONE \
--env=NEO4J_dbms_ssl_policy_client__policy_trust__all=true \
neo4j:$NJ_VERSION
sleep 15
sudo chmod a+rwx $NJ_IMPORTNeo4j 4.x
Neo4j 4.x has similar configuration to 3.x but with updated environment variable names.
#!/bin/sh
#################################
## CONFIG according to your needs
#################################
export CONTAINER=neo4j_cont
export NJ_VERSION=4.4.26
## Ports
export NJ_HTTP_PORT=7474
export NJ_HTTPS_PORT=7473
export NJ_BOLT_PORT=7687
## Change the location of the Neo4j directory
export NJ_HOME=~/neo4j_home
## Authorization
export NJ_AUTH=neo4j/donttrustusers
## APOC download
export NJ_APOC=https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/4.4.0.3/apoc-4.4.0.3-all.jar
#################################
## RUN
#################################
mkdir -p $NJ_HOME
## Import and data directory
export NJ_IMPORT=$NJ_HOME/neo4jImport
mkdir -p $NJ_IMPORT
export NJ_DATA=$NJ_HOME/neo4jData
if test -e $NJ_DATA; then
echo "$NJ_DATA directory exists ==> abort - Remove it before proceeding" >&2
exit
fi
mkdir -p $NJ_DATA
## SSL
export NJ_SSL=${NJ_HOME}/ssl
mkdir -p ${NJ_SSL}/https
mkdir -p ${NJ_SSL}/https/revoked
mkdir -p ${NJ_SSL}/https/trusted
openssl req -subj "/CN=localhost" -new -newkey rsa:2048 \
-days 365 -nodes -x509 \
-keyout ${NJ_SSL}/https/private.key \
-out ${NJ_SSL}/https/public.crt
chmod -R a+rwx ${NJ_SSL}
## Neo4j plugins: APOC
export NJ_PLUGINS=$NJ_HOME/neo4jPlugins
mkdir -p $NJ_PLUGINS
cd $NJ_PLUGINS
wget --no-check-certificate $NJ_APOC
cd -
docker run -d \
--name $CONTAINER \
--publish=$NJ_HTTP_PORT:7474 \
--publish=$NJ_HTTPS_PORT:7473 \
--publish=$NJ_BOLT_PORT:7687 \
--env=NEO4J_dbms_memory_heap_initial__size=2G \
--env=NEO4J_dbms_memory_heap_max__size=2G \
--env=NEO4J_dbms_memory_pagecache_size=1G \
--env=NEO4J_dbms_query__cache__size=0 \
--env=NEO4J_cypher_min__replan__interval=100000000ms \
--env=NEO4J_cypher_statistics__divergence__threshold=1 \
--env=NEO4J_dbms_security_procedures_unrestricted=apoc.\\* \
--env=NEO4J_dbms_directories_import=import \
--env NEO4J_AUTH=$NJ_AUTH \
--volume $NJ_IMPORT:/var/lib/neo4j/import \
--volume $NJ_DATA/data:/data \
--volume $NJ_PLUGINS:/plugins \
--volume=$NJ_SSL:/ssl \
--env=NEO4J_dbms_connector_https_enabled=true \
--env=NEO4J_dbms_ssl_policy_https_enabled=true \
--env=NEO4J_dbms_ssl_policy_https_base__directory=/ssl/https \
--env=NEO4J_dbms_ssl_policy_https_private__key=private.key \
--env=NEO4J_dbms_ssl_policy_https_public__certificate=public.crt \
--env=NEO4J_dbms_ssl_policy_https_client__auth=NONE \
--env=NEO4J_dbms_ssl_policy_https_trust__all=true \
neo4j:$NJ_VERSION
sleep 15
sudo chmod a+rwx $NJ_IMPORTNeo4j 5.x (>= 5.12)
In Neo4j 5.x, it is not possible to instantiate the Docker image with
a specific username and password. The password must be changed after
Neo4j starts. However, you can instantiate the image without any
credentials using --env NEO4J_AUTH=none.
#!/bin/sh
#################################
## CONFIG according to your needs
#################################
export CONTAINER=neo4j_cont
export NJ_VERSION=5.26.26
## Ports
export NJ_HTTP_PORT=7474
export NJ_HTTPS_PORT=7473
export NJ_BOLT_PORT=7687
## Change the location of the Neo4j directory
export NJ_HOME=~/neo4j_home
## APOC download
export NJ_APOC=https://github.com/neo4j/apoc/releases/download/5.26.26/apoc-5.26.26-core.jar
#################################
## RUN
#################################
mkdir -p $NJ_HOME
## Import and data directory
export NJ_IMPORT=$NJ_HOME/neo4jImport
mkdir -p $NJ_IMPORT
export NJ_DATA=$NJ_HOME/neo4jData
if test -e $NJ_DATA; then
echo "$NJ_DATA directory exists ==> abort - Remove it before proceeding" >&2
exit
fi
mkdir -p $NJ_DATA
export NJ_LOGS=$NJ_HOME/neo4jLogs
mkdir -p $NJ_LOGS
## SSL
export NJ_SSL=${NJ_HOME}/ssl
mkdir -p ${NJ_SSL}/https
mkdir -p ${NJ_SSL}/https/revoked
mkdir -p ${NJ_SSL}/https/trusted
openssl req -subj "/CN=localhost" -new -newkey rsa:2048 \
-days 365 -nodes -x509 \
-keyout ${NJ_SSL}/https/private.key \
-out ${NJ_SSL}/https/public.crt
cp ${NJ_SSL}/https/public.crt ${NJ_SSL}/https/trusted
chmod -R a+rwx ${NJ_SSL}
## Neo4j plugins: APOC
export NJ_PLUGINS=$NJ_HOME/neo4jPlugins
mkdir -p $NJ_PLUGINS
cd $NJ_PLUGINS
wget --no-check-certificate $NJ_APOC
cd -
## Add ` --env NEO4J_AUTH=none ` if you don't want to setup credentials
docker run -d \
--name $CONTAINER \
--publish=$NJ_HTTP_PORT:7474 \
--publish=$NJ_HTTPS_PORT:7473 \
--publish=$NJ_BOLT_PORT:7687 \
--env=NEO4J_server_memory_heap_initial__size=2G \
--env=NEO4J_server_memory_heap_max__size=2G \
--env=NEO4J_server_memory_pagecache_size=1G \
--env=NEO4J_server_db_query__cache__size=0 \
--env=NEO4J_dbms_cypher_min__replan__interval=100000000ms \
--env=NEO4J_dbms_cypher_statistics__divergence__threshold=1 \
--env=NEO4J_dbms_security_procedures_unrestricted=apoc.\\* \
--env=NEO4J_server_directories_import=import\
--volume=$NJ_IMPORT:/var/lib/neo4j/import \
--volume=$NJ_DATA/data:/data \
--volume=$NJ_LOGS:/var/lib/neo4j/logs \
--volume=$NJ_PLUGINS:/plugins \
--volume=$NJ_SSL:/ssl \
--env=NEO4J_server_https_enabled=true \
--env=NEO4J_dbms_ssl_policy_https_enabled=true \
--env=NEO4J_dbms_ssl_policy_https_base__directory=/ssl/https \
--env=NEO4J_dbms_ssl_policy_https_private__key=private.key \
--env=NEO4J_dbms_ssl_policy_https_public__certificate=public.crt \
--env=NEO4J_dbms_ssl_policy_https_client__auth=NONE \
--env=NEO4J_dbms_ssl_policy_https_trust__all=true \
neo4j:$NJ_VERSION
sleep 15
sudo chmod a+rwx $NJ_IMPORTNeo4j >= 2025
In recent versions of Neo4j (2025 and later), the APOC jar is bundled
in the image. The NEO4J_PLUGINS environment variable
automatically copies it in at container start, and persisting
/plugins avoids re-copying on every restart.
#!/bin/sh
#################################
## CONFIG according to your needs
#################################
export CONTAINER=neo4j_cont
export NJ_VERSION=2026.06.0
## Ports
export NJ_HTTP_PORT=7474
export NJ_HTTPS_PORT=7473
export NJ_BOLT_PORT=7687
## Change the location of the Neo4j directory
export NJ_HOME=~/neo4j_home
#################################
## RUN
#################################
mkdir -p $NJ_HOME
## Import and data directory
export NJ_IMPORT=$NJ_HOME/neo4jImport
mkdir -p $NJ_IMPORT
export NJ_DATA=$NJ_HOME/neo4jData
if test -e $NJ_DATA; then
echo "$NJ_DATA directory exists ==> abort - Remove it before proceeding" >&2
exit
fi
mkdir -p $NJ_DATA
export NJ_LOGS=$NJ_HOME/neo4jLogs
mkdir -p $NJ_LOGS
## SSL
export NJ_SSL=${NJ_HOME}/ssl
mkdir -p ${NJ_SSL}/https
mkdir -p ${NJ_SSL}/https/revoked
mkdir -p ${NJ_SSL}/https/trusted
openssl req -subj "/CN=localhost" -new -newkey rsa:2048 \
-days 365 -nodes -x509 \
-keyout ${NJ_SSL}/https/private.key \
-out ${NJ_SSL}/https/public.crt
cp ${NJ_SSL}/https/public.crt ${NJ_SSL}/https/trusted
chmod -R a+rwx ${NJ_SSL}
## Plugins directory (APOC jar is now bundled in the image;
## NEO4J_PLUGINS copies it in automatically at container start,
## and persisting /plugins avoids re-copying on every restart)
export NJ_PLUGINS=$NJ_HOME/neo4jPlugins
mkdir -p $NJ_PLUGINS
## Add ` --env NEO4J_AUTH=none ` if you don't want to setup credentials
docker run -d \
--name $CONTAINER \
--publish=$NJ_HTTP_PORT:7474 \
--publish=$NJ_HTTPS_PORT:7473 \
--publish=$NJ_BOLT_PORT:7687 \
--env=NEO4J_server_memory_heap_initial__size=2G \
--env=NEO4J_server_memory_heap_max__size=2G \
--env=NEO4J_server_memory_pagecache_size=1G \
--env=NEO4J_server_db_query__cache__size=0 \
--env=NEO4J_dbms_cypher_min__replan__interval=100000000ms \
--env=NEO4J_dbms_cypher_statistics__divergence__threshold=1 \
--env=NEO4J_PLUGINS='["apoc"]' \
--env=NEO4J_dbms_security_procedures_unrestricted=apoc.\\* \
--env=NEO4J_server_directories_import=import\
--volume=$NJ_IMPORT:/var/lib/neo4j/import \
--volume=$NJ_DATA/data:/data \
--volume=$NJ_LOGS:/var/lib/neo4j/logs \
--volume=$NJ_PLUGINS:/plugins \
--volume=$NJ_SSL:/ssl \
--env=NEO4J_server_https_enabled=true \
--env=NEO4J_dbms_ssl_policy_https_enabled=true \
--env=NEO4J_dbms_ssl_policy_https_base__directory=/ssl/https \
--env=NEO4J_dbms_ssl_policy_https_private__key=private.key \
--env=NEO4J_dbms_ssl_policy_https_public__certificate=public.crt \
--env=NEO4J_dbms_ssl_policy_https_client__auth=NONE \
--env=NEO4J_dbms_ssl_policy_https_trust__all=true \
neo4j:$NJ_VERSION
sleep 15
sudo chmod a+rwx $NJ_IMPORTUpdating Credentials for Neo4j >= 5
If you did not disable credentials (with
--env NEO4J_AUTH=none), you’ll need to first change the
user password before being able to connect to the graph database. The
following code shows how to do it with neo2R:
library(neo2R)
# First connect with default credentials
system <- startGraph(
"https://localhost:7473",
database = "system",
check = FALSE,
username = "neo4j",
password = "neo4j",
importPath = "~/neo4j_home/neo4jImport",
.opts = list(ssl_verifypeer = 0)
)
# Change the password
cypher(
system,
"ALTER CURRENT USER SET PASSWORD FROM 'neo4j' TO 'donttrustusers'"
)Key Differences Summary
| Version | APOC Configuration | SSL Configuration | Authentication |
|---|---|---|---|
| 3.x | Manual download, mount as volume |
client_policy directory |
Set via NEO4J_AUTH
|
| 4.x | Manual download, mount as volume |
https directory |
Set via NEO4J_AUTH
|
| 5.x | Manual download, mount as volume |
https directory |
Change after start or use NEO4J_AUTH=none
|
| 2025+ | Bundled, use NEO4J_PLUGINS
|
https directory |
Change after start or use NEO4J_AUTH=none
|
Further Reading
- Neo4j Docker documentation — Running Neo4j in a Docker container.