#
tokens: 49920/50000 83/140 files (page 1/7)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 1 of 7. Use http://codebase.md/chillbruhhh/crawl4ai-mcp?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .dockerignore
├── .env.example
├── .gitattributes
├── .gitignore
├── crawled_pages.sql
├── Dockerfile
├── knowledge_graphs
│   ├── ai_hallucination_detector.py
│   ├── ai_script_analyzer.py
│   ├── hallucination_reporter.py
│   ├── knowledge_graph_validator.py
│   ├── parse_repo_into_neo4j.py
│   ├── query_knowledge_graph.py
│   └── test_script.py
├── LICENSE
├── neo4j
│   └── docker-neo4j
│       ├── .github
│       │   └── ISSUE_TEMPLATE
│       │       └── bug_report.md
│       ├── .gitignore
│       ├── build-docker-image.sh
│       ├── build-utils-common-functions.sh
│       ├── COPYRIGHT
│       ├── DEVELOPMENT.md
│       ├── devenv
│       ├── devenv.local.template
│       ├── docker-image-src
│       │   ├── 2.3
│       │   │   ├── docker-entrypoint.sh
│       │   │   └── Dockerfile
│       │   ├── 3.0
│       │   │   ├── docker-entrypoint.sh
│       │   │   └── Dockerfile
│       │   ├── 3.1
│       │   │   ├── docker-entrypoint.sh
│       │   │   └── Dockerfile
│       │   ├── 3.2
│       │   │   ├── docker-entrypoint.sh
│       │   │   └── Dockerfile
│       │   ├── 3.3
│       │   │   ├── docker-entrypoint.sh
│       │   │   └── Dockerfile
│       │   ├── 3.4
│       │   │   ├── docker-entrypoint.sh
│       │   │   └── Dockerfile
│       │   ├── 3.5
│       │   │   ├── coredb
│       │   │   │   ├── docker-entrypoint.sh
│       │   │   │   ├── Dockerfile
│       │   │   │   └── neo4j-plugins.json
│       │   │   └── neo4j-admin
│       │   │       ├── docker-entrypoint.sh
│       │   │       └── Dockerfile
│       │   ├── 4.0
│       │   │   ├── coredb
│       │   │   │   ├── docker-entrypoint.sh
│       │   │   │   └── Dockerfile
│       │   │   └── neo4j-admin
│       │   │       ├── docker-entrypoint.sh
│       │   │       └── Dockerfile
│       │   ├── 4.1
│       │   │   ├── coredb
│       │   │   │   ├── docker-entrypoint.sh
│       │   │   │   └── Dockerfile
│       │   │   └── neo4j-admin
│       │   │       ├── docker-entrypoint.sh
│       │   │       └── Dockerfile
│       │   ├── 4.2
│       │   │   ├── coredb
│       │   │   │   ├── docker-entrypoint.sh
│       │   │   │   ├── Dockerfile
│       │   │   │   └── neo4j-plugins.json
│       │   │   └── neo4j-admin
│       │   │       ├── docker-entrypoint.sh
│       │   │       └── Dockerfile
│       │   ├── 4.3
│       │   │   ├── coredb
│       │   │   │   ├── docker-entrypoint.sh
│       │   │   │   ├── Dockerfile
│       │   │   │   └── neo4j-plugins.json
│       │   │   └── neo4j-admin
│       │   │       ├── docker-entrypoint.sh
│       │   │       └── Dockerfile
│       │   ├── 4.4
│       │   │   ├── coredb
│       │   │   │   ├── docker-entrypoint.sh
│       │   │   │   ├── Dockerfile-debian
│       │   │   │   ├── Dockerfile-ubi9
│       │   │   │   ├── neo4j-admin-report.sh
│       │   │   │   └── neo4j-plugins.json
│       │   │   └── neo4j-admin
│       │   │       ├── docker-entrypoint.sh
│       │   │       ├── Dockerfile-debian
│       │   │       └── Dockerfile-ubi9
│       │   ├── 5
│       │   │   ├── coredb
│       │   │   │   ├── docker-entrypoint.sh
│       │   │   │   ├── Dockerfile-debian
│       │   │   │   ├── Dockerfile-ubi8
│       │   │   │   ├── Dockerfile-ubi9
│       │   │   │   ├── neo4j-admin-report.sh
│       │   │   │   └── neo4j-plugins.json
│       │   │   └── neo4j-admin
│       │   │       ├── docker-entrypoint.sh
│       │   │       ├── Dockerfile-debian
│       │   │       ├── Dockerfile-ubi8
│       │   │       └── Dockerfile-ubi9
│       │   ├── calver
│       │   │   ├── coredb
│       │   │   │   ├── docker-entrypoint.sh
│       │   │   │   ├── Dockerfile-debian
│       │   │   │   ├── Dockerfile-ubi9
│       │   │   │   ├── neo4j-admin-report.sh
│       │   │   │   └── neo4j-plugins.json
│       │   │   └── neo4j-admin
│       │   │       ├── docker-entrypoint.sh
│       │   │       ├── Dockerfile-debian
│       │   │       └── Dockerfile-ubi9
│       │   └── common
│       │       ├── semver.jq
│       │       └── utilities.sh
│       ├── generate-stub-plugin
│       │   ├── build.gradle.kts
│       │   ├── Dockerfile
│       │   ├── ExampleNeo4jPlugin.java
│       │   ├── Makefile
│       │   ├── README.md
│       │   └── settings.gradle.kts
│       ├── LICENSE
│       ├── Makefile
│       ├── pom.xml
│       ├── publish-neo4j-admin-image.sh
│       ├── publish-neo4j-admin-images.sh
│       ├── README.md
│       └── src
│           ├── main
│           │   └── resources
│           │       └── log4j.properties
│           └── test
│               ├── java
│               │   └── com
│               │       └── neo4j
│               │           └── docker
│               │               ├── coredb
│               │               │   ├── configurations
│               │               │   │   ├── Configuration.java
│               │               │   │   ├── Setting.java
│               │               │   │   ├── TestConfSettings.java
│               │               │   │   ├── TestExtendedConf.java
│               │               │   │   └── TestJVMAdditionalConfig.java
│               │               │   ├── plugins
│               │               │   │   ├── Neo4jPluginEnv.java
│               │               │   │   ├── StubPluginHelper.java
│               │               │   │   ├── TestBundledPluginInstallation.java
│               │               │   │   ├── TestPluginInstallation.java
│               │               │   │   └── TestSemVerPluginMatching.java
│               │               │   ├── TestAdminReport.java
│               │               │   ├── TestAuthentication.java
│               │               │   ├── TestBasic.java
│               │               │   ├── TestCausalCluster.java
│               │               │   ├── TestMounting.java
│               │               │   └── TestUpgrade.java
│               │               ├── neo4jadmin
│               │               │   ├── TestAdminBasic.java
│               │               │   ├── TestBackupRestore.java
│               │               │   ├── TestBackupRestore44.java
│               │               │   ├── TestDumpLoad.java
│               │               │   ├── TestDumpLoad44.java
│               │               │   └── TestReport.java
│               │               ├── TestDeprecationWarning.java
│               │               ├── TestDockerComposeSecrets.java
│               │               └── utils
│               │                   ├── DatabaseIO.java
│               │                   ├── HostFileHttpHandler.java
│               │                   ├── HttpServerTestExtension.java
│               │                   ├── Neo4jVersion.java
│               │                   ├── Neo4jVersionTest.java
│               │                   ├── Network.java
│               │                   ├── SetContainerUser.java
│               │                   ├── TemporaryFolderManager.java
│               │                   ├── TemporaryFolderManagerTest.java
│               │                   ├── TestSettings.java
│               │                   └── WaitStrategies.java
│               └── resources
│                   ├── causal-cluster-compose.yml
│                   ├── confs
│                   │   ├── before50
│                   │   │   ├── ConfsNotOverridden.conf
│                   │   │   ├── ConfsReplaced.conf
│                   │   │   ├── EnterpriseOnlyNotOverwritten.conf
│                   │   │   ├── EnvVarsOverride.conf
│                   │   │   ├── ExtendedConf.conf
│                   │   │   ├── InvalidExtendedConf.conf
│                   │   │   ├── JvmAdditionalNotOverridden.conf
│                   │   │   ├── NoNewline.conf
│                   │   │   └── ReadConf.conf
│                   │   ├── ConfsNotOverridden.conf
│                   │   ├── ConfsReplaced.conf
│                   │   ├── EnterpriseOnlyNotOverwritten.conf
│                   │   ├── EnvVarsOverride.conf
│                   │   ├── ExtendedConf.conf
│                   │   ├── InvalidExtendedConf.conf
│                   │   ├── JvmAdditionalNotOverridden.conf
│                   │   ├── NoNewline.conf
│                   │   └── ReadConf.conf
│                   ├── dockersecrets
│                   │   ├── container-compose-with-incorrect-secrets.yml
│                   │   ├── container-compose-with-secrets-override.yml
│                   │   ├── container-compose-with-secrets.yml
│                   │   ├── simple-container-compose-with-external-file-var.yml
│                   │   └── simple-container-compose.yml
│                   ├── ha-cluster-compose.yml
│                   └── stubplugin
│                       └── myPlugin.jar
├── pyproject.toml
├── README.md
├── src
│   ├── crawl4ai_mcp.py
│   └── utils.py
└── uv.lock
```

# Files

--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------

```
1 | crawl4ai_mcp.egg-info
2 | __pycache__
3 | .venv
4 | .env
```

--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------

```
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/.gitignore:
--------------------------------------------------------------------------------

```
 1 | .idea
 2 | .java-version
 3 | *.iml
 4 | /tmp/
 5 | /out/
 6 | /in/
 7 | /devenv.local
 8 | /local-mounts/
 9 | /target/
10 | /build/
11 | .DS_Store
12 | # simlinks to dev scripts in https://github.com/neo-technology/teamcity-witchcraft
13 | download_tool.py
14 | docker_tests_get_installers.py
15 | __pycache__/
16 | 
```

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
  1 | # Environment variables
  2 | .env
  3 | .env.local
  4 | .env.development.local
  5 | .env.test.local
  6 | .env.production.local
  7 | .env.txt
  8 | 
  9 | # Python
 10 | __pycache__/
 11 | *.py[cod]
 12 | *$py.class
 13 | *.so
 14 | .Python
 15 | build/
 16 | develop-eggs/
 17 | dist/
 18 | downloads/
 19 | eggs/
 20 | .eggs/
 21 | lib/
 22 | lib64/
 23 | parts/
 24 | sdist/
 25 | var/
 26 | wheels/
 27 | share/python-wheels/
 28 | *.egg-info/
 29 | .installed.cfg
 30 | *.egg
 31 | MANIFEST
 32 | 
 33 | __pycache__
 34 | crawl4ai_mcp.egg-info
 35 | repos
 36 | 
 37 | # Virtual environments
 38 | .venv
 39 | .venv/
 40 | venv/
 41 | ENV/
 42 | env/
 43 | .env/
 44 | 
 45 | # IDE and editor files
 46 | .vscode/
 47 | .idea/
 48 | *.swp
 49 | *.swo
 50 | *~
 51 | .DS_Store
 52 | .claude
 53 | .cursor
 54 | 
 55 | # Jupyter Notebook
 56 | .ipynb_checkpoints
 57 | 
 58 | # PyCharm
 59 | .idea/
 60 | 
 61 | # Project specific
 62 | crawl4ai_mcp.egg-info/
 63 | repos/
 64 | knowledge_graphs/repos/
 65 | test_script_hallucination*
 66 | 
 67 | # Docker
 68 | .dockerignore
 69 | docker-compose.override.yml
 70 | 
 71 | # Logs
 72 | *.log
 73 | logs/
 74 | 
 75 | # Neo4j
 76 | .neo4j/
 77 | 
 78 | # Temporary files
 79 | *.tmp
 80 | *.temp
 81 | .tmp/
 82 | 
 83 | # OS generated files
 84 | .DS_Store
 85 | .DS_Store?
 86 | ._*
 87 | .Spotlight-V100
 88 | .Trashes
 89 | ehthumbs.db
 90 | Thumbs.db
 91 | 
 92 | # Coverage reports
 93 | htmlcov/
 94 | .coverage
 95 | .coverage.*
 96 | coverage.xml
 97 | *.cover
 98 | .hypothesis/
 99 | .pytest_cache/
100 | 
101 | # Playwright browsers
102 | .playwright/
103 | 
104 | # UV lock files (keep uv.lock for reproducible builds)
105 | # uv.lock
106 | 
107 | # FastMCP generated files
108 | .fastmcp/
```

--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------

```
 1 | # The transport for the MCP server - either 'sse' or 'stdio' (defaults to sse if left empty)
 2 | TRANSPORT=
 3 | 
 4 | # Host to bind to if using sse as the transport (leave empty if using stdio)
 5 | # Set this to 0.0.0.0 if using Docker, otherwise set to localhost (if using uv)
 6 | HOST=0.0.0.0
 7 | 
 8 | # Port to listen on if using sse as the transport (leave empty if using stdio)
 9 | PORT=8051
10 | 
11 | # Get your Open AI API Key by following these instructions -
12 | # https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key
13 | # This is for the embedding model - text-embed-small-3 will be used
14 | OPENAI_API_KEY=
15 | # Get your OpenRouter API Key from https://openrouter.ai/keys
16 | # This is for chat completions (summaries, contextual embeddings, code example summaries)
17 | OPENROUTER_API_KEY=
18 | 
19 | # The LLM you want to use for summaries and contextual embeddings
20 | # Use OpenRouter model format like openai/gpt-4o-mini, anthropic/claude-3-haiku, etc.
21 | MODEL_CHOICE=openai/gpt-4o-mini
22 | 
23 | # Optional: Your site URL and name for OpenRouter rankings (optional)
24 | YOUR_SITE_URL=
25 | YOUR_SITE_NAME=Crawl4AI-MCP
26 | 
27 | # RAG strategies - set these to "true" or "false" (default to "false")
28 | # USE_CONTEXTUAL_EMBEDDINGS: Enhances embeddings with contextual information for better retrieval
29 | USE_CONTEXTUAL_EMBEDDINGS=true
30 | 
31 | # USE_HYBRID_SEARCH: Combines vector similarity search with keyword search for better results
32 | USE_HYBRID_SEARCH=true
33 | 
34 | # USE_AGENTIC_RAG: Enables code example extraction, storage, and specialized code search functionality
35 | USE_AGENTIC_RAG=true
36 | 
37 | # USE_RERANKING: Applies cross-encoder reranking to improve search result relevance
38 | USE_RERANKING=true
39 | 
40 | # USE_KNOWLEDGE_GRAPH: Enables AI hallucination detection and repository parsing tools using Neo4j
41 | # If you set this to true, you must also set the Neo4j environment variables below.
42 | USE_KNOWLEDGE_GRAPH=false
43 | 
44 | # For the Supabase version (sample_supabase_agent.py), set your Supabase URL and Service Key.
45 | # Get your SUPABASE_URL from the API section of your Supabase project settings -
46 | # https://supabase.com/dashboard/project/<your project ID>/settings/api
47 | SUPABASE_URL=
48 | 
49 | # Get your SUPABASE_SERVICE_KEY from the API section of your Supabase project settings -
50 | # https://supabase.com/dashboard/project/<your project ID>/settings/api
51 | # On this page it is called the service_role secret.
52 | SUPABASE_SERVICE_KEY=
53 | 
54 | # Neo4j Configuration for Knowledge Graph Tools
55 | # These are required for the AI hallucination detection and repository parsing tools
56 | # Leave empty to disable knowledge graph functionality
57 | 
58 | # Neo4j connection URI - use bolt://localhost:7687 for local, neo4j:// for cloud instances
59 | # IMPORTANT: If running the MCP server through Docker, change localhost to host.docker.internal
60 | NEO4J_URI=bolt://localhost:7687
61 | 
62 | # Neo4j username (usually 'neo4j' for default installations)
63 | NEO4J_USER=neo4j
64 | 
65 | # Neo4j password for your database instance
66 | NEO4J_PASSWORD=password
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/generate-stub-plugin/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # What is this?
 2 | 
 3 | This code is purely for generating the [myPlugin.jar test artifact](../src/test/resources/testplugin/myPlugin.jar).
 4 | It is a test artifact used for verifying that the `NEO4J_PLUGINS` feature works correctly. *It has nothing to do with Neo4j database or even the Neo4j docker image source code.*
 5 | 
 6 | # Do I need to run this code at all?
 7 | 
 8 | Short answer: **No.**
 9 | 
10 | A pre-generated `myPlugin.jar` is already included in the test resources. 
11 | 
12 | The only situation where you would need to even look at this is if you are actively developing the Neo4j docker image and for some reason the plugin tests are not loading `myPlugin.jar` any more.
13 | 
14 | 
15 | ## How to generate new test plugin
16 | 
17 | The Makefile will do all the work for you, all you need to do is pick which version of Neo4j to use:
18 | 
19 | ```shell
20 | NEO4JVERSION=4.4.11 make clean plugin
21 | ```
22 | 
23 | The Dockerfile is currently set to use java 11. If that needs to change then just change the base image that the Dockerfile uses.
24 | 
25 | Don't forget to commit the newly generated `myPlugin.jar` back to git when you've finished.
26 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/README.md:
--------------------------------------------------------------------------------

```markdown
  1 | *NOTE:* Supported images are available in the [official image library](https://hub.docker.com/_/neo4j/) on Docker Hub.
  2 | Please use those in production.
  3 | 
  4 | # Neo4j Docker Image Build and Run Guide
  5 | 
  6 | ## Prerequisites
  7 | 
  8 | - **Docker Desktop** installed and running
  9 | - **Git** (for Git Bash on Windows)
 10 | - **Make** (optional, for convenience commands)
 11 | - **Internet connection** (to download Neo4j source tarballs)
 12 | 
 13 | ## Quick Start
 14 | 
 15 | ### 1. Building the Image
 16 | 
 17 | #### On Windows (PowerShell)
 18 | ```powershell
 19 | # Navigate to the docker-neo4j directory
 20 | cd docker-neo4j
 21 | 
 22 | # Build Neo4j 5.9.0 Community Edition on Debian
 23 | & "C:\Program Files\Git\bin\bash.exe" ./build-docker-image.sh 5.9.0 community debian
 24 | 
 25 | # Build Neo4j 4.4.30 Enterprise Edition on Red Hat UBI9
 26 | & "C:\Program Files\Git\bin\bash.exe" ./build-docker-image.sh 4.4.30 enterprise ubi9
 27 | ```
 28 | 
 29 | #### On Linux/Mac
 30 | ```bash
 31 | # Navigate to the docker-neo4j directory
 32 | cd docker-neo4j
 33 | 
 34 | # Build Neo4j 5.9.0 Community Edition on Debian
 35 | ./build-docker-image.sh 5.9.0 community debian
 36 | 
 37 | # Build Neo4j 4.4.30 Enterprise Edition on Red Hat UBI9
 38 | ./build-docker-image.sh 4.4.30 enterprise ubi9
 39 | ```
 40 | 
 41 | #### Using Make (Linux/Mac)
 42 | ```bash
 43 | # Build and tag Neo4j 5.9.0 Community Edition
 44 | NEO4JVERSION=5.9.0 make tag-debian-community
 45 | 
 46 | # Build and tag Neo4j 4.4.30 Enterprise Edition
 47 | NEO4JVERSION=4.4.30 make tag-ubi9-enterprise
 48 | ```
 49 | 
 50 | ### 2. Running the Container
 51 | 
 52 | #### Basic Usage
 53 | ```bash
 54 | # Run Neo4j Community Edition
 55 | docker run -d --name neo4j-container \
 56 |     -p 7474:7474 -p 7687:7687 \
 57 |     -v neo4j-data:/data \
 58 |     -v neo4j-logs:/logs \
 59 |     -e NEO4J_AUTH=neo4j/your-password \
 60 |     neo4jtest:TAG_ID
 61 | 
 62 | # Run Neo4j Enterprise Edition
 63 | docker run -d --name neo4j-enterprise \
 64 |     -p 7474:7474 -p 7687:7687 \
 65 |     -v neo4j-data:/data \
 66 |     -v neo4j-logs:/logs \
 67 |     -e NEO4J_AUTH=neo4j/your-password \
 68 |     -e NEO4J_ACCEPT_LICENSE_AGREEMENT=yes \
 69 |     neo4jtest:TAG_ID
 70 | ```
 71 | 
 72 | #### With Custom Configuration
 73 | ```bash
 74 | docker run -d --name neo4j-container \
 75 |     -p 7474:7474 -p 7687:7687 \
 76 |     -v neo4j-data:/data \
 77 |     -v neo4j-logs:/logs \
 78 |     -v neo4j-conf:/conf \
 79 |     -e NEO4J_AUTH=neo4j/your-password \
 80 |     -e NEO4J_server_memory_heap_initial__size=1G \
 81 |     -e NEO4J_server_memory_heap_max__size=2G \
 82 |     neo4jtest:TAG_ID
 83 | ```
 84 | 
 85 | ### 3. Accessing Neo4j
 86 | 
 87 | #### Neo4j Browser (Web Interface)
 88 | Open your browser and go to: **http://localhost:7474/**
 89 | 
 90 | Login with:
 91 | - **Username**: `neo4j`
 92 | - **Password**: `your-password` (as set in NEO4J_AUTH)
 93 | 
 94 | #### Programmatic Access
 95 | - **Bolt Protocol**: `bolt://localhost:7687`
 96 | - **HTTP API**: `http://localhost:7474/`
 97 | 
 98 | ## Build Options
 99 | 
100 | ### Supported Versions
101 | - **Neo4j 5.x**: Latest features (recommended)
102 | - **Neo4j 4.4.x**: LTS support
103 | - **Neo4j 4.0-4.3**: Legacy support
104 | 
105 | ### Supported Editions
106 | - **Community**: Free, open-source edition
107 | - **Enterprise**: Commercial edition with advanced features
108 | 
109 | ### Supported Base OS
110 | - **debian**: Debian bullseye-slim (recommended)
111 | - **ubi9**: Red Hat Universal Base Image 9
112 | - **ubi8**: Red Hat Universal Base Image 8 (deprecated)
113 | 
114 | ## Common Issues and Solutions
115 | 
116 | ### Windows Line Ending Issues
117 | If you get errors like `$'\r': command not found`, convert scripts to Unix line endings:
118 | 
119 | ```bash
120 | # Using Git Bash on Windows
121 | dos2unix docker-image-src/common/utilities.sh
122 | dos2unix docker-image-src/5/coredb/docker-entrypoint.sh
123 | dos2unix docker-image-src/5/coredb/neo4j-admin-report.sh
124 | ```
125 | 
126 | ### SHA Command Issues
127 | The build script uses `shasum` which may not be available on all systems. The script has been updated to use `sha256sum` as an alternative.
128 | 
129 | ### Download Issues
130 | If the build fails to download the Neo4j tarball, you can manually download it:
131 | 
132 | ```bash
133 | # Download manually
134 | curl -L -o in/neo4j-community-5.9.0-unix.tar.gz https://dist.neo4j.org/neo4j-community-5.9.0-unix.tar.gz
135 | 
136 | # Then run the build
137 | ./build-docker-image.sh 5.9.0 community debian
138 | ```
139 | 
140 | ## Container Management
141 | 
142 | ### Check Container Status
143 | ```bash
144 | docker ps | grep neo4j
145 | ```
146 | 
147 | ### View Logs
148 | ```bash
149 | docker logs neo4j-container
150 | ```
151 | 
152 | ### Stop/Start Container
153 | ```bash
154 | docker stop neo4j-container
155 | docker start neo4j-container
156 | ```
157 | 
158 | ### Remove Container (data persists in volumes)
159 | ```bash
160 | docker rm neo4j-container
161 | ```
162 | 
163 | ## Data Persistence
164 | 
165 | Neo4j data is stored in Docker volumes:
166 | - **Database data**: `neo4j-data` volume
167 | - **Logs**: `neo4j-logs` volume
168 | - **Configuration**: `neo4j-conf` volume (optional)
169 | 
170 | To backup data:
171 | ```bash
172 | docker run --rm -v neo4j-data:/data -v $(pwd):/backup ubuntu tar czf /backup/neo4j-backup.tar.gz /data
173 | ```
174 | 
175 | ## Environment Variables
176 | 
177 | Common environment variables for configuration:
178 | - `NEO4J_AUTH=neo4j/password` - Set authentication
179 | - `NEO4J_AUTH=none` - Disable authentication (not recommended)
180 | - `NEO4J_ACCEPT_LICENSE_AGREEMENT=yes` - Accept enterprise license
181 | - `NEO4J_server_memory_heap_initial__size=1G` - Set initial heap size
182 | - `NEO4J_server_memory_heap_max__size=2G` - Set maximum heap size
183 | 
184 | ## Using the Built Images
185 | 
186 | After building, you can tag your images for easier management:
187 | 
188 | ```bash
189 | # Tag the built images
190 | docker tag neo4jtest:TAG_ID neo4j:5.9.0-community-debian
191 | docker tag neo4jadmintest:TAG_ID neo4j-admin:5.9.0-community-debian
192 | 
193 | # Use the tagged images
194 | docker run -d --name neo4j-container \
195 |     -p 7474:7474 -p 7687:7687 \
196 |     -v neo4j-data:/data \
197 |     -e NEO4J_AUTH=neo4j/password \
198 |     neo4j:5.9.0-community-debian
199 | ```
200 | 
201 | ## Complete Example
202 | 
203 | Here's a complete example from building to running Neo4j:
204 | 
205 | ```bash
206 | # 1. Build the image
207 | & "C:\Program Files\Git\bin\bash.exe" ./build-docker-image.sh 5.9.0 community debian
208 | 
209 | # 2. Find the built image ID
210 | docker images | grep neo4jtest
211 | 
212 | # 3. Run the container
213 | docker run -d --name neo4j-container \
214 |     -p 7474:7474 -p 7687:7687 \
215 |     -v neo4j-data:/data \
216 |     -v neo4j-logs:/logs \
217 |     -e NEO4J_AUTH=neo4j/mypassword \
218 |     neo4jtest:TAG_ID
219 | 
220 | # 4. Check if it's running
221 | docker ps | grep neo4j
222 | 
223 | # 5. View startup logs
224 | docker logs neo4j-container
225 | 
226 | # 6. Access Neo4j Browser at http://localhost:7474
227 | # Login with: neo4j/mypassword
228 | ```
229 | 
230 | ## Testing Your Build
231 | 
232 | After building and running, you can test your Neo4j instance:
233 | 
234 | ```bash
235 | # Test with cypher-shell (if available)
236 | docker exec -it neo4j-container cypher-shell -u neo4j -p mypassword
237 | 
238 | # Or test with curl
239 | curl -u neo4j:mypassword -H "Content-Type: application/json" \
240 |     -X POST http://localhost:7474/db/data/transaction/commit \
241 |     -d '{"statements":[{"statement":"CREATE (n:Test {name: \"Hello World\"}) RETURN n"}]}'
242 | ```
243 | 
244 | # Neo4j images for ARM64
245 | 
246 | From 4.4.0 and onwards, Neo4j images have been available for ARM64 architectures through [Docker Hub](https://hub.docker.com/_/neo4j/).
247 | 
248 | For earlier versions, we provide unsupported and untested builds of ARM64 Neo4j community edition from 4.0.0 to 4.3.23. 
249 | These are unsuitable for production use, but may be useful for experimentation or hobbyists. 
250 | 
251 | They are available on Docker hub at:
252 | 
253 | https://hub.docker.com/r/neo4j/neo4j-arm64-experimental
254 | 
255 | The images take the name format `neo4j/neo4j-arm64-experimental:<VERSION>-arm64`.
256 | 
257 | ## Building on ARM64
258 | 
259 | The build process is the same as on other architectures for Neo4j 4.4.0+:
260 | 
261 | ```bash
262 | # ARM64 build example
263 | ./build-docker-image.sh 4.4.30 community debian
264 | ```
265 | 
266 | 
267 | # Building and Developing the Neo4j Docker Image
268 | 
269 | See [DEVELOPMENT.md](DEVELOPMENT.md)
270 | 
271 | # Getting support and contributing
272 | 
273 | For bug reports and feature requests, please create issues and pull requests against this Github repository.
274 | 
275 | If you need guidance with using Neo4j you can ask questions here: https://community.neo4j.com/
276 | 
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
  1 | <h1 align="center">Crawl4AI RAG MCP Server</h1>
  2 | 
  3 | <p align="center">
  4 |   <em>Web Crawling and RAG Capabilities for AI Agents and AI Coding Assistants</em>
  5 | </p>
  6 | 
  7 | A powerful implementation of the [Model Context Protocol (MCP)](https://modelcontextprotocol.io) integrated with [Crawl4AI](https://crawl4ai.com) and [Supabase](https://supabase.com/) for providing AI agents and AI coding assistants with advanced web crawling and RAG capabilities.
  8 | 
  9 | With this MCP server, you can <b>scrape anything</b> and then <b>use that knowledge anywhere</b> for RAG.
 10 | 
 11 | The primary goal is to bring this MCP server into [Archon](https://github.com/coleam00/Archon) as I evolve it to be more of a knowledge engine for AI coding assistants to build AI agents. This first version of the Crawl4AI/RAG MCP server will be improved upon greatly soon, especially making it more configurable so you can use different embedding models and run everything locally with Ollama.
 12 | 
 13 | Consider this GitHub repository a testbed, hence why I haven't been super actively address issues and pull requests yet. I certainly will though as I bring this into Archon V2!
 14 | 
 15 | ## Overview
 16 | 
 17 | This MCP server provides tools that enable AI agents to crawl websites, store content in a vector database (Supabase), and perform RAG over the crawled content. It follows the best practices for building MCP servers based on the [Mem0 MCP server template](https://github.com/coleam00/mcp-mem0/) I provided on my channel previously.
 18 | 
 19 | The server includes several advanced RAG strategies that can be enabled to enhance retrieval quality:
 20 | - **Contextual Embeddings** for enriched semantic understanding
 21 | - **Hybrid Search** combining vector and keyword search
 22 | - **Agentic RAG** for specialized code example extraction
 23 | - **Reranking** for improved result relevance using cross-encoder models
 24 | - **Knowledge Graph** for AI hallucination detection and repository code analysis
 25 | 
 26 | See the [Configuration section](#configuration) below for details on how to enable and configure these strategies.
 27 | 
 28 | ## Vision
 29 | 
 30 | The Crawl4AI RAG MCP server is just the beginning. Here's where we're headed:
 31 | 
 32 | 1. **Integration with Archon**: Building this system directly into [Archon](https://github.com/coleam00/Archon) to create a comprehensive knowledge engine for AI coding assistants to build better AI agents.
 33 | 
 34 | 2. **Multiple Embedding Models**: Expanding beyond OpenAI to support a variety of embedding models, including the ability to run everything locally with Ollama for complete control and privacy.
 35 | 
 36 | 3. **Advanced RAG Strategies**: Implementing sophisticated retrieval techniques like contextual retrieval, late chunking, and others to move beyond basic "naive lookups" and significantly enhance the power and precision of the RAG system, especially as it integrates with Archon.
 37 | 
 38 | 4. **Enhanced Chunking Strategy**: Implementing a Context 7-inspired chunking approach that focuses on examples and creates distinct, semantically meaningful sections for each chunk, improving retrieval precision.
 39 | 
 40 | 5. **Performance Optimization**: Increasing crawling and indexing speed to make it more realistic to "quickly" index new documentation to then leverage it within the same prompt in an AI coding assistant.
 41 | 
 42 | ## Features
 43 | 
 44 | - **Smart URL Detection**: Automatically detects and handles different URL types (regular webpages, sitemaps, text files)
 45 | - **Recursive Crawling**: Follows internal links to discover content
 46 | - **Parallel Processing**: Efficiently crawls multiple pages simultaneously
 47 | - **Content Chunking**: Intelligently splits content by headers and size for better processing
 48 | - **Vector Search**: Performs RAG over crawled content, optionally filtering by data source for precision
 49 | - **Source Retrieval**: Retrieve sources available for filtering to guide the RAG process
 50 | - **Full Docker Support**: Complete Docker compatibility including Neo4j knowledge graph functionality
 51 | - **Knowledge Graph Integration**: AI hallucination detection and repository analysis with included Neo4j Docker setup
 52 | 
 53 | ## Tools
 54 | 
 55 | The server provides essential web crawling and search tools:
 56 | 
 57 | ### Core Tools (Always Available)
 58 | 
 59 | 1. **`crawl_single_page`**: Quickly crawl a single web page and store its content in the vector database
 60 | 2. **`smart_crawl_url`**: Intelligently crawl a full website based on the type of URL provided (sitemap, llms-full.txt, or a regular webpage that needs to be crawled recursively)
 61 | 3. **`get_available_sources`**: Get a list of all available sources (domains) in the database
 62 | 4. **`perform_rag_query`**: Search for relevant content using semantic search with optional source filtering
 63 | 
 64 | ### Conditional Tools
 65 | 
 66 | 5. **`search_code_examples`** (requires `USE_AGENTIC_RAG=true`): Search specifically for code examples and their summaries from crawled documentation. This tool provides targeted code snippet retrieval for AI coding assistants.
 67 | 
 68 | ### Knowledge Graph Tools (requires `USE_KNOWLEDGE_GRAPH=true`, see below)
 69 | 
 70 | 6. **`parse_github_repository`**: Parse a GitHub repository into a Neo4j knowledge graph, extracting classes, methods, functions, and their relationships for hallucination detection
 71 | 7. **`check_ai_script_hallucinations`**: Analyze Python scripts for AI hallucinations by validating imports, method calls, and class usage against the knowledge graph
 72 | 8. **`query_knowledge_graph`**: Explore and query the Neo4j knowledge graph with commands like `repos`, `classes`, `methods`, and custom Cypher queries
 73 | 
 74 | ## Prerequisites
 75 | 
 76 | - [Docker/Docker Desktop](https://www.docker.com/products/docker-desktop/) if running the MCP server as a container (recommended)
 77 | - [Python 3.12+](https://www.python.org/downloads/) if running the MCP server directly through uv
 78 | - [Supabase](https://supabase.com/) (database for RAG)
 79 | - [OpenAI API key](https://platform.openai.com/api-keys) (for generating embeddings)
 80 | - [OpenRouter API key](https://openrouter.ai/keys) (for LLM chat completions)
 81 | - [Neo4j](https://neo4j.com/) (optional, for knowledge graph functionality) - see [Knowledge Graph Setup](#knowledge-graph-setup) section
 82 | 
 83 | ## Installation
 84 | 
 85 | ### Using Docker (Recommended)
 86 | 
 87 | 1. Clone this repository:
 88 |    ```bash
 89 |    git clone https://github.com/coleam00/mcp-crawl4ai-rag.git
 90 |    cd mcp-crawl4ai-rag
 91 |    ```
 92 | 
 93 | 2. Build the Docker image:
 94 |    ```bash
 95 |    docker build -t mcp/crawl4ai-rag --build-arg PORT=8051 .
 96 |    ```
 97 | 
 98 | 3. Create a `.env` file based on the configuration section below
 99 | 
100 | ### Using uv directly (no Docker)
101 | 
102 | 1. Clone this repository:
103 |    ```bash
104 |    git clone https://github.com/coleam00/mcp-crawl4ai-rag.git
105 |    cd mcp-crawl4ai-rag
106 |    ```
107 | 
108 | 2. Install uv if you don't have it:
109 |    ```bash
110 |    pip install uv
111 |    ```
112 | 
113 | 3. Create and activate a virtual environment:
114 |    ```bash
115 |    uv venv
116 |    .venv\Scripts\activate
117 |    # on Mac/Linux: source .venv/bin/activate
118 |    ```
119 | 
120 | 4. Install dependencies:
121 |    ```bash
122 |    uv pip install -e .
123 |    crawl4ai-setup
124 |    ```
125 | 
126 | 5. Create a `.env` file based on the configuration section below
127 | 
128 | ## Database Setup
129 | 
130 | Before running the server, you need to set up the database with the pgvector extension:
131 | 
132 | 1. Go to the SQL Editor in your Supabase dashboard (create a new project first if necessary)
133 | 
134 | 2. Create a new query and paste the contents of `crawled_pages.sql`
135 | 
136 | 3. Run the query to create the necessary tables and functions
137 | 
138 | ## Knowledge Graph Setup (Optional)
139 | 
140 | To enable AI hallucination detection and repository analysis features, you need to set up Neo4j.
141 | 
142 | **Neo4j Docker Support**: The knowledge graph implementation is now fully compatible with Docker! You can run the entire MCP server with Neo4j using the included Docker setup.
143 | 
144 | For installing Neo4j:
145 | 
146 | ### Local AI Package (Recommended)
147 | 
148 | The easiest way to get Neo4j running locally is with the [Local AI Package](https://github.com/coleam00/local-ai-packaged) - a curated collection of local AI services including Neo4j:
149 | 
150 | 1. **Clone the Local AI Package**:
151 |    ```bash
152 |    git clone https://github.com/coleam00/local-ai-packaged.git
153 |    cd local-ai-packaged
154 |    ```
155 | 
156 | 2. **Start Neo4j**:
157 |    Follow the instructions in the Local AI Package repository to start Neo4j with Docker Compose
158 | 
159 | 3. **Default connection details**:
160 |    - URI: `bolt://localhost:7687`
161 |    - Username: `neo4j`
162 |    - Password: Check the Local AI Package documentation for the default password
163 | 
164 | ### Using the Included Neo4j Docker Setup (Recommended)
165 | 
166 | **Quick Setup** - Build and run Neo4j in under 2 minutes:
167 | 
168 | 1. **Build the Neo4j Docker image**:
169 |    ```bash
170 |    cd neo4j/docker-neo4j
171 |    ./build-docker-image.sh 5.9.0 community debian
172 |    ```
173 | 
174 | 2. **Run Neo4j container**:
175 |    ```bash
176 |     docker run -d --name neo4j-container -p 7474:7474 -p 7687:7687 -v neo4j-data:/data -v neo4j-logs:/logs -e NEO4J_AUTH=neo4j/password neo4jtest:11027
177 |    ```
178 | 
179 | 3. **Connection details**:
180 |    - **Web UI**: http://localhost:7474 (neo4j/your_password)
181 |    - **Bolt URI**: `bolt://localhost:7687` (for local) or `bolt://host.docker.internal:7687` (for MCP in Docker)
182 | 
183 | 4. **Update your .env file**:
184 |    ```bash
185 |    NEO4J_URI=bolt://localhost:7687
186 |    NEO4J_USER=neo4j
187 |    NEO4J_PASSWORD=password
188 |    USE_KNOWLEDGE_GRAPH=true
189 |    ```
190 | 
191 | That's it! Neo4j is now running and ready for knowledge graph functionality.
192 | 
193 | 📖 **For detailed instructions, troubleshooting, and advanced configurations**, see the [Neo4j Docker Setup Guide](neo4j/docker-neo4j/README.md).
194 | 
195 | ### Manual Neo4j Installation
196 | 
197 | Alternatively, install Neo4j directly:
198 | 
199 | 1. **Install Neo4j Desktop**: Download from [neo4j.com/download](https://neo4j.com/download/)
200 | 
201 | 2. **Create a new database**:
202 |    - Open Neo4j Desktop
203 |    - Create a new project and database
204 |    - Set a password for the `neo4j` user
205 |    - Start the database
206 | 
207 | 3. **Note your connection details**:
208 |    - URI: `bolt://localhost:7687` (default)
209 |    - Username: `neo4j` (default)
210 |    - Password: Whatever you set during creation
211 | 
212 | ## Configuration
213 | 
214 | Create a `.env` file in the project root with the following variables:
215 | 
216 | ```
217 | # MCP Server Configuration
218 | HOST=0.0.0.0
219 | PORT=8051
220 | TRANSPORT=sse
221 | 
222 | # OpenAI API Configuration (for embeddings)
223 | OPENAI_API_KEY=your_openai_api_key
224 | 
225 | # OpenRouter API Configuration (for LLM chat completions)
226 | OPENROUTER_API_KEY=your_openrouter_api_key
227 | 
228 | # LLM for summaries and contextual embeddings (OpenRouter format)
229 | # Use OpenRouter model format like: openai/gpt-4.1-nano, anthropic/claude-3-haiku, etc.
230 | MODEL_CHOICE=openai/gpt-4.1-nano
231 | 
232 | # RAG Strategies (set to "true" or "false", default to "false")
233 | USE_CONTEXTUAL_EMBEDDINGS=false
234 | USE_HYBRID_SEARCH=false
235 | USE_AGENTIC_RAG=false
236 | USE_RERANKING=false
237 | USE_KNOWLEDGE_GRAPH=false
238 | 
239 | # Supabase Configuration
240 | SUPABASE_URL=your_supabase_project_url
241 | SUPABASE_SERVICE_KEY=your_supabase_service_key
242 | 
243 | # Neo4j Configuration (required for knowledge graph functionality)
244 | # Use bolt://localhost:7687 for local Neo4j installation
245 | # Use bolt://host.docker.internal:7687 if MCP server is in Docker
246 | NEO4J_URI=bolt://localhost:7687
247 | NEO4J_USER=neo4j
248 | NEO4J_PASSWORD=password
249 | ```
250 | 
251 | ### OpenRouter Integration
252 | 
253 | This MCP server now uses **OpenRouter** for LLM chat completions while maintaining OpenAI for embeddings. This provides several advantages:
254 | 
255 | - **Model Flexibility**: Access to 200+ models from multiple providers (OpenAI, Anthropic, Google, Meta, etc.)
256 | - **Cost Optimization**: Choose the most cost-effective model for your use case
257 | - **Reliability**: OpenRouter's unified API with automatic failover
258 | - **Performance**: Optimized routing to the fastest available endpoint
259 | 
260 | #### Supported Models
261 | 
262 | Popular model choices for the `MODEL_CHOICE` environment variable:
263 | 
264 | - **OpenAI**: `openai/gpt-4.1-nano`, `openai/gpt-4.1-mini`, `openai/gpt-4o`
265 | - **Anthropic**: `anthropic/claude-3-haiku`, `anthropic/claude-3-sonnet`
266 | - **Google**: `google/gemini-flash-1.5`, `google/gemini-pro-1.5`
267 | - **Meta**: `meta-llama/llama-3.1-8b-instruct`, `meta-llama/llama-3.1-70b-instruct`
268 | - **DeepSeek**: `deepseek/deepseek-chat`, `deepseek/deepseek-coder`
269 | 
270 | For the full list, visit [OpenRouter Models](https://openrouter.ai/models).
271 | 
272 | #### Configuration Notes
273 | 
274 | - **OpenAI API Key**: Still required for embeddings (`text-embedding-3-small`)
275 | - **OpenRouter API Key**: Required for all LLM chat completions
276 | - **Model Format**: Use OpenRouter's model format (`provider/model-name`)
277 | - **Fallback**: If OpenRouter is unavailable, the system will log errors but continue with reduced functionality
278 | 
279 | ### RAG Strategy Options
280 | 
281 | The Crawl4AI RAG MCP server supports four powerful RAG strategies that can be enabled independently:
282 | 
283 | #### 1. **USE_CONTEXTUAL_EMBEDDINGS**
284 | When enabled, this strategy enhances each chunk's embedding with additional context from the entire document. The system passes both the full document and the specific chunk to an LLM (configured via `MODEL_CHOICE`) to generate enriched context that gets embedded alongside the chunk content.
285 | 
286 | - **When to use**: Enable this when you need high-precision retrieval where context matters, such as technical documentation where terms might have different meanings in different sections.
287 | - **Trade-offs**: Slower indexing due to LLM calls for each chunk, but significantly better retrieval accuracy.
288 | - **Cost**: Additional LLM API calls during indexing.
289 | 
290 | #### 2. **USE_HYBRID_SEARCH**
291 | Combines traditional keyword search with semantic vector search to provide more comprehensive results. The system performs both searches in parallel and intelligently merges results, prioritizing documents that appear in both result sets.
292 | 
293 | - **When to use**: Enable this when users might search using specific technical terms, function names, or when exact keyword matches are important alongside semantic understanding.
294 | - **Trade-offs**: Slightly slower search queries but more robust results, especially for technical content.
295 | - **Cost**: No additional API costs, just computational overhead.
296 | 
297 | #### 3. **USE_AGENTIC_RAG**
298 | Enables specialized code example extraction and storage. When crawling documentation, the system identifies code blocks (≥300 characters), extracts them with surrounding context, generates summaries, and stores them in a separate vector database table specifically designed for code search.
299 | 
300 | - **When to use**: Essential for AI coding assistants that need to find specific code examples, implementation patterns, or usage examples from documentation.
301 | - **Trade-offs**: Significantly slower crawling due to code extraction and summarization, requires more storage space.
302 | - **Cost**: Additional LLM API calls for summarizing each code example.
303 | - **Benefits**: Provides a dedicated `search_code_examples` tool that AI agents can use to find specific code implementations.
304 | 
305 | #### 4. **USE_RERANKING**
306 | Applies cross-encoder reranking to search results after initial retrieval. Uses a lightweight cross-encoder model (`cross-encoder/ms-marco-MiniLM-L-6-v2`) to score each result against the original query, then reorders results by relevance.
307 | 
308 | - **When to use**: Enable this when search precision is critical and you need the most relevant results at the top. Particularly useful for complex queries where semantic similarity alone might not capture query intent.
309 | - **Trade-offs**: Adds ~100-200ms to search queries depending on result count, but significantly improves result ordering.
310 | - **Cost**: No additional API costs - uses a local model that runs on CPU.
311 | - **Benefits**: Better result relevance, especially for complex queries. Works with both regular RAG search and code example search.
312 | 
313 | #### 5. **USE_KNOWLEDGE_GRAPH**
314 | Enables AI hallucination detection and repository analysis using Neo4j knowledge graphs. When enabled, the system can parse GitHub repositories into a graph database and validate AI-generated code against real repository structures. **Now fully compatible with Docker** using the included Neo4j Docker setup.
315 | 
316 | - **When to use**: Enable this for AI coding assistants that need to validate generated code against real implementations, or when you want to detect when AI models hallucinate non-existent methods, classes, or incorrect usage patterns.
317 | - **Trade-offs**: Requires Neo4j setup and additional dependencies. Repository parsing can be slow for large codebases, and validation requires repositories to be pre-indexed.
318 | - **Cost**: No additional API costs for validation, but requires Neo4j infrastructure (can use free local installation, included Docker setup, or cloud AuraDB).
319 | - **Benefits**: Provides three powerful tools: `parse_github_repository` for indexing codebases, `check_ai_script_hallucinations` for validating AI-generated code, and `query_knowledge_graph` for exploring indexed repositories.
320 | 
321 | You can now tell the AI coding assistant to add a Python GitHub repository to the knowledge graph like:
322 | 
323 | "Add https://github.com/pydantic/pydantic-ai.git to the knowledge graph"
324 | 
325 | Make sure the repo URL ends with .git.
326 | 
327 | You can also have the AI coding assistant check for hallucinations with scripts it just created, or you can manually run the command:
328 | 
329 | ```
330 | python knowledge_graphs/ai_hallucination_detector.py [full path to your script to analyze]
331 | ```
332 | 
333 | ### Recommended Configurations
334 | 
335 | **For general documentation RAG:**
336 | ```
337 | USE_CONTEXTUAL_EMBEDDINGS=false
338 | USE_HYBRID_SEARCH=true
339 | USE_AGENTIC_RAG=false
340 | USE_RERANKING=true
341 | ```
342 | 
343 | **For AI coding assistant with code examples:**
344 | ```
345 | USE_CONTEXTUAL_EMBEDDINGS=true
346 | USE_HYBRID_SEARCH=true
347 | USE_AGENTIC_RAG=true
348 | USE_RERANKING=true
349 | USE_KNOWLEDGE_GRAPH=false
350 | ```
351 | 
352 | **For AI coding assistant with hallucination detection:**
353 | ```
354 | USE_CONTEXTUAL_EMBEDDINGS=true
355 | USE_HYBRID_SEARCH=true
356 | USE_AGENTIC_RAG=true
357 | USE_RERANKING=true
358 | USE_KNOWLEDGE_GRAPH=true
359 | ```
360 | 
361 | **For fast, basic RAG:**
362 | ```
363 | USE_CONTEXTUAL_EMBEDDINGS=false
364 | USE_HYBRID_SEARCH=true
365 | USE_AGENTIC_RAG=false
366 | USE_RERANKING=false
367 | USE_KNOWLEDGE_GRAPH=false
368 | ```
369 | 
370 | ## Running the Server
371 | 
372 | ### Using Docker
373 | 
374 | ```bash
375 | docker run --env-file .env -p 8051:8051 mcp/crawl4ai-rag
376 | ```
377 | 
378 | ### Using Python
379 | 
380 | ```bash
381 | uv run src/crawl4ai_mcp.py
382 | ```
383 | 
384 | The server will start and listen on the configured host and port.
385 | 
386 | ## Integration with MCP Clients
387 | 
388 | ### SSE Configuration
389 | 
390 | Once you have the server running with SSE transport, you can connect to it using this configuration:
391 | 
392 | ```json
393 | {
394 |   "mcpServers": {
395 |     "crawl4ai-rag": {
396 |       "transport": "sse",
397 |       "url": "http://localhost:8051/sse"
398 |     }
399 |   }
400 | }
401 | ```
402 | 
403 | > **Note for Windsurf users**: Use `serverUrl` instead of `url` in your configuration:
404 | > ```json
405 | > {
406 | >   "mcpServers": {
407 | >     "crawl4ai-rag": {
408 | >       "transport": "sse",
409 | >       "serverUrl": "http://localhost:8051/sse"
410 | >     }
411 | >   }
412 | > }
413 | > ```
414 | >
415 | > **Note for Docker users**: Use `host.docker.internal` instead of `localhost` if your client is running in a different container. This will apply if you are using this MCP server within n8n!
416 | 
417 | > **Note for Claude Code users**: 
418 | ```
419 | claude mcp add-json crawl4ai-rag '{"type":"sse","url":"http://localhost:8051/sse"}' --scope user
420 | ```
421 | 
422 | ### Stdio Configuration
423 | 
424 | Add this server to your MCP configuration for Claude Desktop, Windsurf, or any other MCP client:
425 | 
426 | ```json
427 | {
428 |   "mcpServers": {
429 |     "crawl4ai-rag": {
430 |       "command": "python",
431 |       "args": ["path/to/crawl4ai-mcp/src/crawl4ai_mcp.py"],
432 |       "env": {
433 |         "TRANSPORT": "stdio",
434 |         "OPENAI_API_KEY": "your_openai_api_key",
435 |         "OPENROUTER_API_KEY": "your_openrouter_api_key",
436 |         "SUPABASE_URL": "your_supabase_url",
437 |         "SUPABASE_SERVICE_KEY": "your_supabase_service_key",
438 |         "USE_KNOWLEDGE_GRAPH": "false",
439 |         "NEO4J_URI": "bolt://localhost:7687",
440 |         "NEO4J_USER": "neo4j",
441 |         "NEO4J_PASSWORD": "password"
442 |       }
443 |     }
444 |   }
445 | }
446 | ```
447 | 
448 | ### Docker with Stdio Configuration
449 | 
450 | ```json
451 | {
452 |   "mcpServers": {
453 |     "crawl4ai-rag": {
454 |       "command": "docker",
455 |       "args": ["run", "--rm", "-i", 
456 |                "-e", "TRANSPORT", 
457 |                "-e", "OPENAI_API_KEY", 
458 |                "-e", "OPENROUTER_API_KEY",
459 |                "-e", "SUPABASE_URL", 
460 |                "-e", "SUPABASE_SERVICE_KEY",
461 |                "-e", "USE_KNOWLEDGE_GRAPH",
462 |                "-e", "NEO4J_URI",
463 |                "-e", "NEO4J_USER",
464 |                "-e", "NEO4J_PASSWORD",
465 |                "mcp/crawl4ai"],
466 |       "env": {
467 |         "TRANSPORT": "stdio",
468 |         "OPENAI_API_KEY": "your_openai_api_key",
469 |         "OPENROUTER_API_KEY": "your_openrouter_api_key",
470 |         "SUPABASE_URL": "your_supabase_url",
471 |         "SUPABASE_SERVICE_KEY": "your_supabase_service_key",
472 |         "USE_KNOWLEDGE_GRAPH": "false",
473 |         "NEO4J_URI": "bolt://localhost:7687",
474 |         "NEO4J_USER": "neo4j",
475 |         "NEO4J_PASSWORD": "password"
476 |       }
477 |     }
478 |   }
479 | }
480 | ```
481 | 
482 | > **Note**: For Docker deployments with knowledge graph enabled, use `bolt://host.docker.internal:7687` as the NEO4J_URI to connect to a local Neo4j instance.
483 | 
484 | ## Knowledge Graph Architecture
485 | 
486 | The knowledge graph system stores repository code structure in Neo4j with the following components:
487 | 
488 | ### Core Components (`knowledge_graphs/` folder):
489 | 
490 | - **`parse_repo_into_neo4j.py`**: Clones and analyzes GitHub repositories, extracting Python classes, methods, functions, and imports into Neo4j nodes and relationships
491 | - **`ai_script_analyzer.py`**: Parses Python scripts using AST to extract imports, class instantiations, method calls, and function usage
492 | - **`knowledge_graph_validator.py`**: Validates AI-generated code against the knowledge graph to detect hallucinations (non-existent methods, incorrect parameters, etc.)
493 | - **`hallucination_reporter.py`**: Generates comprehensive reports about detected hallucinations with confidence scores and recommendations
494 | - **`query_knowledge_graph.py`**: Interactive CLI tool for exploring the knowledge graph (functionality now integrated into MCP tools)
495 | 
496 | ### Knowledge Graph Schema:
497 | 
498 | The Neo4j database stores code structure as:
499 | 
500 | **Nodes:**
501 | - `Repository`: GitHub repositories
502 | - `File`: Python files within repositories  
503 | - `Class`: Python classes with methods and attributes
504 | - `Method`: Class methods with parameter information
505 | - `Function`: Standalone functions
506 | - `Attribute`: Class attributes
507 | 
508 | **Relationships:**
509 | - `Repository` -[:CONTAINS]-> `File`
510 | - `File` -[:DEFINES]-> `Class`
511 | - `File` -[:DEFINES]-> `Function`
512 | - `Class` -[:HAS_METHOD]-> `Method`
513 | - `Class` -[:HAS_ATTRIBUTE]-> `Attribute`
514 | 
515 | ### Workflow:
516 | 
517 | 1. **Repository Parsing**: Use `parse_github_repository` tool to clone and analyze open-source repositories
518 | 2. **Code Validation**: Use `check_ai_script_hallucinations` tool to validate AI-generated Python scripts
519 | 3. **Knowledge Exploration**: Use `query_knowledge_graph` tool to explore available repositories, classes, and methods
520 | 
521 | ## Building Your Own Server
522 | 
523 | This implementation provides a foundation for building more complex MCP servers with web crawling capabilities. To build your own:
524 | 
525 | 1. Add your own tools by creating methods with the `@mcp.tool()` decorator
526 | 2. Create your own lifespan function to add your own dependencies
527 | 3. Modify the `utils.py` file for any helper functions you need
528 | 4. Extend the crawling capabilities by adding more specialized crawlers
529 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/ConfsReplaced.conf:
--------------------------------------------------------------------------------

```
1 | #dbms.memory.pagecache.size=1g
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/ReadConf.conf:
--------------------------------------------------------------------------------

```
1 | dbms.memory.heap.max_size=512m
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/ConfsNotOverridden.conf:
--------------------------------------------------------------------------------

```
1 | dbms.memory.pagecache.size=1024M
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/EnvVarsOverride.conf:
--------------------------------------------------------------------------------

```
1 | dbms.memory.pagecache.size=1000m
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/ConfsReplaced.conf:
--------------------------------------------------------------------------------

```
1 | #server.memory.pagecache.size=1g
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/ReadConf.conf:
--------------------------------------------------------------------------------

```
1 | server.memory.heap.max_size=512m
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/ConfsNotOverridden.conf:
--------------------------------------------------------------------------------

```
1 | server.memory.pagecache.size=1024M
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/EnvVarsOverride.conf:
--------------------------------------------------------------------------------

```
1 | server.memory.pagecache.size=1000m
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/ExtendedConf.conf:
--------------------------------------------------------------------------------

```
1 | dbms.logs.gc.rotation.keep_number=$(expr 2 * 10)
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/EnterpriseOnlyNotOverwritten.conf:
--------------------------------------------------------------------------------

```
1 | server.cluster.advertised_address=localhost:6060
2 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/ExtendedConf.conf:
--------------------------------------------------------------------------------

```
1 | server.logs.gc.rotation.keep_number=$(expr 2 * 10)
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/EnterpriseOnlyNotOverwritten.conf:
--------------------------------------------------------------------------------

```
1 | causal_clustering.transaction_advertised_address=localhost:6060
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/JvmAdditionalNotOverridden.conf:
--------------------------------------------------------------------------------

```
1 | dbms.jvm.additional=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/NoNewline.conf:
--------------------------------------------------------------------------------

```
1 | # a configuration file without a trailing newline
2 | dbms.memory.pagecache.size=1000.00MiB
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/JvmAdditionalNotOverridden.conf:
--------------------------------------------------------------------------------

```
1 | server.jvm.additional=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/NoNewline.conf:
--------------------------------------------------------------------------------

```
1 | # a configuration file without a trailing newline
2 | server.memory.pagecache.size=1000.00MiB
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/InvalidExtendedConf.conf:
--------------------------------------------------------------------------------

```
1 | dbms.logs.gc.rotation.keep_number=$(bash -c '>&2 echo "this is an error message from inside neo4j config command expansion" && exit 1')
2 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/InvalidExtendedConf.conf:
--------------------------------------------------------------------------------

```
1 | server.logs.gc.rotation.keep_number=$(bash -c '>&2 echo "this is an error message from inside neo4j config command expansion" && exit 1')
2 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------

```
1 | log4j.rootLogger=INFO, console 
2 | log4j.appender.console=org.apache.log4j.ConsoleAppender
3 | log4j.appender.console.layout=org.apache.log4j.PatternLayout
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/dockersecrets/simple-container-compose.yml:
--------------------------------------------------------------------------------

```yaml
 1 | services:
 2 |   simplecontainer:
 3 |     image: ${NEO4J_IMAGE}
 4 |     environment:
 5 |       - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
 6 |       - NEO4J_AUTH=neo4j/simplecontainerpassword
 7 |       - NEO4J_DEBUG=true
 8 |     volumes:
 9 |       - ${HOST_ROOT}/neo4j/data:/data
10 |       - ${HOST_ROOT}/neo4j/logs:/logs
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/dockersecrets/simple-container-compose-with-external-file-var.yml:
--------------------------------------------------------------------------------

```yaml
 1 | services:
 2 |   simplecontainer:
 3 |     image: ${NEO4J_IMAGE}
 4 |     environment:
 5 |       - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
 6 |       - NEO4J_AUTH=neo4j/simplecontainerpassword
 7 |       - NEO4J_DEBUG=true
 8 |       - CERTIFICATE_FILE="CERTIFICATE CONTENTS"
 9 |     volumes:
10 |       - ${HOST_ROOT}/neo4j/data:/data
11 |       - ${HOST_ROOT}/neo4j/logs:/logs
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/generate-stub-plugin/settings.gradle.kts:
--------------------------------------------------------------------------------

```kotlin
 1 | /*
 2 |  * This file was generated by the Gradle 'init' task.
 3 |  *
 4 |  * The settings file is used to specify which projects to include in your build.
 5 |  *
 6 |  * Detailed information about configuring a multi-project build in Gradle can be found
 7 |  * in the user manual at https://docs.gradle.org/7.6/userguide/multi_project_builds.html
 8 |  */
 9 | 
10 | rootProject.name = "myPlugin"
11 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/dockersecrets/container-compose-with-secrets.yml:
--------------------------------------------------------------------------------

```yaml
 1 | services:
 2 |   secretscontainer:
 3 |     image: ${NEO4J_IMAGE}
 4 |     environment:
 5 |       - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
 6 |       - NEO4J_AUTH_FILE=/run/secrets/neo4j_auth_file
 7 |       - NEO4J_DEBUG=true
 8 |     volumes:
 9 |       - ${HOST_ROOT}/neo4j/data:/data
10 |       - ${HOST_ROOT}/neo4j/logs:/logs
11 |     secrets:
12 |       - neo4j_auth_file
13 | secrets:
14 |   neo4j_auth_file:
15 |     file: ./neo4j_auth.txt
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/dockersecrets/container-compose-with-incorrect-secrets.yml:
--------------------------------------------------------------------------------

```yaml
 1 | services:
 2 |   secretscontainer:
 3 |     image: ${NEO4J_IMAGE}
 4 |     environment:
 5 |       - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
 6 |       - NEO4J_AUTH_FILE="File contents instead of a file path"
 7 |       - NEO4J_DEBUG=true
 8 |     volumes:
 9 |       - ${HOST_ROOT}/neo4j/data:/data
10 |       - ${HOST_ROOT}/neo4j/logs:/logs
11 |     secrets:
12 |       - neo4j_auth_file
13 | secrets:
14 |   neo4j_auth_file:
15 |     file: ./neo4j_auth.txt
```

--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------

```toml
 1 | [project]
 2 | name = "crawl4ai-mcp"
 3 | version = "0.1.0"
 4 | description = "MCP server for integrating web crawling and RAG into AI agents and AI coding assistants"
 5 | readme = "README.md"
 6 | requires-python = ">=3.12"
 7 | dependencies = [
 8 |     "crawl4ai==0.6.2",
 9 |     "mcp==1.7.1",
10 |     "supabase==2.15.1",
11 |     "openai==1.71.0",
12 |     "dotenv==0.9.9",
13 |     "sentence-transformers>=4.1.0",
14 |     "neo4j>=5.28.1",
15 |     "playwright>=1.40.0",
16 | ]
17 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/generate-stub-plugin/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM gradle:7-jdk11
 2 | WORKDIR /testplugin
 3 | COPY ./*.kts ./ExampleNeo4jPlugin.java /testplugin/
 4 | RUN mkdir -p /testplugin/src/main/java/testplugins/ && \
 5 |     mkdir -p /testplugin/build && \
 6 |     ln -s -T /output /testplugin/build/libs && \
 7 |     mv /testplugin/ExampleNeo4jPlugin.java /testplugin/src/main/java/testplugins/ && \
 8 |     chmod a+rw -R /testplugin
 9 | ENV NEO4JVERSION=4.4.38
10 | 
11 | VOLUME /output
12 | CMD gradle jar -Pversion=$NEO4JVERSION
13 | 
```

--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM python:3.12-slim
 2 | 
 3 | ARG PORT=8051
 4 | 
 5 | WORKDIR /app
 6 | 
 7 | # Install system dependencies including git
 8 | RUN apt-get update && apt-get install -y \
 9 |     git \
10 |     && rm -rf /var/lib/apt/lists/*
11 | 
12 | # Install uv
13 | RUN pip install uv
14 | 
15 | # Copy the MCP server files
16 | COPY . .
17 | 
18 | # Install packages directly to the system (no virtual environment)
19 | # Combining commands to reduce Docker layers
20 | RUN uv pip install --system -e . && \
21 |     crawl4ai-setup
22 | 
23 | EXPOSE ${PORT}
24 | 
25 | # Command to run the MCP server
26 | CMD ["python", "src/crawl4ai_mcp.py"]
27 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/utils/Network.java:
--------------------------------------------------------------------------------

```java
 1 | package com.neo4j.docker.utils;
 2 | 
 3 | import java.io.IOException;
 4 | import java.net.ServerSocket;
 5 | 
 6 | import static java.lang.String.format;
 7 | 
 8 | public class Network
 9 | {
10 |     public static int getUniqueHostPort() throws IOException
11 |     {
12 |         try ( ServerSocket socket = new ServerSocket( 0 ) )
13 |         {
14 |             socket.setReuseAddress( true );
15 |             socket.close();
16 |             return socket.getLocalPort();
17 |         }
18 |         catch ( IOException e )
19 |         {
20 |             throw new IOException( format( "Could not get a unique port : ", e.getMessage() ) );
21 |         }
22 |     }
23 | }
24 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/dockersecrets/container-compose-with-secrets-override.yml:
--------------------------------------------------------------------------------

```yaml
 1 | services:
 2 |   secretsoverridecontainer:
 3 |     image: ${NEO4J_IMAGE}
 4 |     environment:
 5 |       - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
 6 |       - NEO4J_dbms_memory_pagecache_size_FILE=/run/secrets/neo4j_dbms_memory_pagecache_size_file
 7 |       - NEO4J_dbms_memory_pagecache_size=10M
 8 |       - NEO4J_DEBUG=true
 9 |       - NEO4J_AUTH=neo4j/secretsoverridecontainerpassword
10 |     volumes:
11 |       - ${HOST_ROOT}/neo4j/data:/data
12 |       - ${HOST_ROOT}/neo4j/logs:/logs
13 |     secrets:
14 |       - neo4j_dbms_memory_pagecache_size_file
15 | secrets:
16 |   neo4j_dbms_memory_pagecache_size_file:
17 |     file: ./neo4j_pagecache.txt
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/generate-stub-plugin/build.gradle.kts:
--------------------------------------------------------------------------------

```kotlin
 1 | /*
 2 |  * This file was generated by the Gradle 'init' task.
 3 |  *
 4 |  * This generated file contains a sample Java library project to get you started.
 5 |  * For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
 6 |  * User Manual available at https://docs.gradle.org/7.6/userguide/building_java_projects.html
 7 |  */
 8 | 
 9 | //version = "4.3.0"
10 | 
11 | plugins {
12 |     // Apply the java-library plugin for API and implementation separation.
13 |     `java-library`
14 | }
15 | 
16 | repositories {
17 |     // Use Maven Central for resolving dependencies.
18 |     mavenCentral()
19 | }
20 | 
21 | dependencies {
22 |     api("org.neo4j:neo4j:$version")
23 | }
24 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/coredb/plugins/Neo4jPluginEnv.java:
--------------------------------------------------------------------------------

```java
 1 | package com.neo4j.docker.coredb.plugins;
 2 | 
 3 | import com.neo4j.docker.utils.Neo4jVersion;
 4 | import com.neo4j.docker.utils.TestSettings;
 5 | 
 6 | public class Neo4jPluginEnv
 7 | {
 8 |     public static final String PLUGIN_ENV_4X = "NEO4JLABS_PLUGINS";
 9 |     public static final String PLUGIN_ENV_5X = "NEO4J_PLUGINS";
10 | 
11 |     public static String get( )
12 |     {
13 |         return get(TestSettings.NEO4J_VERSION);
14 |     }
15 | 
16 |     public static String get( Neo4jVersion version )
17 |     {
18 |         if( version.isAtLeastVersion( Neo4jVersion.NEO4J_VERSION_500 ) )
19 |         {
20 |             return PLUGIN_ENV_5X;
21 |         }
22 |         else return PLUGIN_ENV_4X;
23 |     }
24 | }
25 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/coredb/configurations/Setting.java:
--------------------------------------------------------------------------------

```java
 1 | package com.neo4j.docker.coredb.configurations;
 2 | 
 3 | public enum Setting
 4 | {
 5 |     APOC_EXPORT_FILE_ENABLED,
 6 |     BACKUP_ENABLED,
 7 |     BACKUP_LISTEN_ADDRESS,
 8 |     BROWSER_ALLOW_OUTGOING_CONNECTIONS,
 9 |     CLUSTER_DISCOVERY_ADDRESS,
10 |     CLUSTER_RAFT_ADDRESS,
11 |     CLUSTER_ROUTING_ADDRESS,
12 |     CLUSTER_TRANSACTION_ADDRESS,
13 |     DEFAULT_LISTEN_ADDRESS,
14 |     DIRECTORIES_DATA,
15 |     DIRECTORIES_LOGS,
16 |     DIRECTORIES_METRICS,
17 |     JVM_ADDITIONAL,
18 |     LOGS_GC_ROTATION_KEEPNUMBER,
19 |     MEMORY_HEAP_INITIALSIZE,
20 |     MEMORY_HEAP_MAXSIZE,
21 |     MEMORY_PAGECACHE_SIZE,
22 |     MINIMUM_PASSWORD_LENGTH,
23 |     SECURITY_PROCEDURES_UNRESTRICTED,
24 |     TXLOG_RETENTION_POLICY
25 | }
26 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.0/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM openjdk:8-jre
 2 | 
 3 | ENV NEO4J_SHA256=%%NEO4J_SHA%% \
 4 |     NEO4J_TARBALL=%%NEO4J_TARBALL%%
 5 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
 6 | 
 7 | COPY ./local-package/* /tmp/
 8 | 
 9 | RUN curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
10 |     && echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum --check --quiet - \
11 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
12 |     && mv /var/lib/neo4j-* /var/lib/neo4j \
13 |     && rm ${NEO4J_TARBALL}
14 | 
15 | ENV PATH /var/lib/neo4j/bin:$PATH
16 | 
17 | WORKDIR /var/lib/neo4j
18 | 
19 | RUN mv data /data \
20 |     && ln --symbolic /data
21 | 
22 | VOLUME /data
23 | 
24 | COPY docker-entrypoint.sh /docker-entrypoint.sh
25 | 
26 | EXPOSE 7474 7473 7687
27 | 
28 | ENTRYPOINT ["/docker-entrypoint.sh"]
29 | CMD ["neo4j"]
30 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/2.3/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM openjdk:8-jre
 2 | 
 3 | RUN apt-get update --quiet --quiet \
 4 |     && apt-get install --quiet --quiet --no-install-recommends lsof \
 5 |     && rm -rf /var/lib/apt/lists/*
 6 | 
 7 | ENV NEO4J_SHA256=%%NEO4J_SHA%% \
 8 |     NEO4J_TARBALL=%%NEO4J_TARBALL%%
 9 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
10 | 
11 | COPY ./local-package/* /tmp/
12 | 
13 | RUN curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
14 |     && echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum --check --quiet - \
15 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
16 |     && mv /var/lib/neo4j-* /var/lib/neo4j \
17 |     && rm ${NEO4J_TARBALL}
18 | 
19 | ENV PATH /var/lib/neo4j/bin:$PATH
20 | 
21 | WORKDIR /var/lib/neo4j
22 | 
23 | RUN mv data /data \
24 |     && ln --symbolic /data
25 | 
26 | VOLUME /data
27 | 
28 | COPY docker-entrypoint.sh /docker-entrypoint.sh
29 | 
30 | EXPOSE 7474 7473
31 | 
32 | ENTRYPOINT ["/docker-entrypoint.sh"]
33 | CMD ["neo4j"]
34 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/utils/HostFileHttpHandler.java:
--------------------------------------------------------------------------------

```java
 1 | package com.neo4j.docker.utils;
 2 | 
 3 | import com.sun.net.httpserver.HttpExchange;
 4 | import com.sun.net.httpserver.HttpHandler;
 5 | 
 6 | import java.io.File;
 7 | import java.io.IOException;
 8 | import java.net.HttpURLConnection;
 9 | import java.nio.file.Files;
10 | 
11 | /**
12 |  * HttpHandler that responds to all http requests with the given file from the file system
13 |  */
14 | public class HostFileHttpHandler implements HttpHandler
15 | {
16 |     private final File file;
17 |     private final String contentType;
18 | 
19 |     public HostFileHttpHandler( File fileToDownload, String contentType )
20 |     {
21 |         this.file = fileToDownload;
22 |         this.contentType = contentType;
23 |     }
24 | 
25 |     @Override
26 |     public void handle( HttpExchange exchange ) throws IOException
27 |     {
28 |         exchange.getResponseHeaders().add( "Content-Type", contentType );
29 |         exchange.sendResponseHeaders( HttpURLConnection.HTTP_OK, file.length() );
30 |         Files.copy( this.file.toPath(), exchange.getResponseBody() );
31 |         exchange.close();
32 |     }
33 | }
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------

```markdown
 1 | ---
 2 | name: Bug report
 3 | about: Create a report to help us improve
 4 | title: ''
 5 | labels: ''
 6 | assignees: jennyowen
 7 | 
 8 | ---
 9 | 
10 | ## Guidelines
11 | 
12 | Please note that GitHub issues are only meant for bug reports/feature requests. 
13 | If you have questions on how to use Neo4j, please ask on [Neo4j Community](https://community.neo4j.com/) or [StackOverflow](http://stackoverflow.com/questions/tagged/neo4j) instead of creating an issue here.
14 | 
15 | To help us understand your issue, please specify important details, primarily:
16 | 
17 | - **Steps to reproduce**. *Not including reproduction steps will mean your bug will take considerably longer to investigate and fix. Please don't skip this*.
18 | - Expected behaviour
19 | - Actual behaviour
20 | - Neo4j image tag being used, eg `neo4j:latest`, `neo4j:enterprise-3.5` etc
21 | - The output of the `docker version` command
22 | - Operating system: (for example Windows 95/Ubuntu 16.04)
23 | 
24 | Additionally, include (as appropriate) error messages, log-files, stacktraces, and other debug output.
25 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/utils/SetContainerUser.java:
--------------------------------------------------------------------------------

```java
 1 | package com.neo4j.docker.utils;
 2 | 
 3 | import com.github.dockerjava.api.command.CreateContainerCmd;
 4 | import com.sun.security.auth.module.UnixSystem;
 5 | import org.testcontainers.containers.GenericContainer;
 6 | import java.util.function.Consumer;
 7 | 
 8 | public class SetContainerUser
 9 | {
10 | 
11 |     public static void nonRootUser( GenericContainer container )
12 |     {
13 |         container.withCreateContainerCmdModifier( (Consumer<CreateContainerCmd>) cmd -> cmd.withUser( getNonRootUserString() ) );
14 |     }
15 | 
16 |     public static String getNonRootUserString()
17 |     {
18 |         // check if the non root user environment variable is set, if so use that. Otherwise use current user.
19 |         String user = System.getenv( "NON_ROOT_USER_ID" );
20 |         if(user == null)
21 |         {
22 |             return getCurrentlyRunningUser();
23 |         }
24 |         else
25 |         {
26 |             return user;
27 |         }
28 |     }
29 | 
30 |     private static String getCurrentlyRunningUser()
31 |     {
32 |         UnixSystem fs = new UnixSystem();
33 |         return fs.getUid() + ":" + fs.getGid();
34 |     }
35 | }
36 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/common/utilities.sh:
--------------------------------------------------------------------------------

```bash
 1 | 
 2 | function running_as_root
 3 | {
 4 |     test "$(id -u)" = "0"
 5 | }
 6 | 
 7 | function secure_mode_enabled
 8 | {
 9 |     test "${SECURE_FILE_PERMISSIONS:=no}" = "yes"
10 | }
11 | 
12 | function debugging_enabled
13 | {
14 |     test "${NEO4J_DEBUG+yes}" = "yes"
15 | }
16 | 
17 | function debug_msg
18 | {
19 |     if debugging_enabled; then
20 |         echo "$@"
21 |     fi
22 | }
23 | 
24 | function containsElement
25 | {
26 |   local e match="$1"
27 |   shift
28 |   for e; do [[ "$e" == "$match" ]] && return 0; done
29 |   return 1
30 | }
31 | 
32 | function is_writable
33 | {
34 |     ${exec_cmd} test -w "${1}"
35 | }
36 | 
37 | function print_permissions_advice_and_fail
38 | {
39 |     local _directory=${1}
40 |     local _userid=${2}
41 |     local _groupid=${3}
42 |     echo >&2 "
43 | Folder ${_directory} is not accessible for user: ${_userid} or group ${_groupid}. This is commonly a file permissions issue on the mounted folder.
44 | 
45 | Hints to solve the issue:
46 | 1) Make sure the folder exists before mounting it. Docker will create the folder using root permissions before starting the Neo4j container. The root permissions disallow Neo4j from writing to the mounted folder.
47 | 2) Pass the folder owner's user ID and group ID to docker run, so that docker runs as that user.
48 | If the folder is owned by the current user, this can be done by adding this flag to your docker run command:
49 |   --user=\$(id -u):\$(id -g)
50 |        "
51 |     exit 1
52 | }
53 | 
54 | 
55 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.1/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM adoptopenjdk/openjdk8:alpine-jre
 2 | 
 3 | RUN addgroup -S neo4j && adduser -S -H -h /var/lib/neo4j -G neo4j neo4j
 4 | 
 5 | ENV NEO4J_SHA256=%%NEO4J_SHA%% \
 6 |     NEO4J_TARBALL=%%NEO4J_TARBALL%% \
 7 |     NEO4J_HOME="/var/lib/neo4j"
 8 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
 9 | 
10 | COPY ./local-package/* /tmp/
11 | 
12 | RUN apk add --no-cache --quiet \
13 |     bash \
14 |     curl \
15 |     tini \
16 |     su-exec \
17 |     && curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
18 |     && echo "${NEO4J_SHA256}  ${NEO4J_TARBALL}" | sha256sum -csw - \
19 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
20 |     && mv /var/lib/neo4j-* "${NEO4J_HOME}" \
21 |     && rm ${NEO4J_TARBALL} \
22 |     && mv "${NEO4J_HOME}"/data /data \
23 |     && chown -R neo4j:neo4j /data \
24 |     && chmod -R 777 /data \
25 |     && mv "${NEO4J_HOME}"/logs /logs \
26 |     && chown -R neo4j:neo4j /logs \
27 |     && chmod -R 777 /logs \
28 |     && chown -R neo4j:neo4j "${NEO4J_HOME}" \
29 |     && chmod -R 777 "${NEO4J_HOME}" \
30 |     && ln -s /data "${NEO4J_HOME}"/data \
31 |     && ln -s /logs "${NEO4J_HOME}"/logs \
32 |     && apk del curl
33 | 
34 | ENV PATH "${NEO4J_HOME}"/bin:$PATH
35 | 
36 | WORKDIR "${NEO4J_HOME}"
37 | 
38 | VOLUME /data /logs
39 | 
40 | COPY docker-entrypoint.sh /docker-entrypoint.sh
41 | 
42 | EXPOSE 7474 7473 7687
43 | 
44 | ENTRYPOINT ["/sbin/tini", "-g", "--", "/docker-entrypoint.sh"]
45 | CMD ["neo4j"]
46 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.2/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM adoptopenjdk/openjdk8:alpine-jre
 2 | 
 3 | RUN addgroup -S neo4j && adduser -S -H -h /var/lib/neo4j -G neo4j neo4j
 4 | 
 5 | ENV NEO4J_SHA256=%%NEO4J_SHA%% \
 6 |     NEO4J_TARBALL=%%NEO4J_TARBALL%% \
 7 |     NEO4J_HOME="/var/lib/neo4j"
 8 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
 9 | 
10 | COPY ./local-package/* /tmp/
11 | 
12 | RUN apk add --no-cache --quiet \
13 |     bash \
14 |     curl \
15 |     tini \
16 |     su-exec \
17 |     && curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
18 |     && echo "${NEO4J_SHA256}  ${NEO4J_TARBALL}" | sha256sum -csw - \
19 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
20 |     && mv /var/lib/neo4j-* "${NEO4J_HOME}" \
21 |     && rm ${NEO4J_TARBALL} \
22 |     && mv "${NEO4J_HOME}"/data /data \
23 |     && chown -R neo4j:neo4j /data \
24 |     && chmod -R 777 /data \
25 |     && mv "${NEO4J_HOME}"/logs /logs \
26 |     && chown -R neo4j:neo4j /logs \
27 |     && chmod -R 777 /logs \
28 |     && chown -R neo4j:neo4j "${NEO4J_HOME}" \
29 |     && chmod -R 777 "${NEO4J_HOME}" \
30 |     && ln -s /data "${NEO4J_HOME}"/data \
31 |     && ln -s /logs "${NEO4J_HOME}"/logs \
32 |     && apk del curl
33 | 
34 | ENV PATH "${NEO4J_HOME}"/bin:$PATH
35 | 
36 | WORKDIR "${NEO4J_HOME}"
37 | 
38 | VOLUME /data /logs
39 | 
40 | COPY docker-entrypoint.sh /docker-entrypoint.sh
41 | 
42 | EXPOSE 7474 7473 7687
43 | 
44 | ENTRYPOINT ["/sbin/tini", "-g", "--", "/docker-entrypoint.sh"]
45 | CMD ["neo4j"]
46 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.0/neo4j-admin/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM %%NEO4J_BASE_IMAGE%%
 2 | 
 3 | ENV NEO4J_SHA256=%%NEO4J_SHA%% \
 4 |     NEO4J_TARBALL=%%NEO4J_TARBALL%% \
 5 |     NEO4J_EDITION=%%NEO4J_EDITION%% \
 6 |     NEO4J_HOME="/var/lib/neo4j"
 7 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
 8 | 
 9 | RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
10 | 
11 | COPY ./local-package/* /tmp/
12 | 
13 | RUN apt update \
14 |     && apt install -y curl gosu procps \
15 |     && curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
16 |     && echo "${NEO4J_SHA256}  ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
17 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
18 |     && mv /var/lib/neo4j-* "${NEO4J_HOME}" \
19 |     && rm ${NEO4J_TARBALL} \
20 |     && mv "${NEO4J_HOME}"/data /data \
21 |     && chown -R neo4j:neo4j /data \
22 |     && chmod -R 777 /data \
23 |     && mkdir -p /backups \
24 |     && chown -R neo4j:neo4j /backups \
25 |     && chmod -R 777 /backups \
26 |     && chown -R neo4j:neo4j "${NEO4J_HOME}" \
27 |     && chmod -R 777 "${NEO4J_HOME}" \
28 |     && ln -s /data "${NEO4J_HOME}"/data \
29 |     && rm -rf /tmp/* \
30 |     && rm -rf /var/lib/apt/lists/* \
31 |     && apt-get -y purge --auto-remove curl
32 | 
33 | 
34 | ENV PATH "${NEO4J_HOME}"/bin:$PATH
35 | VOLUME /data /backups
36 | WORKDIR "${NEO4J_HOME}"
37 | 
38 | COPY docker-entrypoint.sh /docker-entrypoint.sh
39 | 
40 | ENTRYPOINT ["/docker-entrypoint.sh"]
41 | 
42 | CMD ["neo4j-admin"]
43 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.1/neo4j-admin/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM %%NEO4J_BASE_IMAGE%%
 2 | 
 3 | ENV NEO4J_SHA256=%%NEO4J_SHA%% \
 4 |     NEO4J_TARBALL=%%NEO4J_TARBALL%% \
 5 |     NEO4J_EDITION=%%NEO4J_EDITION%% \
 6 |     NEO4J_HOME="/var/lib/neo4j"
 7 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
 8 | 
 9 | RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
10 | 
11 | COPY ./local-package/* /startup/
12 | 
13 | RUN apt update \
14 |     && apt install -y curl gosu procps \
15 |     && curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
16 |     && echo "${NEO4J_SHA256}  ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
17 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
18 |     && mv /var/lib/neo4j-* "${NEO4J_HOME}" \
19 |     && rm ${NEO4J_TARBALL} \
20 |     && mv "${NEO4J_HOME}"/data /data \
21 |     && chown -R neo4j:neo4j /data \
22 |     && chmod -R 777 /data \
23 |     && mkdir -p /backups \
24 |     && chown -R neo4j:neo4j /backups \
25 |     && chmod -R 777 /backups \
26 |     && chown -R neo4j:neo4j "${NEO4J_HOME}" \
27 |     && chmod -R 777 "${NEO4J_HOME}" \
28 |     && ln -s /data "${NEO4J_HOME}"/data \
29 |     && rm -rf /tmp/* \
30 |     && rm -rf /var/lib/apt/lists/* \
31 |     && apt-get -y purge --auto-remove curl
32 | 
33 | 
34 | ENV PATH "${NEO4J_HOME}"/bin:$PATH
35 | VOLUME /data /backups
36 | WORKDIR "${NEO4J_HOME}"
37 | 
38 | COPY docker-entrypoint.sh /docker-entrypoint.sh
39 | 
40 | ENTRYPOINT ["/docker-entrypoint.sh"]
41 | 
42 | CMD ["neo4j-admin"]
43 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/calver/coredb/neo4j-plugins.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "apoc-extended": {
 3 |     "versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
 4 |     "properties": {
 5 |       "dbms.security.procedures.unrestricted": "apoc.*"
 6 |     }
 7 |   },
 8 |   "apoc": {
 9 |     "location": "/var/lib/neo4j/labs/apoc-*-core.jar",
10 |     "versions": "https://neo4j.github.io/apoc/versions.json",
11 |     "properties": {
12 |       "dbms.security.procedures.unrestricted": "apoc.*"
13 |     }
14 |   },
15 |   "bloom": {
16 |     "location": "/var/lib/neo4j/products/bloom-plugin-*.jar",
17 |     "versions": "https://bloom-plugins.s3.eu-west-2.amazonaws.com/versions.json",
18 |     "properties": {
19 |       "server.unmanaged_extension_classes": "com.neo4j.bloom.server=/browser/bloom",
20 |       "dbms.security.procedures.unrestricted": "bloom.*",
21 |       "dbms.bloom.license_file": "/licenses/bloom.license"
22 |     }
23 |   },
24 |   "graph-data-science": {
25 |     "versions": "https://graphdatascience.ninja/versions.json",
26 |     "location": "/var/lib/neo4j/products/neo4j-graph-data-science-*.jar",
27 |     "properties": {
28 |       "dbms.security.procedures.unrestricted": "gds.*"
29 |     }
30 |   },
31 |   "genai": {
32 |     "location": "/var/lib/neo4j/products/neo4j-genai-plugin-*.jar",
33 |     "properties": {
34 |       "dbms.security.procedures.unrestricted": "genai.*"
35 |     }
36 |   },
37 |   "_testing": {
38 |     "versions": "http://host.testcontainers.internal:3000/versions.json",
39 |     "properties": {
40 |       "dbms.security.procedures.unrestricted": "com.neo4j.docker.neo4jserver.plugins.*"
41 |     }
42 |   }
43 | }
44 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.5/neo4j-admin/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM debian:bullseye-slim
 2 | ENV JAVA_HOME=/opt/java/openjdk
 3 | COPY --from=eclipse-temurin:8 $JAVA_HOME $JAVA_HOME
 4 | ENV PATH="${JAVA_HOME}/bin:${PATH}" \
 5 |     NEO4J_SHA256=%%NEO4J_SHA%% \
 6 |     NEO4J_TARBALL=%%NEO4J_TARBALL%% \
 7 |     NEO4J_EDITION=%%NEO4J_EDITION%% \
 8 |     NEO4J_HOME="/var/lib/neo4j"
 9 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
10 | 
11 | RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
12 | 
13 | COPY ./local-package/* /startup/
14 | 
15 | RUN apt update \
16 |     && apt install -y curl procps \
17 |     && curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
18 |     && echo "${NEO4J_SHA256}  ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
19 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
20 |     && mv /var/lib/neo4j-* "${NEO4J_HOME}" \
21 |     && rm ${NEO4J_TARBALL} \
22 |     && rm ${NEO4J_HOME}/bin/neo4j \
23 |     && mv "${NEO4J_HOME}"/data /data \
24 |     && chown -R neo4j:neo4j /data \
25 |     && chmod -R 777 /data \
26 |     && mkdir -p /backups \
27 |     && chown -R neo4j:neo4j /backups \
28 |     && chmod -R 777 /backups \
29 |     && chown -R neo4j:neo4j "${NEO4J_HOME}" \
30 |     && chmod -R 777 "${NEO4J_HOME}" \
31 |     && ln -s /data "${NEO4J_HOME}"/data \
32 |     && ln -s /startup/docker-entrypoint.sh /docker-entrypoint.sh \
33 |     && rm -rf /tmp/* \
34 |     && rm -rf /var/lib/apt/lists/* \
35 |     && apt-get -y purge --auto-remove curl
36 | 
37 | 
38 | ENV PATH "${NEO4J_HOME}"/bin:$PATH
39 | VOLUME /data /backups
40 | WORKDIR "${NEO4J_HOME}"
41 | 
42 | ENTRYPOINT ["/startup/docker-entrypoint.sh"]
43 | 
44 | CMD ["neo4j-admin"]
45 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.2/neo4j-admin/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM debian:bullseye-slim
 2 | ENV JAVA_HOME=/opt/java/openjdk
 3 | COPY --from=eclipse-temurin:11 $JAVA_HOME $JAVA_HOME
 4 | ENV PATH="${JAVA_HOME}/bin:${PATH}" \
 5 |     NEO4J_SHA256=%%NEO4J_SHA%% \
 6 |     NEO4J_TARBALL=%%NEO4J_TARBALL%% \
 7 |     NEO4J_EDITION=%%NEO4J_EDITION%% \
 8 |     NEO4J_HOME="/var/lib/neo4j"
 9 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
10 | 
11 | RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
12 | 
13 | COPY ./local-package/* /startup/
14 | 
15 | RUN apt update \
16 |     && apt install -y curl procps \
17 |     && curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
18 |     && echo "${NEO4J_SHA256}  ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
19 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
20 |     && mv /var/lib/neo4j-* "${NEO4J_HOME}" \
21 |     && rm ${NEO4J_TARBALL} \
22 |     && rm ${NEO4J_HOME}/bin/neo4j \
23 |     && mv "${NEO4J_HOME}"/data /data \
24 |     && chown -R neo4j:neo4j /data \
25 |     && chmod -R 777 /data \
26 |     && mkdir -p /backups \
27 |     && chown -R neo4j:neo4j /backups \
28 |     && chmod -R 777 /backups \
29 |     && chown -R neo4j:neo4j "${NEO4J_HOME}" \
30 |     && chmod -R 777 "${NEO4J_HOME}" \
31 |     && ln -s /data "${NEO4J_HOME}"/data \
32 |     && ln -s /startup/docker-entrypoint.sh /docker-entrypoint.sh \
33 |     && rm -rf /tmp/* \
34 |     && rm -rf /var/lib/apt/lists/* \
35 |     && apt-get -y purge --auto-remove curl
36 | 
37 | 
38 | ENV PATH "${NEO4J_HOME}"/bin:$PATH
39 | VOLUME /data /backups
40 | WORKDIR "${NEO4J_HOME}"
41 | 
42 | ENTRYPOINT ["/startup/docker-entrypoint.sh"]
43 | 
44 | CMD ["neo4j-admin"]
45 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.3/neo4j-admin/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM debian:bullseye-slim
 2 | ENV JAVA_HOME=/opt/java/openjdk
 3 | COPY --from=eclipse-temurin:11 $JAVA_HOME $JAVA_HOME
 4 | ENV PATH="${JAVA_HOME}/bin:${PATH}" \
 5 |     NEO4J_SHA256=%%NEO4J_SHA%% \
 6 |     NEO4J_TARBALL=%%NEO4J_TARBALL%% \
 7 |     NEO4J_EDITION=%%NEO4J_EDITION%% \
 8 |     NEO4J_HOME="/var/lib/neo4j"
 9 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
10 | 
11 | RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
12 | 
13 | COPY ./local-package/* /startup/
14 | 
15 | RUN apt update \
16 |     && apt install -y curl procps \
17 |     && curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
18 |     && echo "${NEO4J_SHA256}  ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
19 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
20 |     && mv /var/lib/neo4j-* "${NEO4J_HOME}" \
21 |     && rm ${NEO4J_TARBALL} \
22 |     && rm ${NEO4J_HOME}/bin/neo4j \
23 |     && mv "${NEO4J_HOME}"/data /data \
24 |     && chown -R neo4j:neo4j /data \
25 |     && chmod -R 777 /data \
26 |     && mkdir -p /backups \
27 |     && chown -R neo4j:neo4j /backups \
28 |     && chmod -R 777 /backups \
29 |     && chown -R neo4j:neo4j "${NEO4J_HOME}" \
30 |     && chmod -R 777 "${NEO4J_HOME}" \
31 |     && ln -s /data "${NEO4J_HOME}"/data \
32 |     && ln -s /startup/docker-entrypoint.sh /docker-entrypoint.sh \
33 |     && rm -rf /tmp/* \
34 |     && rm -rf /var/lib/apt/lists/* \
35 |     && apt-get -y purge --auto-remove curl
36 | 
37 | 
38 | ENV PATH "${NEO4J_HOME}"/bin:$PATH
39 | VOLUME /data /backups
40 | WORKDIR "${NEO4J_HOME}"
41 | 
42 | ENTRYPOINT ["/startup/docker-entrypoint.sh"]
43 | 
44 | CMD ["neo4j-admin"]
45 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.5/coredb/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM debian:bullseye-slim
 2 | ENV JAVA_HOME=/opt/java/openjdk
 3 | COPY --from=eclipse-temurin:8 $JAVA_HOME $JAVA_HOME
 4 | ENV PATH="${JAVA_HOME}/bin:${PATH}" \
 5 |     NEO4J_SHA256=%%NEO4J_SHA%% \
 6 |     NEO4J_TARBALL=%%NEO4J_TARBALL%% \
 7 |     NEO4J_EDITION=%%NEO4J_EDITION%% \
 8 |     NEO4J_HOME="/var/lib/neo4j"
 9 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
10 | 
11 | RUN addgroup --system neo4j && adduser --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
12 | 
13 | COPY ./local-package/* /startup/
14 | 
15 | RUN apt update \
16 |     && apt install -y curl gosu jq tini wget \
17 |     && curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
18 |     && echo "${NEO4J_SHA256}  ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
19 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
20 |     && mv /var/lib/neo4j-* "${NEO4J_HOME}" \
21 |     && rm ${NEO4J_TARBALL} \
22 |     && mv "${NEO4J_HOME}"/data /data \
23 |     && mv "${NEO4J_HOME}"/logs /logs \
24 |     && chown -R neo4j:neo4j /data \
25 |     && chmod -R 777 /data \
26 |     && chown -R neo4j:neo4j /logs \
27 |     && chmod -R 777 /logs \
28 |     && chown -R neo4j:neo4j "${NEO4J_HOME}" \
29 |     && chmod -R 777 "${NEO4J_HOME}" \
30 |     && ln -s /data "${NEO4J_HOME}"/data \
31 |     && ln -s /logs "${NEO4J_HOME}"/logs \
32 |     && ln -s /startup/docker-entrypoint.sh /docker-entrypoint.sh \
33 |     && apt-get -y purge --auto-remove curl \
34 |     && rm -rf /var/lib/apt/lists/*
35 | 
36 | 
37 | ENV PATH "${NEO4J_HOME}"/bin:$PATH
38 | 
39 | WORKDIR "${NEO4J_HOME}"
40 | 
41 | VOLUME /data /logs
42 | 
43 | EXPOSE 7474 7473 7687
44 | 
45 | ENTRYPOINT ["tini", "-g", "--", "/startup/docker-entrypoint.sh"]
46 | CMD ["neo4j"]
47 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.1/coredb/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM debian:bullseye-slim
 2 | ENV JAVA_HOME=/opt/java/openjdk
 3 | COPY --from=eclipse-temurin:11 $JAVA_HOME $JAVA_HOME
 4 | ENV PATH="${JAVA_HOME}/bin:${PATH}" \
 5 |     NEO4J_SHA256=%%NEO4J_SHA%% \
 6 |     NEO4J_TARBALL=%%NEO4J_TARBALL%% \
 7 |     NEO4J_EDITION=%%NEO4J_EDITION%% \
 8 |     NEO4J_HOME="/var/lib/neo4j"
 9 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
10 | 
11 | RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
12 | 
13 | COPY ./local-package/* /startup/
14 | 
15 | RUN apt update \
16 |     && apt install -y curl wget gosu jq tini \
17 |     && curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
18 |     && echo "${NEO4J_SHA256}  ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
19 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
20 |     && mv /var/lib/neo4j-* "${NEO4J_HOME}" \
21 |     && rm ${NEO4J_TARBALL} \
22 |     && mv "${NEO4J_HOME}"/data /data \
23 |     && mv "${NEO4J_HOME}"/logs /logs \
24 |     && chown -R neo4j:neo4j /data \
25 |     && chmod -R 777 /data \
26 |     && chown -R neo4j:neo4j /logs \
27 |     && chmod -R 777 /logs \
28 |     && chown -R neo4j:neo4j "${NEO4J_HOME}" \
29 |     && chmod -R 777 "${NEO4J_HOME}" \
30 |     && ln -s /data "${NEO4J_HOME}"/data \
31 |     && ln -s /logs "${NEO4J_HOME}"/logs \
32 |     && ln -s /startup/docker-entrypoint.sh /docker-entrypoint.sh \
33 |     && apt-get -y purge --auto-remove curl \
34 |     && rm -rf /var/lib/apt/lists/*
35 | 
36 | 
37 | ENV PATH "${NEO4J_HOME}"/bin:$PATH
38 | 
39 | WORKDIR "${NEO4J_HOME}"
40 | 
41 | VOLUME /data /logs
42 | 
43 | EXPOSE 7474 7473 7687
44 | 
45 | ENTRYPOINT ["tini", "-g", "--", "/startup/docker-entrypoint.sh"]
46 | CMD ["neo4j"]
47 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.2/coredb/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM debian:bullseye-slim
 2 | ENV JAVA_HOME=/opt/java/openjdk
 3 | COPY --from=eclipse-temurin:11 $JAVA_HOME $JAVA_HOME
 4 | ENV PATH="${JAVA_HOME}/bin:${PATH}" \
 5 |     NEO4J_SHA256=%%NEO4J_SHA%% \
 6 |     NEO4J_TARBALL=%%NEO4J_TARBALL%% \
 7 |     NEO4J_EDITION=%%NEO4J_EDITION%% \
 8 |     NEO4J_HOME="/var/lib/neo4j"
 9 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
10 | 
11 | RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
12 | 
13 | COPY ./local-package/* /startup/
14 | 
15 | RUN apt update \
16 |     && apt install -y curl wget gosu jq tini \
17 |     && curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
18 |     && echo "${NEO4J_SHA256}  ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
19 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
20 |     && mv /var/lib/neo4j-* "${NEO4J_HOME}" \
21 |     && rm ${NEO4J_TARBALL} \
22 |     && mv "${NEO4J_HOME}"/data /data \
23 |     && mv "${NEO4J_HOME}"/logs /logs \
24 |     && chown -R neo4j:neo4j /data \
25 |     && chmod -R 777 /data \
26 |     && chown -R neo4j:neo4j /logs \
27 |     && chmod -R 777 /logs \
28 |     && chown -R neo4j:neo4j "${NEO4J_HOME}" \
29 |     && chmod -R 777 "${NEO4J_HOME}" \
30 |     && ln -s /data "${NEO4J_HOME}"/data \
31 |     && ln -s /logs "${NEO4J_HOME}"/logs \
32 |     && ln -s /startup/docker-entrypoint.sh /docker-entrypoint.sh \
33 |     && apt-get -y purge --auto-remove curl \
34 |     && rm -rf /var/lib/apt/lists/*
35 | 
36 | 
37 | ENV PATH "${NEO4J_HOME}"/bin:$PATH
38 | 
39 | WORKDIR "${NEO4J_HOME}"
40 | 
41 | VOLUME /data /logs
42 | 
43 | EXPOSE 7474 7473 7687
44 | 
45 | ENTRYPOINT ["tini", "-g", "--", "/startup/docker-entrypoint.sh"]
46 | CMD ["neo4j"]
47 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.3/coredb/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM debian:bullseye-slim
 2 | ENV JAVA_HOME=/opt/java/openjdk
 3 | COPY --from=eclipse-temurin:11 $JAVA_HOME $JAVA_HOME
 4 | ENV PATH="${JAVA_HOME}/bin:${PATH}" \
 5 |     NEO4J_SHA256=%%NEO4J_SHA%% \
 6 |     NEO4J_TARBALL=%%NEO4J_TARBALL%% \
 7 |     NEO4J_EDITION=%%NEO4J_EDITION%% \
 8 |     NEO4J_HOME="/var/lib/neo4j"
 9 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
10 | 
11 | RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
12 | 
13 | COPY ./local-package/* /startup/
14 | 
15 | RUN apt update \
16 |     && apt install -y curl gosu jq procps tini wget \
17 |     && curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
18 |     && echo "${NEO4J_SHA256}  ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
19 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
20 |     && mv /var/lib/neo4j-* "${NEO4J_HOME}" \
21 |     && rm ${NEO4J_TARBALL} \
22 |     && mv "${NEO4J_HOME}"/data /data \
23 |     && mv "${NEO4J_HOME}"/logs /logs \
24 |     && chown -R neo4j:neo4j /data \
25 |     && chmod -R 777 /data \
26 |     && chown -R neo4j:neo4j /logs \
27 |     && chmod -R 777 /logs \
28 |     && chown -R neo4j:neo4j "${NEO4J_HOME}" \
29 |     && chmod -R 777 "${NEO4J_HOME}" \
30 |     && ln -s /data "${NEO4J_HOME}"/data \
31 |     && ln -s /logs "${NEO4J_HOME}"/logs \
32 |     && ln -s /startup/docker-entrypoint.sh /docker-entrypoint.sh \
33 |     && apt-get -y purge --auto-remove curl \
34 |     && rm -rf /var/lib/apt/lists/*
35 | 
36 | 
37 | ENV PATH "${NEO4J_HOME}"/bin:$PATH
38 | 
39 | WORKDIR "${NEO4J_HOME}"
40 | 
41 | VOLUME /data /logs
42 | 
43 | EXPOSE 7474 7473 7687
44 | 
45 | ENTRYPOINT ["tini", "-g", "--", "/startup/docker-entrypoint.sh"]
46 | CMD ["neo4j"]
47 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/5/coredb/neo4j-plugins.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "apoc-extended": {
 3 |     "versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
 4 |     "properties": {
 5 |       "dbms.security.procedures.unrestricted": "apoc.*"
 6 |     }
 7 |   },
 8 |   "apoc": {
 9 |     "location": "/var/lib/neo4j/labs/apoc-*-core.jar",
10 |     "versions": "https://neo4j.github.io/apoc/versions.json",
11 |     "properties": {
12 |       "dbms.security.procedures.unrestricted": "apoc.*"
13 |     }
14 |   },
15 |   "bloom": {
16 |     "location": "/var/lib/neo4j/products/bloom-plugin-*.jar",
17 |     "versions": "https://bloom-plugins.s3.eu-west-2.amazonaws.com/versions.json",
18 |     "properties": {
19 |       "server.unmanaged_extension_classes": "com.neo4j.bloom.server=/browser/bloom",
20 |       "dbms.security.procedures.unrestricted": "bloom.*",
21 |       "dbms.bloom.license_file": "/licenses/bloom.license"
22 |     }
23 |   },
24 |   "graph-data-science": {
25 |     "versions": "https://graphdatascience.ninja/versions.json",
26 |     "location": "/var/lib/neo4j/products/neo4j-graph-data-science-*.jar",
27 |     "properties": {
28 |       "dbms.security.procedures.unrestricted": "gds.*"
29 |     }
30 |   },
31 |   "n10s": {
32 |     "versions": "https://neo4j-labs.github.io/neosemantics/versions.json",
33 |     "properties": {
34 |       "dbms.security.procedures.unrestricted":"semantics.*"
35 |     }
36 |   },
37 |   "genai": {
38 |     "location": "/var/lib/neo4j/products/neo4j-genai-plugin-*.jar",
39 |     "properties": {
40 |       "dbms.security.procedures.unrestricted": "genai.*"
41 |     }
42 |   },
43 |   "_testing": {
44 |     "versions": "http://host.testcontainers.internal:3000/versions.json",
45 |     "properties": {
46 |       "dbms.security.procedures.unrestricted": "com.neo4j.docker.neo4jserver.plugins.*"
47 |     }
48 |   }
49 | }
50 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.0/coredb/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM debian:bullseye-slim
 2 | ENV JAVA_HOME=/opt/java/openjdk
 3 | COPY --from=eclipse-temurin:11 $JAVA_HOME $JAVA_HOME
 4 | ENV PATH="${JAVA_HOME}/bin:${PATH}" \
 5 |     NEO4J_SHA256=%%NEO4J_SHA%% \
 6 |     NEO4J_TARBALL=%%NEO4J_TARBALL%% \
 7 |     NEO4J_EDITION=%%NEO4J_EDITION%% \
 8 |     NEO4J_HOME="/var/lib/neo4j"
 9 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
10 | 
11 | RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
12 | 
13 | COPY ./local-package/* /tmp/
14 | 
15 | RUN apt update \
16 |     && apt install -y curl wget gosu jq tini \
17 |     && curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
18 |     && echo "${NEO4J_SHA256}  ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
19 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
20 |     && mv /var/lib/neo4j-* "${NEO4J_HOME}" \
21 |     && rm ${NEO4J_TARBALL} \
22 |     && mv "${NEO4J_HOME}"/data /data \
23 |     && mv "${NEO4J_HOME}"/logs /logs \
24 |     && chown -R neo4j:neo4j /data \
25 |     && chmod -R 777 /data \
26 |     && chown -R neo4j:neo4j /logs \
27 |     && chmod -R 777 /logs \
28 |     && chown -R neo4j:neo4j "${NEO4J_HOME}" \
29 |     && chmod -R 777 "${NEO4J_HOME}" \
30 |     && ln -s /data "${NEO4J_HOME}"/data \
31 |     && ln -s /logs "${NEO4J_HOME}"/logs \
32 |     && mv /tmp/neo4j-plugins.json /neo4j-plugins.json \
33 |     && rm -rf /tmp/* \
34 |     && rm -rf /var/lib/apt/lists/* \
35 |     && apt-get -y purge --auto-remove curl
36 | 
37 | ENV PATH "${NEO4J_HOME}"/bin:$PATH
38 | 
39 | WORKDIR "${NEO4J_HOME}"
40 | 
41 | VOLUME /data /logs
42 | 
43 | COPY docker-entrypoint.sh /docker-entrypoint.sh
44 | 
45 | EXPOSE 7474 7473 7687
46 | 
47 | ENTRYPOINT ["tini", "-g", "--", "/docker-entrypoint.sh"]
48 | CMD ["neo4j"]
49 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.4/coredb/neo4j-admin-report.sh:
--------------------------------------------------------------------------------

```bash
 1 | #!/bin/bash
 2 | 
 3 | # load useful utility functions
 4 | . /startup/utilities.sh
 5 | 
 6 | function find_report_destination
 7 | {
 8 |     local to_flag="--to"
 9 | 
10 |     while [[ $# -gt 0 ]]; do
11 |         case $1 in
12 |     # for arg in "$@"; do
13 |     #     case $arg in
14 |             "${to_flag}"=*)
15 |                 echo ${1#*=}
16 |                 return
17 |                 ;;
18 |             "${to_flag}")
19 |                 echo ${2}
20 |                 return
21 |                 ;;
22 |             *)
23 |                 shift
24 |                 ;;
25 |         esac
26 |     done
27 |     mkdir -p /tmp/reports
28 |     echo "/tmp/reports"
29 | }
30 | 
31 | report_cmd=("neo4j-admin" "report")
32 | 
33 | # note, these debug messages are unlikely to work in a docker exec, since environment isn't preserved.
34 | debug_msg "Called ${0}"
35 | debug_msg "neo4j-admin report command is:" "${report_cmd[@]}" "$@"
36 | 
37 | # find report destination. This could be specified by argument to neo4j-admin or it could be the default location.
38 | report_destination=$(find_report_destination "$@")
39 | debug_msg "report_destination will be ${report_destination}"
40 | 
41 | debug_msg "Determining which user to run neo4j-admin as."
42 | if running_as_root; then
43 |     debug_msg "running neo4j-admin report as root"
44 |     if [[ ! $(su-exec neo4j:neo4j test -w "${report_destination}") ]]; then
45 |         debug_msg "reowning ${report_destination} to neo4j:neo4j"
46 |         chown neo4j:neo4j "${report_destination}"
47 |     fi
48 |     debug_msg su-exec neo4j:neo4j "${report_cmd[@]}" "$@"
49 |     su-exec neo4j:neo4j "${report_cmd[@]}" "$@"
50 | else
51 |     debug_msg "running neo4j-admin report as user defined by --user flag"
52 |     if [[ ! -w "${report_destination}" ]]; then
53 |         print_permissions_advice_and_fail "${report_destination}" "$(id -u)" "$(id -g)"
54 |     fi
55 |     debug_msg "${report_cmd[@]}" "$@"
56 |     "${report_cmd[@]}" "$@"
57 | fi
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/5/coredb/neo4j-admin-report.sh:
--------------------------------------------------------------------------------

```bash
 1 | #!/bin/bash
 2 | 
 3 | # load useful utility functions
 4 | . /startup/utilities.sh
 5 | 
 6 | function find_report_destination
 7 | {
 8 |     local to_flag="--to-path"
 9 | 
10 |     while [[ $# -gt 0 ]]; do
11 |         case $1 in
12 |     # for arg in "$@"; do
13 |     #     case $arg in
14 |             "${to_flag}"=*)
15 |                 echo ${1#*=}
16 |                 return
17 |                 ;;
18 |             "${to_flag}")
19 |                 echo ${2}
20 |                 return
21 |                 ;;
22 |             *)
23 |                 shift
24 |                 ;;
25 |         esac
26 |     done
27 |     mkdir -p /tmp/reports
28 |     echo "/tmp/reports"
29 | }
30 | 
31 | report_cmd=("neo4j-admin" "server" "report")
32 | 
33 | # note, these debug messages are unlikely to work in a docker exec, since environment isn't preserved.
34 | debug_msg "Called ${0}"
35 | debug_msg "neo4j-admin report command is:" "${report_cmd[@]}" "$@"
36 | 
37 | # find report destination. This could be specified by argument to neo4j-admin or it could be the default location.
38 | report_destination=$(find_report_destination "$@")
39 | debug_msg "report_destination will be ${report_destination}"
40 | 
41 | debug_msg "Determining which user to run neo4j-admin as."
42 | if running_as_root; then
43 |     debug_msg "running neo4j-admin report as root"
44 |     if [[ ! $(su-exec neo4j:neo4j test -w "${report_destination}") ]]; then
45 |         debug_msg "reowning ${report_destination} to neo4j:neo4j"
46 |         chown neo4j:neo4j "${report_destination}"
47 |     fi
48 |     debug_msg su-exec neo4j:neo4j "${report_cmd[@]}" "$@"
49 |     su-exec neo4j:neo4j "${report_cmd[@]}" "$@"
50 | else
51 |     debug_msg "running neo4j-admin report as user defined by --user flag"
52 |     if [[ ! -w "${report_destination}" ]]; then
53 |         print_permissions_advice_and_fail "${report_destination}" "$(id -u)" "$(id -g)"
54 |     fi
55 |     debug_msg "${report_cmd[@]}" "$@"
56 |     "${report_cmd[@]}" "$@"
57 | fi
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/calver/coredb/neo4j-admin-report.sh:
--------------------------------------------------------------------------------

```bash
 1 | #!/bin/bash
 2 | 
 3 | # load useful utility functions
 4 | . /startup/utilities.sh
 5 | 
 6 | function find_report_destination
 7 | {
 8 |     local to_flag="--to-path"
 9 | 
10 |     while [[ $# -gt 0 ]]; do
11 |         case $1 in
12 |     # for arg in "$@"; do
13 |     #     case $arg in
14 |             "${to_flag}"=*)
15 |                 echo ${1#*=}
16 |                 return
17 |                 ;;
18 |             "${to_flag}")
19 |                 echo ${2}
20 |                 return
21 |                 ;;
22 |             *)
23 |                 shift
24 |                 ;;
25 |         esac
26 |     done
27 |     mkdir -p /tmp/reports
28 |     echo "/tmp/reports"
29 | }
30 | 
31 | report_cmd=("neo4j-admin" "server" "report")
32 | 
33 | # note, these debug messages are unlikely to work in a docker exec, since environment isn't preserved.
34 | debug_msg "Called ${0}"
35 | debug_msg "neo4j-admin report command is:" "${report_cmd[@]}" "$@"
36 | 
37 | # find report destination. This could be specified by argument to neo4j-admin or it could be the default location.
38 | report_destination=$(find_report_destination "$@")
39 | debug_msg "report_destination will be ${report_destination}"
40 | 
41 | debug_msg "Determining which user to run neo4j-admin as."
42 | if running_as_root; then
43 |     debug_msg "running neo4j-admin report as root"
44 |     if [[ ! $(su-exec neo4j:neo4j test -w "${report_destination}") ]]; then
45 |         debug_msg "reowning ${report_destination} to neo4j:neo4j"
46 |         chown neo4j:neo4j "${report_destination}"
47 |     fi
48 |     debug_msg su-exec neo4j:neo4j "${report_cmd[@]}" "$@"
49 |     su-exec neo4j:neo4j "${report_cmd[@]}" "$@"
50 | else
51 |     debug_msg "running neo4j-admin report as user defined by --user flag"
52 |     if [[ ! -w "${report_destination}" ]]; then
53 |         print_permissions_advice_and_fail "${report_destination}" "$(id -u)" "$(id -g)"
54 |     fi
55 |     debug_msg "${report_cmd[@]}" "$@"
56 |     "${report_cmd[@]}" "$@"
57 | fi
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/utils/HttpServerTestExtension.java:
--------------------------------------------------------------------------------

```java
 1 | package com.neo4j.docker.utils;
 2 | 
 3 | import com.sun.net.httpserver.HttpHandler;
 4 | import com.sun.net.httpserver.HttpServer;
 5 | import org.junit.jupiter.api.extension.AfterEachCallback;
 6 | import org.junit.jupiter.api.extension.BeforeEachCallback;
 7 | import org.junit.jupiter.api.extension.ExtensionContext;
 8 | 
 9 | import java.net.InetSocketAddress;
10 | 
11 | /**
12 |  * Runs a HTTP Server with to allow integration testing
13 |  */
14 | public class HttpServerTestExtension implements AfterEachCallback, BeforeEachCallback
15 | {
16 |     public final int PORT = 3000;
17 |     private HttpServer server;
18 | 
19 |     @Override
20 |     public void beforeEach(ExtensionContext extensionContext) throws Exception
21 |     {
22 |         server = HttpServer.create( new InetSocketAddress( PORT ), 0 );
23 |         server.setExecutor( null ); // creates a default executor
24 |         server.start();
25 |     }
26 | 
27 |     @Override
28 |     public void afterEach(ExtensionContext extensionContext) throws Exception
29 |     {
30 |         if ( server != null )
31 |         {
32 |             server.stop( 5 ); // waits up to 5 seconds to stop serving http requests
33 |         }
34 |     }
35 | 
36 |     // Register a handler to provide desired behaviour on a specific uri path
37 |     public void registerHandler( String uriToHandle, HttpHandler httpHandler )
38 |     {
39 |         if (!uriToHandle.startsWith( "/" )){
40 |             uriToHandle = '/' + uriToHandle;
41 |         }
42 |         server.createContext( uriToHandle, httpHandler );
43 |     }
44 | 
45 |     public void unregisterEndpoint(String endpoint)
46 |     {
47 |         if (!endpoint.startsWith( "/" )){
48 |             endpoint = '/' + endpoint;
49 |         }
50 |         try
51 |         {
52 |             server.removeContext(endpoint);
53 |         }
54 |         catch (IllegalArgumentException iex)
55 |         {
56 |             // there was nothing registered to that endpoint so action is a NOP.
57 |         }
58 |     }
59 | }
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.3/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM openjdk:8-jre-slim
 2 | 
 3 | ENV NEO4J_SHA256=%%NEO4J_SHA%% \
 4 |     NEO4J_TARBALL=%%NEO4J_TARBALL%% \
 5 |     NEO4J_EDITION=%%NEO4J_EDITION%% \
 6 |     NEO4J_HOME="/var/lib/neo4j" \
 7 |     TINI_VERSION="v0.18.0" \
 8 |     TINI_SHA256="12d20136605531b09a2c2dac02ccee85e1b874eb322ef6baf7561cd93f93c855"
 9 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
10 | 
11 | RUN addgroup --system neo4j && adduser --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
12 | 
13 | COPY ./local-package/* /tmp/
14 | 
15 | RUN apt update \
16 |     && apt install -y curl gosu jq \
17 |     && curl -L --fail --silent --show-error "https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini" > /sbin/tini \
18 |     && echo "${TINI_SHA256}  /sbin/tini" | sha256sum -c --strict --quiet \
19 |     && chmod +x /sbin/tini \
20 |     && curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
21 |     && echo "${NEO4J_SHA256}  ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
22 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
23 |     && mv /var/lib/neo4j-* "${NEO4J_HOME}" \
24 |     && rm ${NEO4J_TARBALL} \
25 |     && mv "${NEO4J_HOME}"/data /data \
26 |     && mv "${NEO4J_HOME}"/logs /logs \
27 |     && chown -R neo4j:neo4j /data \
28 |     && chmod -R 777 /data \
29 |     && chown -R neo4j:neo4j /logs \
30 |     && chmod -R 777 /logs \
31 |     && chown -R neo4j:neo4j "${NEO4J_HOME}" \
32 |     && chmod -R 777 "${NEO4J_HOME}" \
33 |     && ln -s /data "${NEO4J_HOME}"/data \
34 |     && ln -s /logs "${NEO4J_HOME}"/logs \
35 |     && mv /tmp/neo4j-plugins.json /neo4j-plugins.json \
36 |     && rm -rf /tmp/* \
37 |     && rm -rf /var/lib/apt/lists/*
38 | 
39 | ENV PATH "${NEO4J_HOME}"/bin:$PATH
40 | 
41 | WORKDIR "${NEO4J_HOME}"
42 | 
43 | VOLUME /data /logs
44 | 
45 | COPY docker-entrypoint.sh /docker-entrypoint.sh
46 | 
47 | EXPOSE 7474 7473 7687
48 | 
49 | ENTRYPOINT ["/sbin/tini", "-g", "--", "/docker-entrypoint.sh"]
50 | CMD ["neo4j"]
51 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.4/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | FROM openjdk:8-jre-slim
 2 | 
 3 | ENV NEO4J_SHA256=%%NEO4J_SHA%% \
 4 |     NEO4J_TARBALL=%%NEO4J_TARBALL%% \
 5 |     NEO4J_EDITION=%%NEO4J_EDITION%% \
 6 |     NEO4J_HOME="/var/lib/neo4j" \
 7 |     TINI_VERSION="v0.18.0" \
 8 |     TINI_SHA256="12d20136605531b09a2c2dac02ccee85e1b874eb322ef6baf7561cd93f93c855"
 9 | ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
10 | 
11 | RUN addgroup --system neo4j && adduser --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
12 | 
13 | COPY ./local-package/* /tmp/
14 | 
15 | RUN apt update \
16 |     && apt install -y curl wget gosu jq \
17 |     && curl -L --fail --silent --show-error "https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini" > /sbin/tini \
18 |     && echo "${TINI_SHA256}  /sbin/tini" | sha256sum -c --strict --quiet \
19 |     && chmod +x /sbin/tini \
20 |     && curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
21 |     && echo "${NEO4J_SHA256}  ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
22 |     && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
23 |     && mv /var/lib/neo4j-* "${NEO4J_HOME}" \
24 |     && rm ${NEO4J_TARBALL} \
25 |     && mv "${NEO4J_HOME}"/data /data \
26 |     && mv "${NEO4J_HOME}"/logs /logs \
27 |     && chown -R neo4j:neo4j /data \
28 |     && chmod -R 777 /data \
29 |     && chown -R neo4j:neo4j /logs \
30 |     && chmod -R 777 /logs \
31 |     && chown -R neo4j:neo4j "${NEO4J_HOME}" \
32 |     && chmod -R 777 "${NEO4J_HOME}" \
33 |     && ln -s /data "${NEO4J_HOME}"/data \
34 |     && ln -s /logs "${NEO4J_HOME}"/logs \
35 |     && mv /tmp/neo4j-plugins.json /neo4j-plugins.json \
36 |     && rm -rf /tmp/* \
37 |     && rm -rf /var/lib/apt/lists/* \
38 |     && apt-get -y purge --auto-remove curl
39 | 
40 | ENV PATH "${NEO4J_HOME}"/bin:$PATH
41 | 
42 | WORKDIR "${NEO4J_HOME}"
43 | 
44 | VOLUME /data /logs
45 | 
46 | COPY docker-entrypoint.sh /docker-entrypoint.sh
47 | 
48 | EXPOSE 7474 7473 7687
49 | 
50 | ENTRYPOINT ["/sbin/tini", "-g", "--", "/docker-entrypoint.sh"]
51 | CMD ["neo4j"]
52 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/neo4jadmin/TestReport.java:
--------------------------------------------------------------------------------

```java
 1 | package com.neo4j.docker.neo4jadmin;
 2 | 
 3 | import com.neo4j.docker.utils.WaitStrategies;
 4 | import com.neo4j.docker.utils.TestSettings;
 5 | import org.junit.jupiter.api.Assertions;
 6 | import org.junit.jupiter.api.Test;
 7 | import org.slf4j.Logger;
 8 | import org.slf4j.LoggerFactory;
 9 | import org.testcontainers.containers.ContainerLaunchException;
10 | import org.testcontainers.containers.GenericContainer;
11 | import org.testcontainers.containers.output.Slf4jLogConsumer;
12 | 
13 | import java.time.Duration;
14 | 
15 | public class TestReport
16 | {
17 |     private final Logger log = LoggerFactory.getLogger( TestReport.class );
18 | 
19 |     private GenericContainer createAdminContainer()
20 |     {
21 |         GenericContainer container = new GenericContainer( TestSettings.ADMIN_IMAGE_ID )
22 |                 .withEnv( "NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes" ).withEnv( "NEO4J_DEBUG", "yes" )
23 |                 .withCommand( "neo4j-admin", "server", "report" )
24 |                 .withLogConsumer( new Slf4jLogConsumer( log ) );
25 |         WaitStrategies.waitUntilContainerFinished( container, Duration.ofSeconds( 20 ) );
26 |         return container;
27 |     }
28 | 
29 |     @Test
30 |     void shouldErrorHelpfullyIfAdminReport()
31 |     {
32 |         try(GenericContainer container = createAdminContainer())
33 |         {
34 |             Assertions.assertThrows( ContainerLaunchException.class, container::start );
35 |             Assertions.assertTrue( container.getLogs().contains( "To run the report tool inside a neo4j container, do:" ),
36 |                                    "did not error about needing to run in the same container as the database." +
37 |                                    " Actual logs:"+container.getLogs() );
38 |             Assertions.assertTrue( container.getLogs().contains( "docker exec <CONTAINER NAME> neo4j-admin-report" ),
39 |                                    "did not error about needing to run in the same container as the database." +
40 |                                    " Actual logs:"+container.getLogs() );
41 |         }
42 |     }
43 | }
44 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.5/coredb/neo4j-plugins.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "apoc": {
 3 |     "versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
 4 |     "properties": {
 5 |       "dbms.security.procedures.unrestricted": "apoc.*"
 6 |     }
 7 |   },
 8 |   "apoc-core": {
 9 |     "location": "/var/lib/neo4j/labs/apoc-*-core.jar",
10 |     "versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
11 |     "properties": {
12 |       "dbms.security.procedures.unrestricted": "apoc.*"
13 |     }
14 |   },
15 |   "bloom": {
16 |     "location": "/var/lib/neo4j/products/bloom-plugin-*.jar",
17 |     "versions": "https://bloom-plugins.s3.eu-west-2.amazonaws.com/versions.json",
18 |     "properties": {
19 |       "dbms.unmanaged_extension_classes": "com.neo4j.bloom.server=/browser/bloom",
20 |       "dbms.security.procedures.unrestricted": "bloom.*",
21 |       "neo4j.bloom.license_file": "/licenses/bloom.license"
22 |     }
23 |   },
24 |   "streams": {
25 |     "versions": "https://neo4j-contrib.github.io/neo4j-streams/versions.json",
26 |     "properties": {}
27 |   },
28 |   "graphql": {
29 |     "versions": "https://neo4j-graphql.github.io/neo4j-graphql/versions.json",
30 |     "properties": {
31 |       "dbms.unmanaged_extension_classes": "org.neo4j.graphql=/graphql",
32 |       "dbms.security.procedures.unrestricted": "graphql.*"
33 |     }
34 |   },
35 |   "graph-algorithms": {
36 |     "versions": "https://neo4j-contrib.github.io/neo4j-graph-algorithms/versions.json",
37 |     "properties": {
38 |       "dbms.security.procedures.unrestricted": "algo.*"
39 |     }
40 |   },
41 |   "graph-data-science": {
42 |     "versions": "https://graphdatascience.ninja/versions.json",
43 |     "location": "/var/lib/neo4j/products/neo4j-graph-data-science-*.jar",
44 |     "properties": {
45 |       "dbms.security.procedures.unrestricted": "gds.*"
46 |     }
47 |   },
48 |   "n10s": {
49 |     "versions": "https://neo4j-labs.github.io/neosemantics/versions.json",
50 |     "properties": {
51 |       "dbms.security.procedures.unrestricted":"semantics.*"
52 |     }
53 |   },
54 |   "_testing": {
55 |     "versions": "http://host.testcontainers.internal:3000/versions.json",
56 |     "properties": {
57 |       "dbms.security.procedures.unrestricted": "com.neo4j.docker.neo4jserver.plugins.*"
58 |     }
59 |   }
60 | }
61 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.2/coredb/neo4j-plugins.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "apoc": {
 3 |     "versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
 4 |     "properties": {
 5 |       "dbms.security.procedures.unrestricted": "apoc.*"
 6 |     }
 7 |   },
 8 |   "apoc-core": {
 9 |     "location": "/var/lib/neo4j/labs/apoc-*-core.jar",
10 |     "versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
11 |     "properties": {
12 |       "dbms.security.procedures.unrestricted": "apoc.*"
13 |     }
14 |   },
15 |   "bloom": {
16 |     "location": "/var/lib/neo4j/products/bloom-plugin-*.jar",
17 |     "versions": "https://bloom-plugins.s3.eu-west-2.amazonaws.com/versions.json",
18 |     "properties": {
19 |       "dbms.unmanaged_extension_classes": "com.neo4j.bloom.server=/browser/bloom",
20 |       "dbms.security.procedures.unrestricted": "bloom.*",
21 |       "neo4j.bloom.license_file": "/licenses/bloom.license"
22 |     }
23 |   },
24 |   "streams": {
25 |     "versions": "https://neo4j-contrib.github.io/neo4j-streams/versions.json",
26 |     "properties": {}
27 |   },
28 |   "graphql": {
29 |     "versions": "https://neo4j-graphql.github.io/neo4j-graphql/versions.json",
30 |     "properties": {
31 |       "dbms.unmanaged_extension_classes": "org.neo4j.graphql=/graphql",
32 |       "dbms.security.procedures.unrestricted": "graphql.*"
33 |     }
34 |   },
35 |   "graph-algorithms": {
36 |     "versions": "https://neo4j-contrib.github.io/neo4j-graph-algorithms/versions.json",
37 |     "properties": {
38 |       "dbms.security.procedures.unrestricted": "algo.*"
39 |     }
40 |   },
41 |   "graph-data-science": {
42 |     "versions": "https://graphdatascience.ninja/versions.json",
43 |     "location": "/var/lib/neo4j/products/neo4j-graph-data-science-*.jar",
44 |     "properties": {
45 |       "dbms.security.procedures.unrestricted": "gds.*"
46 |     }
47 |   },
48 |   "n10s": {
49 |     "versions": "https://neo4j-labs.github.io/neosemantics/versions.json",
50 |     "properties": {
51 |       "dbms.security.procedures.unrestricted":"semantics.*"
52 |     }
53 |   },
54 |   "_testing": {
55 |     "versions": "http://host.testcontainers.internal:3000/versions.json",
56 |     "properties": {
57 |       "dbms.security.procedures.unrestricted": "com.neo4j.docker.neo4jserver.plugins.*"
58 |     }
59 |   }
60 | }
61 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.3/coredb/neo4j-plugins.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "apoc": {
 3 |     "versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
 4 |     "properties": {
 5 |       "dbms.security.procedures.unrestricted": "apoc.*"
 6 |     }
 7 |   },
 8 |   "apoc-core": {
 9 |     "location": "/var/lib/neo4j/labs/apoc-*-core.jar",
10 |     "versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
11 |     "properties": {
12 |       "dbms.security.procedures.unrestricted": "apoc.*"
13 |     }
14 |   },
15 |   "bloom": {
16 |     "location": "/var/lib/neo4j/products/bloom-plugin-*.jar",
17 |     "versions": "https://bloom-plugins.s3.eu-west-2.amazonaws.com/versions.json",
18 |     "properties": {
19 |       "dbms.unmanaged_extension_classes": "com.neo4j.bloom.server=/browser/bloom",
20 |       "dbms.security.procedures.unrestricted": "bloom.*",
21 |       "neo4j.bloom.license_file": "/licenses/bloom.license"
22 |     }
23 |   },
24 |   "streams": {
25 |     "versions": "https://neo4j-contrib.github.io/neo4j-streams/versions.json",
26 |     "properties": {}
27 |   },
28 |   "graphql": {
29 |     "versions": "https://neo4j-graphql.github.io/neo4j-graphql/versions.json",
30 |     "properties": {
31 |       "dbms.unmanaged_extension_classes": "org.neo4j.graphql=/graphql",
32 |       "dbms.security.procedures.unrestricted": "graphql.*"
33 |     }
34 |   },
35 |   "graph-algorithms": {
36 |     "versions": "https://neo4j-contrib.github.io/neo4j-graph-algorithms/versions.json",
37 |     "properties": {
38 |       "dbms.security.procedures.unrestricted": "algo.*"
39 |     }
40 |   },
41 |   "graph-data-science": {
42 |     "versions": "https://graphdatascience.ninja/versions.json",
43 |     "location": "/var/lib/neo4j/products/neo4j-graph-data-science-*.jar",
44 |     "properties": {
45 |       "dbms.security.procedures.unrestricted": "gds.*"
46 |     }
47 |   },
48 |   "n10s": {
49 |     "versions": "https://neo4j-labs.github.io/neosemantics/versions.json",
50 |     "properties": {
51 |       "dbms.security.procedures.unrestricted":"semantics.*"
52 |     }
53 |   },
54 |   "_testing": {
55 |     "versions": "http://host.testcontainers.internal:3000/versions.json",
56 |     "properties": {
57 |       "dbms.security.procedures.unrestricted": "com.neo4j.docker.neo4jserver.plugins.*"
58 |     }
59 |   }
60 | }
61 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/ha-cluster-compose.yml:
--------------------------------------------------------------------------------

```yaml
 1 | version: '2.1'
 2 | 
 3 | networks:
 4 |   lan:
 5 | 
 6 | services:
 7 | 
 8 |   master:
 9 |     user: "%%USERIDGROUPID%%"
10 |     image: "%%IMAGE%%"
11 |     volumes:
12 |       - "%%LOGS_DIR%%/master:/logs"
13 |     networks:
14 |       - lan
15 |     ports:
16 |       - 7474
17 |       - 7687
18 |     environment:
19 |       - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
20 |       - NEO4J_dbms_memory_pagecache_size=10M
21 |       - NEO4J_dbms_memory_heap_initial__size=10M
22 |       - NEO4J_AUTH=neo4j/neo
23 |       - NEO4J_ha_serverId=1
24 |       - NEO4J_dbms_mode=HA
25 |       - NEO4J_ha_initialHosts=master:5001,slave1:5555,slave2:5001
26 | 
27 |       # Use this to make sure master pushes TXs to both slaves, by default it will be only one
28 |       # - NEO4J_ha_tx__push__factor=2
29 | 
30 |   slave1:
31 |     user: "%%USERIDGROUPID%%"
32 |     image: "%%IMAGE%%"
33 |     volumes:
34 |       - "%%LOGS_DIR%%/slave1:/logs"
35 |     networks:
36 |       - lan
37 |     ports:
38 |       - 7474
39 |       - 7687
40 |     environment:
41 |       - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
42 |       - NEO4J_dbms_memory_pagecache_size=10M
43 |       - NEO4J_dbms_memory_heap_initial__size=10M
44 |       - NEO4J_AUTH=neo4j/neo
45 |       - NEO4J_dbms_mode=HA
46 |       - NEO4J_ha_serverId=2
47 |       - NEO4J_ha_initialHosts=master:5001,slave1:5555,slave2:5001
48 |       - NEO4J_ha_host_coordination=slave1:5555
49 |       - NEO4J_ha_host_data=slave1:6666
50 |       - NEO4J_ha_slave__only=true
51 |       - NEO4J_ha_pull__interval=5s # Default value is disabled but we want slave to poll master for test
52 | 
53 |   slave2:
54 |     user: "%%USERIDGROUPID%%"
55 |     image: "%%IMAGE%%"
56 |     volumes:
57 |       - "%%LOGS_DIR%%/slave2:/logs"
58 |     networks:
59 |       - lan
60 |     ports:
61 |       - 7474
62 |       - 7687
63 |     environment:
64 |       - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
65 |       - NEO4J_dbms_memory_pagecache_size=10M
66 |       - NEO4J_dbms_memory_heap_initial__size=10M
67 |       - NEO4J_AUTH=neo4j/neo
68 |       - NEO4J_dbms_mode=HA
69 |       - NEO4J_ha_serverId=3
70 |       - NEO4J_ha_initialHosts=master:5001,slave1:5555,slave2:5001
71 |       - NEO4J_ha_host_coordination=slave2:5001
72 |       - NEO4J_ha_host_data=slave2:6001
73 |       - NEO4J_ha_slave__only=true
74 |       - NEO4J_ha_pull__interval=5s # Default value is disabled but we want slave to poll master for test
75 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.4/coredb/neo4j-plugins.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "apoc": {
 3 |     "versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
 4 |     "properties": {
 5 |       "dbms.security.procedures.unrestricted": "apoc.*"
 6 |     }
 7 |   },
 8 |   "apoc-core": {
 9 |     "location": "/var/lib/neo4j/labs/apoc-*-core.jar",
10 |     "versions": "https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/refs/heads/master/versions.json",
11 |     "properties": {
12 |       "dbms.security.procedures.unrestricted": "apoc.*"
13 |     }
14 |   },
15 |   "bloom": {
16 |     "location": "/var/lib/neo4j/products/bloom-plugin-*.jar",
17 |     "versions": "https://bloom-plugins.s3.eu-west-2.amazonaws.com/versions.json",
18 |     "properties": {
19 |       "dbms.unmanaged_extension_classes": "com.neo4j.bloom.server=/browser/bloom",
20 |       "dbms.security.procedures.unrestricted": "bloom.*",
21 |       "neo4j.bloom.license_file": "/licenses/bloom.license"
22 |     }
23 |   },
24 |   "streams": {
25 |     "versions": "https://neo4j-contrib.github.io/neo4j-streams/versions.json",
26 |     "properties": {}
27 |   },
28 |   "graphql": {
29 |     "versions": "https://neo4j-graphql.github.io/neo4j-graphql/versions.json",
30 |     "properties": {
31 |       "dbms.unmanaged_extension_classes": "org.neo4j.graphql=/graphql",
32 |       "dbms.security.procedures.unrestricted": "graphql.*"
33 |     }
34 |   },
35 |   "graph-algorithms": {
36 |     "versions": "https://neo4j-contrib.github.io/neo4j-graph-algorithms/versions.json",
37 |     "properties": {
38 |       "dbms.security.procedures.unrestricted": "algo.*"
39 |     }
40 |   },
41 |   "graph-data-science": {
42 |     "versions": "https://graphdatascience.ninja/versions.json",
43 |     "location": "/var/lib/neo4j/products/neo4j-graph-data-science-*.jar",
44 |     "properties": {
45 |       "dbms.security.procedures.unrestricted": "gds.*"
46 |     }
47 |   },
48 |   "n10s": {
49 |     "versions": "https://neo4j-labs.github.io/neosemantics/versions.json",
50 |     "properties": {
51 |       "dbms.security.procedures.unrestricted":"semantics.*"
52 |     }
53 |   },
54 |   "_testing": {
55 |     "versions": "http://host.testcontainers.internal:3000/versions.json",
56 |     "properties": {
57 |       "dbms.security.procedures.unrestricted": "com.neo4j.docker.neo4jserver.plugins.*"
58 |     }
59 |   }
60 | }
61 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/generate-stub-plugin/ExampleNeo4jPlugin.java:
--------------------------------------------------------------------------------

```java
 1 | package com.neo4j.docker.test.myplugin;
 2 | 
 3 | import java.util.stream.Stream;
 4 | 
 5 | import org.neo4j.graphdb.GraphDatabaseService;
 6 | import org.neo4j.logging.Log;
 7 | import org.neo4j.procedure.Context;
 8 | import org.neo4j.procedure.Name;
 9 | import org.neo4j.procedure.Procedure;
10 | 
11 | /*
12 | This class is a basic Neo4J plugin that defines a procedure which can be called via Cypher.
13 |  */
14 | public class ExampleNeo4jPlugin
15 | {
16 |     // Output data class containing primitive types
17 |     public static class PrimitiveOutput
18 |     {
19 |         public String string;
20 |         public long integer;
21 |         public double aFloat;
22 |         public boolean aBoolean;
23 | 
24 |         public PrimitiveOutput( String string, long integer, double aFloat, boolean aBoolean )
25 |         {
26 |             this.string = string;
27 |             this.integer = integer;
28 |             this.aFloat = aFloat;
29 |             this.aBoolean = aBoolean;
30 |         }
31 |     }
32 | //    @ServiceProvider
33 | //    public static class ExampleConfigurationSetting implements SettingsDeclaration
34 | //    {
35 | //        public static final String CONF_NAME = "com.neo4j.docker.neo4jserver.plugins.loaded_verison";
36 | //
37 | //        @Description("Unique setting to identify which semver field was matched")
38 | //        public static final Setting<String> loadedVersionValue = SettingImpl.newBuilder(
39 | //                CONF_NAME,
40 | //                SettingValueParsers.STRING,
41 | //                "unset"
42 | //        ).build();
43 | //    }
44 | 
45 |     @Context
46 |     public GraphDatabaseService db;
47 | 
48 |     @Context
49 |     public Log log;
50 | 
51 |     // A Neo4j procedure that always returns fixed values
52 |     @Procedure
53 |     public Stream<PrimitiveOutput> defaultValues( @Name( value = "string", defaultValue = "a string" ) String string,
54 |                                                   @Name( value = "integer", defaultValue = "42" ) long integer,
55 |                                                   @Name( value = "float", defaultValue = "3.14" ) double aFloat,
56 |                                                   @Name( value = "boolean", defaultValue = "true" ) boolean aBoolean )
57 |     {
58 |         return Stream.of( new PrimitiveOutput( string, integer, aFloat, aBoolean ) );
59 |     }
60 | }
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/build-utils-common-functions.sh:
--------------------------------------------------------------------------------

```bash
 1 | # Common functions used by build-docker-image.sh and publish-neo4j-admin-image.sh
 2 | 
 3 | function contains_element
 4 | {
 5 |   local e match="$1"
 6 |   shift
 7 |   for e; do [[ "$e" == "$match" ]] && return 0; done
 8 |   return 1
 9 | }
10 | 
11 | function get_branch_from_version
12 | {
13 |     local version=$1
14 |     local major=$(echo "${version}" | sed -E 's/^([0-9]+)\.([0-9]+)\..*/\1/')
15 |     local minor=$(echo "${version}" | sed -E 's/^([0-9]+)\.([0-9]+)\..*/\2/')
16 |     case ${major} in
17 |       1|2|3|4)
18 |         echo "${major}.${minor}"
19 |         return
20 |         ;;
21 |       5)
22 |         echo "${major}"
23 |         return
24 |         ;;
25 |       *)
26 |         echo "calver"
27 |         return
28 |     esac
29 | }
30 | 
31 | function get_major_from_version
32 | {
33 |     echo "$1" | sed -E 's/^([0-9]+)\.([0-9]+)\..*/\1/'
34 | }
35 | 
36 | function get_compatible_dockerfile_for_os_or_error
37 | {
38 |     local branch=${1}
39 |     local requested_os=${2}
40 | 
41 |     case ${branch} in
42 |         calver | 5 | 4.4 )
43 |             local SUPPORTED_IMAGE_OS=("debian" "ubi9")
44 |             if contains_element "${requested_os}" "${SUPPORTED_IMAGE_OS[@]}"; then
45 |                 echo  "Dockerfile-${requested_os}"
46 |                 return 0
47 |             fi
48 |             ;;
49 |         *)
50 |             local SUPPORTED_IMAGE_OS=("debian")
51 |             if contains_element "${requested_os}" "${SUPPORTED_IMAGE_OS[@]}"; then
52 |                 echo  "Dockerfile"
53 |                 return 0
54 |             else
55 |                 echo >&2 "${requested_os} is not a supported operating system for ${branch}."
56 |                 return 1
57 |             fi
58 |             ;;
59 |     esac
60 | }
61 | 
62 | function tarball_name
63 | {
64 |     local version=${1}
65 |     local edition=${2}
66 |     echo "neo4j-${2}-${1}-unix.tar.gz"
67 | }
68 | 
69 | function cached_tarball
70 | {
71 |     local version=${1}
72 |     local edition=${2}
73 |     echo "${TAR_CACHE}/$(tarball_name ${version} ${edition})"
74 | }
75 | 
76 | function fetch_tarball
77 | {
78 |     local version=${1}
79 |     local edition=${2}
80 |     local tar_name=$(tarball_name "${version}" "${edition}")
81 |     mkdir -p ${TAR_CACHE}
82 |     if [[ ! -f $(cached_tarball "${version}" "${edition}") ]]; then
83 |         echo "Downloading ${tar_name} from ${DISTRIBUTION_SITE} to $(cached_tarball ${version} ${edition})"
84 |         wget ${DISTRIBUTION_SITE}/${tar_name} -O "$(cached_tarball ${version} ${edition})"
85 |     fi
86 | }
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/neo4jadmin/TestAdminBasic.java:
--------------------------------------------------------------------------------

```java
 1 | package com.neo4j.docker.neo4jadmin;
 2 | 
 3 | import com.neo4j.docker.utils.WaitStrategies;
 4 | import com.neo4j.docker.utils.TestSettings;
 5 | import org.junit.jupiter.api.Assertions;
 6 | import org.junit.jupiter.api.Assumptions;
 7 | import org.junit.jupiter.api.Test;
 8 | import org.slf4j.Logger;
 9 | import org.slf4j.LoggerFactory;
10 | import org.testcontainers.containers.ContainerLaunchException;
11 | import org.testcontainers.containers.GenericContainer;
12 | import org.testcontainers.containers.output.Slf4jLogConsumer;
13 | 
14 | import java.time.Duration;
15 | 
16 | public class TestAdminBasic
17 | {
18 |     private final Logger log = LoggerFactory.getLogger( TestAdminBasic.class );
19 | 
20 |     @Test
21 |     void testCannotRunNeo4j()
22 |     {
23 |         GenericContainer admin = new GenericContainer( TestSettings.ADMIN_IMAGE_ID );
24 |         admin.withEnv( "NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes" )
25 |              .withExposedPorts( 7474, 7687 )
26 |              .withLogConsumer( new Slf4jLogConsumer( log ) )
27 |              .withCommand( "neo4j", "console" );
28 |         WaitStrategies.waitUntilContainerFinished( admin, Duration.ofSeconds( 30) );
29 | 
30 |         Assertions.assertThrows( ContainerLaunchException.class, admin::start );
31 |         admin.stop();
32 |     }
33 |     @Test
34 |     void testLicenseAcceptanceRequired_Neo4jAdmin()
35 |     {
36 |         Assumptions.assumeTrue( TestSettings.EDITION == TestSettings.Edition.ENTERPRISE,
37 |                                 "No license checks for community edition");
38 | 
39 |         String logsOut;
40 |         try(GenericContainer container = new GenericContainer( TestSettings.ADMIN_IMAGE_ID )
41 |                 .withLogConsumer( new Slf4jLogConsumer( log ) ) )
42 |         {
43 |             WaitStrategies.waitUntilContainerFinished( container, Duration.ofSeconds( 30) );
44 |             // container start should fail due to licensing.
45 |             Assertions.assertThrows( ContainerLaunchException.class, container::start,
46 |                                      "Neo4j did not notify about accepting the license agreement" );
47 |             logsOut = container.getLogs();
48 |         }
49 |         // double check the container didn't warn and start neo4j anyway
50 |         Assertions.assertTrue( logsOut.contains( "must accept the license" ),
51 |                                "Neo4j did not notify about accepting the license agreement" );
52 |         Assertions.assertFalse( logsOut.contains( "Remote interface available" ),
53 |                                 "Neo4j was started even though the license was not accepted" );
54 |     }
55 | }
56 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/publish-neo4j-admin-images.sh:
--------------------------------------------------------------------------------

```bash
 1 | #!/bin/bash
 2 | set -eu -o pipefail
 3 | 
 4 | ROOT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
 5 | source "$ROOT_DIR/build-utils-common-functions.sh"
 6 | 
 7 | if [[ $# -eq 2 ]]; then
 8 |     NEO4JVERSION=${1}
 9 |     REPOSITORY=${2}
10 | elif [[ -z ${NEO4JVERSION:-""} ]]; then
11 |     echo >&2 "NEO4JVERSION is unset. Either set it in the environment or pass as argument to this script."
12 |     exit 1
13 | elif [[ -z ${REPOSITORY:-""} ]]; then
14 |     echo >&2 "REPOSITORY is unset. Either set it in the environment or pass as argument to this script."
15 |     exit 1
16 | fi
17 | 
18 | echo "Verifying access or failing fast, by re-tagging neo4j-admin:5, when successful it's a noop."
19 | docker buildx imagetools create "${REPOSITORY}":5-community \
20 | --tag "${REPOSITORY}:5"
21 | 
22 | echo "Publishing ${REPOSITORY}:${NEO4JVERSION}"
23 | "${ROOT_DIR}/publish-neo4j-admin-image.sh" "${NEO4JVERSION}" "enterprise" "ubi9" "${REPOSITORY}"
24 | "${ROOT_DIR}/publish-neo4j-admin-image.sh" "${NEO4JVERSION}" "community" "ubi9" "${REPOSITORY}"
25 | "${ROOT_DIR}/publish-neo4j-admin-image.sh" "${NEO4JVERSION}" "enterprise" "debian" "${REPOSITORY}"
26 | "${ROOT_DIR}/publish-neo4j-admin-image.sh" "${NEO4JVERSION}" "community" "debian" "${REPOSITORY}"
27 | 
28 | echo "Adding extra tags..."
29 | 
30 | MAJOR=$(get_major_from_version "${NEO4JVERSION}")
31 | 
32 | if [[ "$MAJOR" == "5" ]]; then
33 |     echo "Tagging ${MAJOR}..."
34 |     docker buildx imagetools create "${REPOSITORY}:${NEO4JVERSION}-community-debian" \
35 |     --tag "${REPOSITORY}:5-community" \
36 |     --tag "${REPOSITORY}:5"
37 | 
38 |     docker buildx imagetools create "${REPOSITORY}:${NEO4JVERSION}-enterprise-debian" \
39 |     --tag "${REPOSITORY}:5-enterprise"
40 | 
41 | elif [[ "$MAJOR" -gt 2024 ]]; then
42 |     echo "Tagging calver ${MAJOR}..."
43 |     docker buildx imagetools create "${REPOSITORY}:${NEO4JVERSION}-community-debian" \
44 |     --tag "${REPOSITORY}:${MAJOR}" \
45 |     --tag "${REPOSITORY}:${MAJOR}-community" \
46 |     --tag "${REPOSITORY}:community-debian" \
47 |     --tag "${REPOSITORY}:community" \
48 |     --tag "${REPOSITORY}:debian" \
49 |     --tag "${REPOSITORY}:latest"
50 | 
51 |     docker buildx imagetools create "${REPOSITORY}:${NEO4JVERSION}-community-ubi9" \
52 |     --tag "${REPOSITORY}:community-ubi9" \
53 |     --tag "${REPOSITORY}:ubi9" \
54 | 
55 |     docker buildx imagetools create "${REPOSITORY}:${NEO4JVERSION}-enterprise-debian" \
56 |     --tag "${REPOSITORY}:${MAJOR}-enterprise" \
57 |     --tag "${REPOSITORY}:enterprise-debian" \
58 |     --tag "${REPOSITORY}:enterprise"
59 | 
60 |     docker buildx imagetools create "${REPOSITORY}:${NEO4JVERSION}-enterprise-ubi9" \
61 |     --tag "${REPOSITORY}:enterprise-ubi9"
62 | fi
63 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/utils/WaitStrategies.java:
--------------------------------------------------------------------------------

```java
 1 | package com.neo4j.docker.utils;
 2 | 
 3 | import com.github.dockerjava.api.command.InspectContainerResponse;
 4 | import org.rnorth.ducttape.unreliables.Unreliables;
 5 | import org.testcontainers.containers.GenericContainer;
 6 | import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy;
 7 | import org.testcontainers.containers.wait.strategy.AbstractWaitStrategy;
 8 | import org.testcontainers.containers.wait.strategy.Wait;
 9 | import org.testcontainers.containers.wait.strategy.WaitStrategy;
10 | import org.testcontainers.utility.DockerStatus;
11 | 
12 | import java.time.Duration;
13 | import java.util.concurrent.Callable;
14 | import java.util.concurrent.TimeUnit;
15 | 
16 | public class WaitStrategies
17 | {
18 | 
19 |     private final static Duration STARTUP_TIMEOUT_SECONDS = Duration.ofSeconds(180);
20 | 
21 |     private WaitStrategies() {}
22 | 
23 |     public static WaitStrategy waitForNeo4jReady( String username, String password, String database, Duration timeout )
24 |     {
25 |         if (TestSettings.EDITION == TestSettings.Edition.ENTERPRISE &&
26 |             TestSettings.NEO4J_VERSION.isAtLeastVersion(Neo4jVersion.NEO4J_VERSION_500)) {
27 |             return Wait.forHttp("/db/" + database + "/cluster/available")
28 |                        .withBasicCredentials(username, password)
29 |                        .forPort(7474)
30 |                        .forStatusCode(200)
31 |                        .withStartupTimeout(timeout);
32 |         } else
33 |         {
34 |             return waitForBoltReady();
35 |         }
36 |     }
37 | 
38 |     public static WaitStrategy waitForNeo4jReady( String password ) {
39 |         return waitForNeo4jReady( "neo4j", password, "neo4j", STARTUP_TIMEOUT_SECONDS);
40 |     }
41 | 
42 |     public static WaitStrategy waitForBoltReady()
43 |     {
44 |         return Wait.forHttp("/")
45 |                    .forPort(7687)
46 |                    .forStatusCode(200)
47 |                    .withStartupTimeout(STARTUP_TIMEOUT_SECONDS);
48 |     }
49 | 
50 |     /**For containers that will just run a command and exit automatically.
51 |      * With this wait strategy, starting a container will block until the container has closed itself.
52 |      * The container could have succeeded or failed, we just wait for it to close.
53 |      * If the container fails to start, it will still throw an exception, this just prevents us from having to wait the full timeout.
54 |      * @param container the container to set the wait strategy on
55 |      * @param timeout how long to wait
56 |      * @return container in the modified state.
57 |      * */
58 |     public static GenericContainer waitUntilContainerFinished( GenericContainer container, Duration timeout)
59 |     {
60 |         container.setStartupCheckStrategy( new OneShotStartupCheckStrategy().withTimeout( timeout ) );
61 |         container.setWaitStrategy( new AbstractWaitStrategy()
62 |         {
63 |             @Override
64 |             protected void waitUntilReady()
65 |             {
66 |                 Callable<Boolean> isFinished = () -> {
67 |                     InspectContainerResponse.ContainerState x = waitStrategyTarget.getCurrentContainerInfo().getState();
68 |                     return DockerStatus.isContainerStopped( x );
69 |                 };
70 |                 Unreliables.retryUntilTrue( (int)timeout.getSeconds(), TimeUnit.SECONDS, isFinished );
71 |             }
72 |         });
73 |         return container;
74 |     }
75 | }
76 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/utils/TestSettings.java:
--------------------------------------------------------------------------------

```java
  1 | package com.neo4j.docker.utils;
  2 | 
  3 | import org.junit.jupiter.api.Assertions;
  4 | import org.testcontainers.utility.DockerImageName;
  5 | 
  6 | import java.nio.file.Path;
  7 | import java.nio.file.Paths;
  8 | 
  9 | public class TestSettings
 10 | {
 11 |     public static final Neo4jVersion NEO4J_VERSION = getVersion();
 12 |     public static final DockerImageName IMAGE_ID = getImage();
 13 |     public static final DockerImageName ADMIN_IMAGE_ID = getNeo4jAdminImage();
 14 |     public static final Path TEST_TMP_FOLDER = Paths.get("local-mounts" );
 15 |     public static final Edition EDITION = getEdition();
 16 |     public static final BaseOS BASE_OS = getBaseOS();
 17 |     public static final boolean SKIP_MOUNTED_FOLDER_TARBALLING = getSkipTarballingFromEnv();
 18 | 
 19 |     public enum Edition
 20 |     {
 21 |         COMMUNITY,
 22 |         ENTERPRISE;
 23 |     }
 24 |     public enum BaseOS
 25 |     {
 26 |         BULLSEYE,
 27 |         UBI9,
 28 |         UBI8;
 29 |     }
 30 | 
 31 |     private static String getValueFromPropertyOrEnv(String propertyName, String envName)
 32 |     {
 33 |         String verStr = System.getProperty( propertyName );
 34 |         if(verStr == null)
 35 |         {
 36 |             verStr = System.getenv( envName );
 37 |         }
 38 |         Assertions.assertNotNull( String.format( "Neo4j %s has not been specified. " +
 39 |                                                  "Either use mvn argument -D%s or set env %s",
 40 |                                                  propertyName, propertyName, envName),
 41 |                                   verStr);
 42 |         return verStr;
 43 |     }
 44 | 
 45 |     private static Neo4jVersion getVersion()
 46 |     {
 47 |         return Neo4jVersion.fromVersionString( getValueFromPropertyOrEnv( "version", "NEO4JVERSION" ));
 48 |     }
 49 | 
 50 |     private static DockerImageName getImage()
 51 |     {
 52 |         return DockerImageName.parse(getValueFromPropertyOrEnv("image", "NEO4J_IMAGE"));
 53 |     }
 54 | 
 55 |     private static DockerImageName getNeo4jAdminImage()
 56 |     {
 57 |         return DockerImageName.parse(getValueFromPropertyOrEnv("adminimage", "NEO4JADMIN_IMAGE"));
 58 |     }
 59 | 
 60 |     private static Edition getEdition()
 61 |     {
 62 |         String edition = getValueFromPropertyOrEnv("edition", "NEO4J_EDITION");
 63 |         switch ( edition.toLowerCase() )
 64 |         {
 65 |         case "community":
 66 |             return Edition.COMMUNITY;
 67 |         case "enterprise":
 68 |             return Edition.ENTERPRISE;
 69 |         default:
 70 |             Assertions.fail( edition + " is not a valid Neo4j edition. Options are \"community\" or \"enterprise\"." );
 71 |         }
 72 |         return null;
 73 |     }
 74 | 
 75 |     private static BaseOS getBaseOS()
 76 |     {
 77 |         String os = getValueFromPropertyOrEnv("baseos", "BASE_OS");
 78 |         switch ( os.toLowerCase() )
 79 |         {
 80 |         case "debian":
 81 |             return BaseOS.BULLSEYE;
 82 |         case "ubi9":
 83 |             return BaseOS.UBI9;
 84 |         case "ubi8":
 85 |             return BaseOS.UBI8;
 86 |         default:
 87 |             Assertions.fail( os + " is not a valid Neo4j base operating system. Options are \"debian\", \"ubi9\" or \"ubi8\"." );
 88 |         }
 89 |         return null;
 90 |     }
 91 | 
 92 |     private static boolean getSkipTarballingFromEnv()
 93 |     {
 94 |         // defaults to false. Tarballing test artifacts must be opt-out not opt-in.
 95 |         String skipTar = System.getenv( "NEO4J_SKIP_MOUNTED_FOLDER_TARBALLING" );
 96 |         if(skipTar == null)  return false;
 97 |         else return (skipTar.equals( "true" ));
 98 |     }
 99 | }
100 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/causal-cluster-compose.yml:
--------------------------------------------------------------------------------

```yaml
  1 | version: '2.1'
  2 | 
  3 | networks:
  4 |   lan:
  5 | 
  6 | services:
  7 | 
  8 |   core1:
  9 |     user: "%%USERIDGROUPID%%"
 10 |     image: "%%IMAGE%%"
 11 |     volumes:
 12 |       - "%%LOGS_DIR%%/core1:/logs"
 13 |     networks:
 14 |       - lan
 15 |     ports:
 16 |       - 7474
 17 |       - 7687
 18 |     environment:
 19 |       - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
 20 |       - NEO4J_dbms_memory_pagecache_size=10M
 21 |       - NEO4J_dbms_memory_heap_initial__size=10M
 22 |       - NEO4J_AUTH=neo4j/neo
 23 |       - NEO4J_dbms_mode=CORE
 24 |       - NEO4J_causalClustering_discoveryAdvertisedAddress=core1:5000
 25 |       - NEO4J_causalClustering_transactionAdvertisedAddress=core1:6000
 26 |       - NEO4J_causalClustering_raftAdvertisedAddress=core1:7000
 27 |       - NEO4J_causalClustering_expectedCoreClusterSize=3
 28 |       - NEO4J_causalClustering_initialDiscoveryMembers=core1:5000,core2:5000,core3:5000
 29 |       - NEO4J_causal__clustering_disable__middleware__logging=false
 30 | 
 31 |   core2:
 32 |     user: "%%USERIDGROUPID%%"
 33 |     image: "%%IMAGE%%"
 34 |     volumes:
 35 |       - "%%LOGS_DIR%%/core2:/logs"
 36 |     networks:
 37 |       - lan
 38 |     ports:
 39 |       - 7474
 40 |       - 7687
 41 |     environment:
 42 |       - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
 43 |       - NEO4J_dbms_memory_pagecache_size=10M
 44 |       - NEO4J_dbms_memory_heap_initial__size=10M
 45 |       - NEO4J_AUTH=neo4j/neo
 46 |       - NEO4J_dbms_mode=CORE
 47 |       - NEO4J_causalClustering_discoveryAdvertisedAddress=core2:5000
 48 |       - NEO4J_causalClustering_transactionAdvertisedAddress=core2:6000
 49 |       - NEO4J_causalClustering_raftAdvertisedAddress=core2:7000
 50 |       - NEO4J_causalClustering_expectedCoreClusterSize=3
 51 |       - NEO4J_causalClustering_initialDiscoveryMembers=core1:5000,core2:5000,core3:5000
 52 |       - NEO4J_causalClustering_refuseToBeLeader=true
 53 | 
 54 |   core3:
 55 |     user: "%%USERIDGROUPID%%"
 56 |     image: "%%IMAGE%%"
 57 |     volumes:
 58 |       - "%%LOGS_DIR%%/core3:/logs"
 59 |       - "%%LOGS_DIR%%/core3/backups:/backups"
 60 |     networks:
 61 |       - lan
 62 |     ports:
 63 |       - 6362
 64 |       - 7474
 65 |       - 7687
 66 |     environment:
 67 |       - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
 68 |       - NEO4J_dbms_memory_pagecache_size=10M
 69 |       - NEO4J_dbms_memory_heap_initial__size=10M
 70 |       - NEO4J_AUTH=neo4j/neo
 71 |       - NEO4J_dbms_mode=CORE
 72 |       - NEO4J_causalClustering_discoveryAdvertisedAddress=core3:5000
 73 |       - NEO4J_causalClustering_transactionAdvertisedAddress=core3:6000
 74 |       - NEO4J_causalClustering_raftAdvertisedAddress=core3:7000
 75 |       - NEO4J_causalClustering_expectedCoreClusterSize=3
 76 |       - NEO4J_causalClustering_initialDiscoveryMembers=core1:5000,core2:5000,core3:5000
 77 |       - NEO4J_causalClustering_refuseToBeLeader=true
 78 |       - NEO4J_dbms_backup_enabled=true
 79 |       - NEO4J_dbms_backup_address=0.0.0.0:6362
 80 | 
 81 |   readreplica1:
 82 |     user: "%%USERIDGROUPID%%"
 83 |     image: "%%IMAGE%%"
 84 |     volumes:
 85 |       - "%%LOGS_DIR%%/readreplica1:/logs"
 86 |     networks:
 87 |       - lan
 88 |     ports:
 89 |       - 7474
 90 |       - 7687
 91 |     environment:
 92 |       - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
 93 |       - NEO4J_dbms_memory_pagecache_size=10M
 94 |       - NEO4J_dbms_memory_heap_initial__size=10M
 95 |       - NEO4J_AUTH=neo4j/neo
 96 |       - NEO4J_dbms_mode=READ_REPLICA
 97 |       - NEO4J_causalClustering_discoveryAdvertisedAddress=readreplica1:5000
 98 |       - NEO4J_causalClustering_transactionAdvertisedAddress=readreplica1:6000
 99 |       - NEO4J_causalClustering_raftAdvertisedAddress=readreplica1:7000
100 |       - NEO4J_causalClustering_initialDiscoveryMembers=core1:5000,core2:5000,core3:5000
101 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/utils/Neo4jVersion.java:
--------------------------------------------------------------------------------

```java
  1 | package com.neo4j.docker.utils;
  2 | 
  3 | import java.util.regex.Matcher;
  4 | import java.util.regex.Pattern;
  5 | 
  6 | public class Neo4jVersion
  7 | {
  8 |     public static final Neo4jVersion NEO4J_VERSION_400 = new Neo4jVersion( 4, 0, 0 );
  9 |     public static final Neo4jVersion NEO4J_VERSION_440 = new Neo4jVersion( 4, 4, 0 );
 10 |     public static final Neo4jVersion NEO4J_VERSION_500 = new Neo4jVersion( 5, 0, 0 );
 11 |     public static final Neo4jVersion NEO4J_VERSION_527 = new Neo4jVersion( 5, 27, 0 );
 12 | 
 13 |     public final int major;
 14 |     public final int minor;
 15 |     public final int patch;
 16 |     public final String label;
 17 | 
 18 |     public static Neo4jVersion fromVersionString( String version )
 19 |     {
 20 |         Pattern pattern = Pattern.compile( "(?<major>[\\d]+)\\.(?<minor>[\\d]+)\\.(?<patch>[\\d]+)(?<label>-(.*))?" );
 21 |         Matcher x = pattern.matcher( version );
 22 |         x.find();
 23 | 
 24 |         return new Neo4jVersion(
 25 |                 Integer.parseInt( x.group( "major" ) ),
 26 |                 Integer.parseInt( x.group( "minor" ) ),
 27 |                 Integer.parseInt( x.group( "patch" ) ),
 28 |                 (x.group( "label" ) == null) ? "" : x.group( "label" )
 29 |         );
 30 |     }
 31 | 
 32 |     public static String makeVersionString(int major, int minor)
 33 |     {
 34 |         if ( major > 2023 )
 35 |         {
 36 |             return String.format( "%d.%02d", major, minor);
 37 |         }
 38 |         return String.format( "%d.%d", major, minor);
 39 |     }
 40 | 
 41 |     public static String makeVersionString(int major, int minor, int patch)
 42 |     {
 43 |         return makeVersionString( major, minor) + String.format(".%d", patch);
 44 |     }
 45 | 
 46 |     public Neo4jVersion( int major, int minor, int patch )
 47 |     {
 48 |         this( major, minor, patch, "" );
 49 |     }
 50 | 
 51 |     public Neo4jVersion( int major, int minor, int patch, String label )
 52 |     {
 53 |         this.major = major;
 54 |         this.minor = minor;
 55 |         this.patch = patch;
 56 |         this.label = label;
 57 |     }
 58 | 
 59 |     public boolean isNewerThan(Neo4jVersion that)
 60 |     {
 61 |         if ( this.major != that.major )
 62 |         {
 63 |             return (this.major > that.major);
 64 |         }
 65 |         else
 66 |         {
 67 |             if ( this.minor != that.minor )
 68 |             {
 69 |                 return (this.minor > that.minor);
 70 |             }
 71 |             else
 72 |             {
 73 |                 return (this.patch > that.patch);
 74 |             }
 75 |         }
 76 |         // Not comparing the alpha/beta label because it's still the *same* major minor patch version and a very unlikely upgrade path
 77 |     }
 78 | 
 79 |     public boolean isOlderThan( Neo4jVersion that )
 80 |     {
 81 |         return !isAtLeastVersion( that );
 82 |     }
 83 | 
 84 |     public boolean isAtLeastVersion( Neo4jVersion that )
 85 |     {
 86 |         boolean isNewer = this.isNewerThan( that );
 87 |         if ( !isNewer )
 88 |         {
 89 |             return isEqual( that );
 90 |         }
 91 |         else
 92 |         {
 93 |             return true;
 94 |         }
 95 |     }
 96 | 
 97 |     public boolean isEqual( Neo4jVersion that )
 98 |     {
 99 |         return (major == that.major) && (minor == that.minor) && (patch == that.patch);
100 |     }
101 | 
102 |     @Override
103 |     public String toString()
104 |     {
105 |         return makeVersionString( major, minor, patch ) + label;
106 |     }
107 | 
108 |     public String toReleaseString()
109 |     {
110 |         return makeVersionString( major, minor, patch );
111 |     }
112 | 
113 |     @Override
114 |     public boolean equals( Object o )
115 |     {
116 |         if ( this == o )
117 |         {
118 |             return true;
119 |         }
120 |         if ( o == null || getClass() != o.getClass() )
121 |         {
122 |             return false;
123 |         }
124 | 
125 |         return isEqual( (Neo4jVersion) o );
126 |     }
127 | }
128 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/2.3/docker-entrypoint.sh:
--------------------------------------------------------------------------------

```bash
 1 | #!/bin/bash -eu
 2 | 
 3 | setting() {
 4 |     setting="${1}"
 5 |     value="${2}"
 6 |     file="${3}"
 7 | 
 8 |     if [ -n "${value}" ]; then
 9 |         if grep --quiet --fixed-strings "${setting}=" "${NEO4J_HOME}/conf/${file}"; then
10 |             sed --in-place "s|.*${setting}=.*|${setting}=${value}|" "${NEO4J_HOME}/conf/${file}"
11 |         else
12 |             echo "${setting}=${value}" >>"${NEO4J_HOME}/conf/${file}"
13 |         fi
14 |     fi
15 | }
16 | 
17 | if [ "$1" == "neo4j" ]; then
18 |     setting "keep_logical_logs" "${NEO4J_KEEP_LOGICAL_LOGS:-100M size}" neo4j.properties
19 |     setting "dbms.pagecache.memory" "${NEO4J_CACHE_MEMORY:-512M}" neo4j.properties
20 |     setting "wrapper.java.additional=-Dneo4j.ext.udc.source" "${NEO4J_UDC_SOURCE:-docker}" neo4j-wrapper.conf
21 |     setting "wrapper.java.initmemory" "${NEO4J_HEAP_MEMORY:-512}" neo4j-wrapper.conf
22 |     setting "wrapper.java.maxmemory" "${NEO4J_HEAP_MEMORY:-512}" neo4j-wrapper.conf
23 |     setting "org.neo4j.server.thirdparty_jaxrs_classes" "${NEO4J_THIRDPARTY_JAXRS_CLASSES:-}" neo4j-server.properties
24 |     setting "allow_store_upgrade" "${NEO4J_ALLOW_STORE_UPGRADE:-}" neo4j.properties
25 | 
26 |     if [ "${NEO4J_AUTH:-}" == "none" ]; then
27 |         setting "dbms.security.auth_enabled" "false" neo4j-server.properties
28 |     elif [[ "${NEO4J_AUTH:-}" == neo4j/* ]]; then
29 |         password="${NEO4J_AUTH#neo4j/}"
30 |         setting "org.neo4j.server.webserver.address" "127.0.0.1" neo4j-server.properties
31 |         bin/neo4j start || \
32 |             (cat data/log/console.log && echo "Neo4j failed to start" && exit 1)
33 |         if ! curl --fail --silent --user "neo4j:${password}" http://localhost:7474/db/data/ >/dev/null ; then
34 |             curl --fail --silent --show-error --user neo4j:neo4j \
35 |                 --data '{"password": "'"${password}"'"}' \
36 |                 --header 'Content-Type: application/json' \
37 |                 http://localhost:7474/user/neo4j/password
38 |         fi
39 |         bin/neo4j stop
40 |     elif [ -n "${NEO4J_AUTH:-}" ]; then
41 |         echo "Invalid value for NEO4J_AUTH: '${NEO4J_AUTH}'"
42 |         exit 1
43 |     fi
44 | 
45 |     setting "org.neo4j.server.webserver.address" "0.0.0.0" neo4j-server.properties
46 |     setting "org.neo4j.server.database.mode" "${NEO4J_DATABASE_MODE:-}" neo4j-server.properties
47 |     setting "ha.server_id" "${NEO4J_SERVER_ID:-}" neo4j.properties
48 |     setting "ha.server" "${NEO4J_HA_ADDRESS:-}:6001" neo4j.properties
49 |     setting "ha.cluster_server" "${NEO4J_HA_ADDRESS:-}:5001" neo4j.properties
50 |     setting "ha.initial_hosts" "${NEO4J_INITIAL_HOSTS:-}" neo4j.properties
51 | 
52 |     [ -f "${EXTENSION_SCRIPT:-}" ] && . ${EXTENSION_SCRIPT}
53 | 
54 |     if [ -d /conf ]; then
55 |         find /conf -type f -exec cp {} "${NEO4J_HOME}/conf" \;
56 |     fi
57 | 
58 |     if [ -d /ssl ]; then
59 |         num_certs=$(ls /ssl/*.cert 2>/dev/null | wc -l)
60 |         num_keys=$(ls /ssl/*.key 2>/dev/null | wc -l)
61 |         if [ $num_certs == "1" -a $num_keys == "1" ]; then
62 |             cert=$(ls /ssl/*.cert)
63 |             key=$(ls /ssl/*.key)
64 |             setting "dbms.security.tls_certificate_file" $cert neo4j-server.properties
65 |             setting "dbms.security.tls_key_file" $key neo4j-server.properties
66 |         else
67 |             echo "You must provide exactly one *.cert and exactly one *.key in /ssl."
68 |             exit 1
69 |         fi
70 |     fi
71 | 
72 |     if [ -d /plugins ]; then
73 |         find /plugins -type f -exec cp {} plugins \;
74 |     fi
75 | 
76 |     exec bin/neo4j console
77 | elif [ "$1" == "dump-config" ]; then
78 |     if [ -d "${NEO4J_HOME}/conf" ]; then
79 |         cp --recursive "${NEO4J_HOME}"/conf/* /conf
80 |     else
81 |         echo >&2 "You must provide a /conf volume"
82 |         exit 1
83 |     fi
84 | else
85 |     exec "$@"
86 | fi
87 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.5/neo4j-admin/docker-entrypoint.sh:
--------------------------------------------------------------------------------

```bash
  1 | #!/bin/bash -eu
  2 | 
  3 | function running_as_root
  4 | {
  5 |     test "$(id -u)" = "0"
  6 | }
  7 | 
  8 | function is_writable
  9 | {
 10 |     ${exec_cmd} test -w "${1}"
 11 | }
 12 | 
 13 | function print_permissions_advice_and_fail
 14 | {
 15 |     local _directory=${1}
 16 |     echo >&2 "
 17 | Folder ${_directory} is not accessible for user: ${userid} or group ${groupid} or groups ${groups[@]}, this is commonly a file permissions issue on the mounted folder.
 18 | 
 19 | Hints to solve the issue:
 20 | 1) Make sure the folder exists before mounting it. Docker will create the folder using root permissions before starting the Neo4j container. The root permissions disallow Neo4j from writing to the mounted folder.
 21 | 2) Pass the folder owner's user ID and group ID to docker run, so that docker runs as that user.
 22 | If the folder is owned by the current user, this can be done by adding this flag to your docker run command:
 23 |   --user=\$(id -u):\$(id -g)
 24 |        "
 25 |     exit 1
 26 | }
 27 | 
 28 | 
 29 | function check_mounted_folder_writable_with_chown
 30 | {
 31 |     local mountFolder=${1}
 32 |     if running_as_root; then
 33 |         # check folder permissions
 34 |         if ! is_writable "${mountFolder}" ;  then
 35 |             # warn that we're about to chown the folder and then chown it
 36 |             echo "Warning: Folder mounted to \"${mountFolder}\" is not writable from inside container. Changing folder owner to ${userid}."
 37 |             chown -R "${userid}":"${groupid}" "${mountFolder}"
 38 |         # check permissions on files in the folder
 39 |         elif [ $(${exec_cmd} find "${mountFolder}" -not -writable | wc -l) -gt 0 ]; then
 40 |             echo "Warning: Some files inside \"${mountFolder}\" are not writable from inside container. Changing folder owner to ${userid}."
 41 |             chown -R "${userid}":"${groupid}" "${mountFolder}"
 42 |         fi
 43 |     else
 44 |         if [[ ! -w "${mountFolder}" ]]  && [[ "$(stat -c %U ${mountFolder})" != "neo4j" ]]; then
 45 |             print_permissions_advice_and_fail "${mountFolder}"
 46 |         fi
 47 |     fi
 48 | }
 49 | 
 50 | # ==== SETUP WHICH USER TO RUN AS ====
 51 | 
 52 | if running_as_root; then
 53 |   userid="neo4j"
 54 |   groupid="neo4j"
 55 |   groups=($(id -G neo4j))
 56 |   exec_cmd="runuser -p -u neo4j -g neo4j --"
 57 | else
 58 |   userid="$(id -u)"
 59 |   groupid="$(id -g)"
 60 |   groups=($(id -G))
 61 |   exec_cmd="exec"
 62 | fi
 63 | 
 64 | 
 65 | # ==== CHECK LICENSE AGREEMENT ====
 66 | 
 67 | if [ "${NEO4J_EDITION}" == "enterprise" ]; then
 68 |     if [ "${NEO4J_ACCEPT_LICENSE_AGREEMENT:=no}" != "yes" ]; then
 69 |       echo >&2 "
 70 | In order to use Neo4j Enterprise Edition you must accept the license agreement.
 71 | 
 72 | (c) Neo4j Sweden AB. 2022.  All Rights Reserved.
 73 | Use of this Software without a proper commercial license with Neo4j,
 74 | Inc. or its affiliates is prohibited.
 75 | 
 76 | Email inquiries can be directed to: [email protected]
 77 | 
 78 | More information is also available at: https://neo4j.com/licensing/
 79 | 
 80 | 
 81 | To accept the license agreement set the environment variable
 82 | NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
 83 | 
 84 | To do this you can use the following docker argument:
 85 | 
 86 |     --env=NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
 87 | "
 88 |       exit 1
 89 |     fi
 90 | fi
 91 | 
 92 | # ==== ENSURE MOUNT FOLDER READ/WRITABILITY ====
 93 | 
 94 | if [ -d /data ]; then
 95 |     check_mounted_folder_writable_with_chown "/data"
 96 |     if [ -d /data/databases ]; then
 97 |         check_mounted_folder_writable_with_chown "/data/databases"
 98 |     fi
 99 |     if [ -d /data/dbms ]; then
100 |         check_mounted_folder_writable_with_chown "/data/dbms"
101 |     fi
102 | fi
103 | if [ -d /backups ]; then
104 |     check_mounted_folder_writable_with_chown "/backups"
105 | fi
106 | 
107 | # ==== MAKE SURE NEO4J CANNOT BE RUN FROM THIS CONTAINER ====
108 | 
109 | if [[ "${1}" == "neo4j" ]]; then
110 |     correct_image="neo4j:"$(neo4j-admin --version)"-${NEO4J_EDITION}"
111 |     echo >&2 "
112 | This is a neo4j-admin only image, and usage of Neo4j server is not supported from here.
113 | If you wish to start a Neo4j database, use:
114 | 
115 | docker run ${correct_image}
116 |     "
117 |     exit 1
118 | fi
119 | 
120 | # ==== START NEO4J-ADMIN COMMAND ====
121 | 
122 | ${exec_cmd} "${@}"
123 | 
```

--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.3/neo4j-admin/docker-entrypoint.sh:
--------------------------------------------------------------------------------

```bash
  1 | #!/bin/bash -eu
  2 | 
  3 | function running_as_root
  4 | {
  5 |     test "$(id -u)" = "0"
  6 | }
  7 | 
  8 | function is_writable
  9 | {
 10 |     ${exec_cmd} test -w "${1}"
 11 | }
 12 | 
 13 | function print_permissions_advice_and_fail
 14 | {
 15 |     local _directory=${1}
 16 |     echo >&2 "
 17 | Folder ${_directory} is not accessible for user: ${userid} or group ${groupid} or groups ${groups[@]}, this is commonly a file permissions issue on the mounted folder.
 18 | 
 19 | Hints to solve the issue:
 20 | 1) Make sure the folder exists before mounting it. Docker will create the folder using root permissions before starting the Neo4j container. The root permissions disallow Neo4j from writing to the mounted folder.
 21 | 2) Pass the folder owner's user ID and group ID to docker run, so that docker runs as that user.
 22 | If the folder is owned by the current user, this can be done by adding this flag to your docker run command:
 23 |   --user=\$(id -u):\$(id -g)
 24 |        "
 25 |     exit 1
 26 | }
 27 | 
 28 | 
 29 | function check_mounted_folder_writable_with_chown
 30 | {
 31 |     local mountFolder=${1}
 32 |     if running_as_root; then
 33 |         # check folder permissions
 34 |         if ! is_writable "${mountFolder}" ;  then
 35 |             # warn that we're about to chown the folder and then chown it
 36 |             echo "Warning: Folder mounted to \"${mountFolder}\" is not writable from inside container. Changing folder owner to ${userid}."
 37 |             chown -R "${userid}":"${groupid}" "${mountFolder}"
 38 |         # check permissions on files in the folder
 39 |         elif [ $(${exec_cmd} find "${mountFolder}" -not -writable | wc -l) -gt 0 ]; then
 40 |             echo "Warning: Some files inside \"${mountFolder}\" are not writable from inside container. Changing folder owner to ${userid}."
 41 |             chown -R "${userid}":"${groupid}" "${mountFolder}"
 42 |         fi
 43 |     else
 44 |         if [[ ! -w "${mountFolder}" ]]  && [[ "$(stat -c %U ${mountFolder})" != "neo4j" ]]; then
 45 |             print_permissions_advice_and_fail "${mountFolder}"
 46 |         fi
 47 |     fi
 48 | }
 49 | 
 50 | # ==== SETUP WHICH USER TO RUN AS ====
 51 | 
 52 | if running_as_root; then
 53 |   userid="neo4j"
 54 |   groupid="neo4j"
 55 |   groups=($(id -G neo4j))
 56 |   exec_cmd="runuser -p -u neo4j -g neo4j --"
 57 | else
 58 |   userid="$(id -u)"
 59 |   groupid="$(id -g)"
 60 |   groups=($(id -G))
 61 |   exec_cmd="exec"
 62 | fi
 63 | 
 64 | 
 65 | # ==== CHECK LICENSE AGREEMENT ====
 66 | 
 67 | if [ "${NEO4J_EDITION}" == "enterprise" ]; then
 68 |     if [ "${NEO4J_ACCEPT_LICENSE_AGREEMENT:=no}" != "yes" ]; then
 69 |       echo >&2 "
 70 | In order to use Neo4j Enterprise Edition you must accept the license agreement.
 71 | 
 72 | (c) Neo4j Sweden AB. 2022.  All Rights Reserved.
 73 | Use of this Software without a proper commercial license with Neo4j,
 74 | Inc. or its affiliates is prohibited.
 75 | 
 76 | Email inquiries can be directed to: [email protected]
 77 | 
 78 | More information is also available at: https://neo4j.com/licensing/
 79 | 
 80 | 
 81 | To accept the license agreement set the environment variable
 82 | NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
 83 | 
 84 | To do this you can use the following docker argument:
 85 | 
 86 |     --env=NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
 87 | "
 88 |       exit 1
 89 |     fi
 90 | fi
 91 | 
 92 | # ==== ENSURE MOUNT FOLDER READ/WRITABILITY ====
 93 | 
 94 | if [ -d /data ]; then
 95 |     check_mounted_folder_writable_with_chown "/data"
 96 |     if [ -d /data/databases ]; then
 97 |         check_mounted_folder_writable_with_chown "/data/databases"
 98 |     fi
 99 |     if [ -d /data/dbms ]; then
100 |         check_mounted_folder_writable_with_chown "/data/dbms"
101 |     fi
102 |     if [ -d /data/transactions ]; then
103 |         check_mounted_folder_writable_with_chown "/data/transactions"
104 |     fi
105 | fi
106 | if [ -d /backups ]; then
107 |     check_mounted_folder_writable_with_chown "/backups"
108 | fi
109 | 
110 | # ==== MAKE SURE NEO4J CANNOT BE RUN FROM THIS CONTAINER ====
111 | 
112 | if [[ "${1}" == "neo4j" ]]; then
113 |     correct_image="neo4j:"$(neo4j-admin --version)"-${NEO4J_EDITION}"
114 |     echo >&2 "
115 | This is a neo4j-admin only image, and usage of Neo4j server is not supported from here.
116 | If you wish to start a Neo4j database, use:
117 | 
118 | docker run ${correct_image}
119 |     "
120 |     exit 1
121 | fi
122 | 
123 | # ==== START NEO4J-ADMIN COMMAND ====
124 | 
125 | ${exec_cmd} "${@}"
126 | 
```
Page 1/7FirstPrevNextLast