This is page 1 of 6. Use http://codebase.md/chillbruhhh/crawl4ai-mcp?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:
--------------------------------------------------------------------------------
```
crawl4ai_mcp.egg-info
__pycache__
.venv
.env
```
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
```
# Auto detect text files and perform LF normalization
* text=auto
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/.gitignore:
--------------------------------------------------------------------------------
```
.idea
.java-version
*.iml
/tmp/
/out/
/in/
/devenv.local
/local-mounts/
/target/
/build/
.DS_Store
# simlinks to dev scripts in https://github.com/neo-technology/teamcity-witchcraft
download_tool.py
docker_tests_get_installers.py
__pycache__/
```
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
# Environment variables
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
.env.txt
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
__pycache__
crawl4ai_mcp.egg-info
repos
# Virtual environments
.venv
.venv/
venv/
ENV/
env/
.env/
# IDE and editor files
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
.claude
.cursor
# Jupyter Notebook
.ipynb_checkpoints
# PyCharm
.idea/
# Project specific
crawl4ai_mcp.egg-info/
repos/
knowledge_graphs/repos/
test_script_hallucination*
# Docker
.dockerignore
docker-compose.override.yml
# Logs
*.log
logs/
# Neo4j
.neo4j/
# Temporary files
*.tmp
*.temp
.tmp/
# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Coverage reports
htmlcov/
.coverage
.coverage.*
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Playwright browsers
.playwright/
# UV lock files (keep uv.lock for reproducible builds)
# uv.lock
# FastMCP generated files
.fastmcp/
```
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
```
# The transport for the MCP server - either 'sse' or 'stdio' (defaults to sse if left empty)
TRANSPORT=
# Host to bind to if using sse as the transport (leave empty if using stdio)
# Set this to 0.0.0.0 if using Docker, otherwise set to localhost (if using uv)
HOST=0.0.0.0
# Port to listen on if using sse as the transport (leave empty if using stdio)
PORT=8051
# Get your Open AI API Key by following these instructions -
# https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key
# This is for the embedding model - text-embed-small-3 will be used
OPENAI_API_KEY=
# Get your OpenRouter API Key from https://openrouter.ai/keys
# This is for chat completions (summaries, contextual embeddings, code example summaries)
OPENROUTER_API_KEY=
# The LLM you want to use for summaries and contextual embeddings
# Use OpenRouter model format like openai/gpt-4o-mini, anthropic/claude-3-haiku, etc.
MODEL_CHOICE=openai/gpt-4o-mini
# Optional: Your site URL and name for OpenRouter rankings (optional)
YOUR_SITE_URL=
YOUR_SITE_NAME=Crawl4AI-MCP
# RAG strategies - set these to "true" or "false" (default to "false")
# USE_CONTEXTUAL_EMBEDDINGS: Enhances embeddings with contextual information for better retrieval
USE_CONTEXTUAL_EMBEDDINGS=true
# USE_HYBRID_SEARCH: Combines vector similarity search with keyword search for better results
USE_HYBRID_SEARCH=true
# USE_AGENTIC_RAG: Enables code example extraction, storage, and specialized code search functionality
USE_AGENTIC_RAG=true
# USE_RERANKING: Applies cross-encoder reranking to improve search result relevance
USE_RERANKING=true
# USE_KNOWLEDGE_GRAPH: Enables AI hallucination detection and repository parsing tools using Neo4j
# If you set this to true, you must also set the Neo4j environment variables below.
USE_KNOWLEDGE_GRAPH=false
# For the Supabase version (sample_supabase_agent.py), set your Supabase URL and Service Key.
# Get your SUPABASE_URL from the API section of your Supabase project settings -
# https://supabase.com/dashboard/project/<your project ID>/settings/api
SUPABASE_URL=
# Get your SUPABASE_SERVICE_KEY from the API section of your Supabase project settings -
# https://supabase.com/dashboard/project/<your project ID>/settings/api
# On this page it is called the service_role secret.
SUPABASE_SERVICE_KEY=
# Neo4j Configuration for Knowledge Graph Tools
# These are required for the AI hallucination detection and repository parsing tools
# Leave empty to disable knowledge graph functionality
# Neo4j connection URI - use bolt://localhost:7687 for local, neo4j:// for cloud instances
# IMPORTANT: If running the MCP server through Docker, change localhost to host.docker.internal
NEO4J_URI=bolt://localhost:7687
# Neo4j username (usually 'neo4j' for default installations)
NEO4J_USER=neo4j
# Neo4j password for your database instance
NEO4J_PASSWORD=password
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/generate-stub-plugin/README.md:
--------------------------------------------------------------------------------
```markdown
# What is this?
This code is purely for generating the [myPlugin.jar test artifact](../src/test/resources/testplugin/myPlugin.jar).
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.*
# Do I need to run this code at all?
Short answer: **No.**
A pre-generated `myPlugin.jar` is already included in the test resources.
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.
## How to generate new test plugin
The Makefile will do all the work for you, all you need to do is pick which version of Neo4j to use:
```shell
NEO4JVERSION=4.4.11 make clean plugin
```
The Dockerfile is currently set to use java 11. If that needs to change then just change the base image that the Dockerfile uses.
Don't forget to commit the newly generated `myPlugin.jar` back to git when you've finished.
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/README.md:
--------------------------------------------------------------------------------
```markdown
*NOTE:* Supported images are available in the [official image library](https://hub.docker.com/_/neo4j/) on Docker Hub.
Please use those in production.
# Neo4j Docker Image Build and Run Guide
## Prerequisites
- **Docker Desktop** installed and running
- **Git** (for Git Bash on Windows)
- **Make** (optional, for convenience commands)
- **Internet connection** (to download Neo4j source tarballs)
## Quick Start
### 1. Building the Image
#### On Windows (PowerShell)
```powershell
# Navigate to the docker-neo4j directory
cd docker-neo4j
# Build Neo4j 5.9.0 Community Edition on Debian
& "C:\Program Files\Git\bin\bash.exe" ./build-docker-image.sh 5.9.0 community debian
# Build Neo4j 4.4.30 Enterprise Edition on Red Hat UBI9
& "C:\Program Files\Git\bin\bash.exe" ./build-docker-image.sh 4.4.30 enterprise ubi9
```
#### On Linux/Mac
```bash
# Navigate to the docker-neo4j directory
cd docker-neo4j
# Build Neo4j 5.9.0 Community Edition on Debian
./build-docker-image.sh 5.9.0 community debian
# Build Neo4j 4.4.30 Enterprise Edition on Red Hat UBI9
./build-docker-image.sh 4.4.30 enterprise ubi9
```
#### Using Make (Linux/Mac)
```bash
# Build and tag Neo4j 5.9.0 Community Edition
NEO4JVERSION=5.9.0 make tag-debian-community
# Build and tag Neo4j 4.4.30 Enterprise Edition
NEO4JVERSION=4.4.30 make tag-ubi9-enterprise
```
### 2. Running the Container
#### Basic Usage
```bash
# Run Neo4j Community Edition
docker run -d --name neo4j-container \
-p 7474:7474 -p 7687:7687 \
-v neo4j-data:/data \
-v neo4j-logs:/logs \
-e NEO4J_AUTH=neo4j/your-password \
neo4jtest:TAG_ID
# Run Neo4j Enterprise Edition
docker run -d --name neo4j-enterprise \
-p 7474:7474 -p 7687:7687 \
-v neo4j-data:/data \
-v neo4j-logs:/logs \
-e NEO4J_AUTH=neo4j/your-password \
-e NEO4J_ACCEPT_LICENSE_AGREEMENT=yes \
neo4jtest:TAG_ID
```
#### With Custom Configuration
```bash
docker run -d --name neo4j-container \
-p 7474:7474 -p 7687:7687 \
-v neo4j-data:/data \
-v neo4j-logs:/logs \
-v neo4j-conf:/conf \
-e NEO4J_AUTH=neo4j/your-password \
-e NEO4J_server_memory_heap_initial__size=1G \
-e NEO4J_server_memory_heap_max__size=2G \
neo4jtest:TAG_ID
```
### 3. Accessing Neo4j
#### Neo4j Browser (Web Interface)
Open your browser and go to: **http://localhost:7474/**
Login with:
- **Username**: `neo4j`
- **Password**: `your-password` (as set in NEO4J_AUTH)
#### Programmatic Access
- **Bolt Protocol**: `bolt://localhost:7687`
- **HTTP API**: `http://localhost:7474/`
## Build Options
### Supported Versions
- **Neo4j 5.x**: Latest features (recommended)
- **Neo4j 4.4.x**: LTS support
- **Neo4j 4.0-4.3**: Legacy support
### Supported Editions
- **Community**: Free, open-source edition
- **Enterprise**: Commercial edition with advanced features
### Supported Base OS
- **debian**: Debian bullseye-slim (recommended)
- **ubi9**: Red Hat Universal Base Image 9
- **ubi8**: Red Hat Universal Base Image 8 (deprecated)
## Common Issues and Solutions
### Windows Line Ending Issues
If you get errors like `$'\r': command not found`, convert scripts to Unix line endings:
```bash
# Using Git Bash on Windows
dos2unix docker-image-src/common/utilities.sh
dos2unix docker-image-src/5/coredb/docker-entrypoint.sh
dos2unix docker-image-src/5/coredb/neo4j-admin-report.sh
```
### SHA Command Issues
The build script uses `shasum` which may not be available on all systems. The script has been updated to use `sha256sum` as an alternative.
### Download Issues
If the build fails to download the Neo4j tarball, you can manually download it:
```bash
# Download manually
curl -L -o in/neo4j-community-5.9.0-unix.tar.gz https://dist.neo4j.org/neo4j-community-5.9.0-unix.tar.gz
# Then run the build
./build-docker-image.sh 5.9.0 community debian
```
## Container Management
### Check Container Status
```bash
docker ps | grep neo4j
```
### View Logs
```bash
docker logs neo4j-container
```
### Stop/Start Container
```bash
docker stop neo4j-container
docker start neo4j-container
```
### Remove Container (data persists in volumes)
```bash
docker rm neo4j-container
```
## Data Persistence
Neo4j data is stored in Docker volumes:
- **Database data**: `neo4j-data` volume
- **Logs**: `neo4j-logs` volume
- **Configuration**: `neo4j-conf` volume (optional)
To backup data:
```bash
docker run --rm -v neo4j-data:/data -v $(pwd):/backup ubuntu tar czf /backup/neo4j-backup.tar.gz /data
```
## Environment Variables
Common environment variables for configuration:
- `NEO4J_AUTH=neo4j/password` - Set authentication
- `NEO4J_AUTH=none` - Disable authentication (not recommended)
- `NEO4J_ACCEPT_LICENSE_AGREEMENT=yes` - Accept enterprise license
- `NEO4J_server_memory_heap_initial__size=1G` - Set initial heap size
- `NEO4J_server_memory_heap_max__size=2G` - Set maximum heap size
## Using the Built Images
After building, you can tag your images for easier management:
```bash
# Tag the built images
docker tag neo4jtest:TAG_ID neo4j:5.9.0-community-debian
docker tag neo4jadmintest:TAG_ID neo4j-admin:5.9.0-community-debian
# Use the tagged images
docker run -d --name neo4j-container \
-p 7474:7474 -p 7687:7687 \
-v neo4j-data:/data \
-e NEO4J_AUTH=neo4j/password \
neo4j:5.9.0-community-debian
```
## Complete Example
Here's a complete example from building to running Neo4j:
```bash
# 1. Build the image
& "C:\Program Files\Git\bin\bash.exe" ./build-docker-image.sh 5.9.0 community debian
# 2. Find the built image ID
docker images | grep neo4jtest
# 3. Run the container
docker run -d --name neo4j-container \
-p 7474:7474 -p 7687:7687 \
-v neo4j-data:/data \
-v neo4j-logs:/logs \
-e NEO4J_AUTH=neo4j/mypassword \
neo4jtest:TAG_ID
# 4. Check if it's running
docker ps | grep neo4j
# 5. View startup logs
docker logs neo4j-container
# 6. Access Neo4j Browser at http://localhost:7474
# Login with: neo4j/mypassword
```
## Testing Your Build
After building and running, you can test your Neo4j instance:
```bash
# Test with cypher-shell (if available)
docker exec -it neo4j-container cypher-shell -u neo4j -p mypassword
# Or test with curl
curl -u neo4j:mypassword -H "Content-Type: application/json" \
-X POST http://localhost:7474/db/data/transaction/commit \
-d '{"statements":[{"statement":"CREATE (n:Test {name: \"Hello World\"}) RETURN n"}]}'
```
# Neo4j images for ARM64
From 4.4.0 and onwards, Neo4j images have been available for ARM64 architectures through [Docker Hub](https://hub.docker.com/_/neo4j/).
For earlier versions, we provide unsupported and untested builds of ARM64 Neo4j community edition from 4.0.0 to 4.3.23.
These are unsuitable for production use, but may be useful for experimentation or hobbyists.
They are available on Docker hub at:
https://hub.docker.com/r/neo4j/neo4j-arm64-experimental
The images take the name format `neo4j/neo4j-arm64-experimental:<VERSION>-arm64`.
## Building on ARM64
The build process is the same as on other architectures for Neo4j 4.4.0+:
```bash
# ARM64 build example
./build-docker-image.sh 4.4.30 community debian
```
# Building and Developing the Neo4j Docker Image
See [DEVELOPMENT.md](DEVELOPMENT.md)
# Getting support and contributing
For bug reports and feature requests, please create issues and pull requests against this Github repository.
If you need guidance with using Neo4j you can ask questions here: https://community.neo4j.com/
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
<h1 align="center">Crawl4AI RAG MCP Server</h1>
<p align="center">
<em>Web Crawling and RAG Capabilities for AI Agents and AI Coding Assistants</em>
</p>
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.
With this MCP server, you can <b>scrape anything</b> and then <b>use that knowledge anywhere</b> for RAG.
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.
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!
## Overview
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.
The server includes several advanced RAG strategies that can be enabled to enhance retrieval quality:
- **Contextual Embeddings** for enriched semantic understanding
- **Hybrid Search** combining vector and keyword search
- **Agentic RAG** for specialized code example extraction
- **Reranking** for improved result relevance using cross-encoder models
- **Knowledge Graph** for AI hallucination detection and repository code analysis
See the [Configuration section](#configuration) below for details on how to enable and configure these strategies.
## Vision
The Crawl4AI RAG MCP server is just the beginning. Here's where we're headed:
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.
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.
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.
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.
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.
## Features
- **Smart URL Detection**: Automatically detects and handles different URL types (regular webpages, sitemaps, text files)
- **Recursive Crawling**: Follows internal links to discover content
- **Parallel Processing**: Efficiently crawls multiple pages simultaneously
- **Content Chunking**: Intelligently splits content by headers and size for better processing
- **Vector Search**: Performs RAG over crawled content, optionally filtering by data source for precision
- **Source Retrieval**: Retrieve sources available for filtering to guide the RAG process
- **Full Docker Support**: Complete Docker compatibility including Neo4j knowledge graph functionality
- **Knowledge Graph Integration**: AI hallucination detection and repository analysis with included Neo4j Docker setup
## Tools
The server provides essential web crawling and search tools:
### Core Tools (Always Available)
1. **`crawl_single_page`**: Quickly crawl a single web page and store its content in the vector database
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)
3. **`get_available_sources`**: Get a list of all available sources (domains) in the database
4. **`perform_rag_query`**: Search for relevant content using semantic search with optional source filtering
### Conditional Tools
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.
### Knowledge Graph Tools (requires `USE_KNOWLEDGE_GRAPH=true`, see below)
6. **`parse_github_repository`**: Parse a GitHub repository into a Neo4j knowledge graph, extracting classes, methods, functions, and their relationships for hallucination detection
7. **`check_ai_script_hallucinations`**: Analyze Python scripts for AI hallucinations by validating imports, method calls, and class usage against the knowledge graph
8. **`query_knowledge_graph`**: Explore and query the Neo4j knowledge graph with commands like `repos`, `classes`, `methods`, and custom Cypher queries
## Prerequisites
- [Docker/Docker Desktop](https://www.docker.com/products/docker-desktop/) if running the MCP server as a container (recommended)
- [Python 3.12+](https://www.python.org/downloads/) if running the MCP server directly through uv
- [Supabase](https://supabase.com/) (database for RAG)
- [OpenAI API key](https://platform.openai.com/api-keys) (for generating embeddings)
- [OpenRouter API key](https://openrouter.ai/keys) (for LLM chat completions)
- [Neo4j](https://neo4j.com/) (optional, for knowledge graph functionality) - see [Knowledge Graph Setup](#knowledge-graph-setup) section
## Installation
### Using Docker (Recommended)
1. Clone this repository:
```bash
git clone https://github.com/coleam00/mcp-crawl4ai-rag.git
cd mcp-crawl4ai-rag
```
2. Build the Docker image:
```bash
docker build -t mcp/crawl4ai-rag --build-arg PORT=8051 .
```
3. Create a `.env` file based on the configuration section below
### Using uv directly (no Docker)
1. Clone this repository:
```bash
git clone https://github.com/coleam00/mcp-crawl4ai-rag.git
cd mcp-crawl4ai-rag
```
2. Install uv if you don't have it:
```bash
pip install uv
```
3. Create and activate a virtual environment:
```bash
uv venv
.venv\Scripts\activate
# on Mac/Linux: source .venv/bin/activate
```
4. Install dependencies:
```bash
uv pip install -e .
crawl4ai-setup
```
5. Create a `.env` file based on the configuration section below
## Database Setup
Before running the server, you need to set up the database with the pgvector extension:
1. Go to the SQL Editor in your Supabase dashboard (create a new project first if necessary)
2. Create a new query and paste the contents of `crawled_pages.sql`
3. Run the query to create the necessary tables and functions
## Knowledge Graph Setup (Optional)
To enable AI hallucination detection and repository analysis features, you need to set up Neo4j.
**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.
For installing Neo4j:
### Local AI Package (Recommended)
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:
1. **Clone the Local AI Package**:
```bash
git clone https://github.com/coleam00/local-ai-packaged.git
cd local-ai-packaged
```
2. **Start Neo4j**:
Follow the instructions in the Local AI Package repository to start Neo4j with Docker Compose
3. **Default connection details**:
- URI: `bolt://localhost:7687`
- Username: `neo4j`
- Password: Check the Local AI Package documentation for the default password
### Using the Included Neo4j Docker Setup (Recommended)
**Quick Setup** - Build and run Neo4j in under 2 minutes:
1. **Build the Neo4j Docker image**:
```bash
cd neo4j/docker-neo4j
./build-docker-image.sh 5.9.0 community debian
```
2. **Run Neo4j container**:
```bash
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
```
3. **Connection details**:
- **Web UI**: http://localhost:7474 (neo4j/your_password)
- **Bolt URI**: `bolt://localhost:7687` (for local) or `bolt://host.docker.internal:7687` (for MCP in Docker)
4. **Update your .env file**:
```bash
NEO4J_URI=bolt://localhost:7687
NEO4J_USER=neo4j
NEO4J_PASSWORD=password
USE_KNOWLEDGE_GRAPH=true
```
That's it! Neo4j is now running and ready for knowledge graph functionality.
📖 **For detailed instructions, troubleshooting, and advanced configurations**, see the [Neo4j Docker Setup Guide](neo4j/docker-neo4j/README.md).
### Manual Neo4j Installation
Alternatively, install Neo4j directly:
1. **Install Neo4j Desktop**: Download from [neo4j.com/download](https://neo4j.com/download/)
2. **Create a new database**:
- Open Neo4j Desktop
- Create a new project and database
- Set a password for the `neo4j` user
- Start the database
3. **Note your connection details**:
- URI: `bolt://localhost:7687` (default)
- Username: `neo4j` (default)
- Password: Whatever you set during creation
## Configuration
Create a `.env` file in the project root with the following variables:
```
# MCP Server Configuration
HOST=0.0.0.0
PORT=8051
TRANSPORT=sse
# OpenAI API Configuration (for embeddings)
OPENAI_API_KEY=your_openai_api_key
# OpenRouter API Configuration (for LLM chat completions)
OPENROUTER_API_KEY=your_openrouter_api_key
# LLM for summaries and contextual embeddings (OpenRouter format)
# Use OpenRouter model format like: openai/gpt-4.1-nano, anthropic/claude-3-haiku, etc.
MODEL_CHOICE=openai/gpt-4.1-nano
# RAG Strategies (set to "true" or "false", default to "false")
USE_CONTEXTUAL_EMBEDDINGS=false
USE_HYBRID_SEARCH=false
USE_AGENTIC_RAG=false
USE_RERANKING=false
USE_KNOWLEDGE_GRAPH=false
# Supabase Configuration
SUPABASE_URL=your_supabase_project_url
SUPABASE_SERVICE_KEY=your_supabase_service_key
# Neo4j Configuration (required for knowledge graph functionality)
# Use bolt://localhost:7687 for local Neo4j installation
# Use bolt://host.docker.internal:7687 if MCP server is in Docker
NEO4J_URI=bolt://localhost:7687
NEO4J_USER=neo4j
NEO4J_PASSWORD=password
```
### OpenRouter Integration
This MCP server now uses **OpenRouter** for LLM chat completions while maintaining OpenAI for embeddings. This provides several advantages:
- **Model Flexibility**: Access to 200+ models from multiple providers (OpenAI, Anthropic, Google, Meta, etc.)
- **Cost Optimization**: Choose the most cost-effective model for your use case
- **Reliability**: OpenRouter's unified API with automatic failover
- **Performance**: Optimized routing to the fastest available endpoint
#### Supported Models
Popular model choices for the `MODEL_CHOICE` environment variable:
- **OpenAI**: `openai/gpt-4.1-nano`, `openai/gpt-4.1-mini`, `openai/gpt-4o`
- **Anthropic**: `anthropic/claude-3-haiku`, `anthropic/claude-3-sonnet`
- **Google**: `google/gemini-flash-1.5`, `google/gemini-pro-1.5`
- **Meta**: `meta-llama/llama-3.1-8b-instruct`, `meta-llama/llama-3.1-70b-instruct`
- **DeepSeek**: `deepseek/deepseek-chat`, `deepseek/deepseek-coder`
For the full list, visit [OpenRouter Models](https://openrouter.ai/models).
#### Configuration Notes
- **OpenAI API Key**: Still required for embeddings (`text-embedding-3-small`)
- **OpenRouter API Key**: Required for all LLM chat completions
- **Model Format**: Use OpenRouter's model format (`provider/model-name`)
- **Fallback**: If OpenRouter is unavailable, the system will log errors but continue with reduced functionality
### RAG Strategy Options
The Crawl4AI RAG MCP server supports four powerful RAG strategies that can be enabled independently:
#### 1. **USE_CONTEXTUAL_EMBEDDINGS**
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.
- **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.
- **Trade-offs**: Slower indexing due to LLM calls for each chunk, but significantly better retrieval accuracy.
- **Cost**: Additional LLM API calls during indexing.
#### 2. **USE_HYBRID_SEARCH**
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.
- **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.
- **Trade-offs**: Slightly slower search queries but more robust results, especially for technical content.
- **Cost**: No additional API costs, just computational overhead.
#### 3. **USE_AGENTIC_RAG**
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.
- **When to use**: Essential for AI coding assistants that need to find specific code examples, implementation patterns, or usage examples from documentation.
- **Trade-offs**: Significantly slower crawling due to code extraction and summarization, requires more storage space.
- **Cost**: Additional LLM API calls for summarizing each code example.
- **Benefits**: Provides a dedicated `search_code_examples` tool that AI agents can use to find specific code implementations.
#### 4. **USE_RERANKING**
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.
- **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.
- **Trade-offs**: Adds ~100-200ms to search queries depending on result count, but significantly improves result ordering.
- **Cost**: No additional API costs - uses a local model that runs on CPU.
- **Benefits**: Better result relevance, especially for complex queries. Works with both regular RAG search and code example search.
#### 5. **USE_KNOWLEDGE_GRAPH**
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.
- **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.
- **Trade-offs**: Requires Neo4j setup and additional dependencies. Repository parsing can be slow for large codebases, and validation requires repositories to be pre-indexed.
- **Cost**: No additional API costs for validation, but requires Neo4j infrastructure (can use free local installation, included Docker setup, or cloud AuraDB).
- **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.
You can now tell the AI coding assistant to add a Python GitHub repository to the knowledge graph like:
"Add https://github.com/pydantic/pydantic-ai.git to the knowledge graph"
Make sure the repo URL ends with .git.
You can also have the AI coding assistant check for hallucinations with scripts it just created, or you can manually run the command:
```
python knowledge_graphs/ai_hallucination_detector.py [full path to your script to analyze]
```
### Recommended Configurations
**For general documentation RAG:**
```
USE_CONTEXTUAL_EMBEDDINGS=false
USE_HYBRID_SEARCH=true
USE_AGENTIC_RAG=false
USE_RERANKING=true
```
**For AI coding assistant with code examples:**
```
USE_CONTEXTUAL_EMBEDDINGS=true
USE_HYBRID_SEARCH=true
USE_AGENTIC_RAG=true
USE_RERANKING=true
USE_KNOWLEDGE_GRAPH=false
```
**For AI coding assistant with hallucination detection:**
```
USE_CONTEXTUAL_EMBEDDINGS=true
USE_HYBRID_SEARCH=true
USE_AGENTIC_RAG=true
USE_RERANKING=true
USE_KNOWLEDGE_GRAPH=true
```
**For fast, basic RAG:**
```
USE_CONTEXTUAL_EMBEDDINGS=false
USE_HYBRID_SEARCH=true
USE_AGENTIC_RAG=false
USE_RERANKING=false
USE_KNOWLEDGE_GRAPH=false
```
## Running the Server
### Using Docker
```bash
docker run --env-file .env -p 8051:8051 mcp/crawl4ai-rag
```
### Using Python
```bash
uv run src/crawl4ai_mcp.py
```
The server will start and listen on the configured host and port.
## Integration with MCP Clients
### SSE Configuration
Once you have the server running with SSE transport, you can connect to it using this configuration:
```json
{
"mcpServers": {
"crawl4ai-rag": {
"transport": "sse",
"url": "http://localhost:8051/sse"
}
}
}
```
> **Note for Windsurf users**: Use `serverUrl` instead of `url` in your configuration:
> ```json
> {
> "mcpServers": {
> "crawl4ai-rag": {
> "transport": "sse",
> "serverUrl": "http://localhost:8051/sse"
> }
> }
> }
> ```
>
> **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!
> **Note for Claude Code users**:
```
claude mcp add-json crawl4ai-rag '{"type":"sse","url":"http://localhost:8051/sse"}' --scope user
```
### Stdio Configuration
Add this server to your MCP configuration for Claude Desktop, Windsurf, or any other MCP client:
```json
{
"mcpServers": {
"crawl4ai-rag": {
"command": "python",
"args": ["path/to/crawl4ai-mcp/src/crawl4ai_mcp.py"],
"env": {
"TRANSPORT": "stdio",
"OPENAI_API_KEY": "your_openai_api_key",
"OPENROUTER_API_KEY": "your_openrouter_api_key",
"SUPABASE_URL": "your_supabase_url",
"SUPABASE_SERVICE_KEY": "your_supabase_service_key",
"USE_KNOWLEDGE_GRAPH": "false",
"NEO4J_URI": "bolt://localhost:7687",
"NEO4J_USER": "neo4j",
"NEO4J_PASSWORD": "password"
}
}
}
}
```
### Docker with Stdio Configuration
```json
{
"mcpServers": {
"crawl4ai-rag": {
"command": "docker",
"args": ["run", "--rm", "-i",
"-e", "TRANSPORT",
"-e", "OPENAI_API_KEY",
"-e", "OPENROUTER_API_KEY",
"-e", "SUPABASE_URL",
"-e", "SUPABASE_SERVICE_KEY",
"-e", "USE_KNOWLEDGE_GRAPH",
"-e", "NEO4J_URI",
"-e", "NEO4J_USER",
"-e", "NEO4J_PASSWORD",
"mcp/crawl4ai"],
"env": {
"TRANSPORT": "stdio",
"OPENAI_API_KEY": "your_openai_api_key",
"OPENROUTER_API_KEY": "your_openrouter_api_key",
"SUPABASE_URL": "your_supabase_url",
"SUPABASE_SERVICE_KEY": "your_supabase_service_key",
"USE_KNOWLEDGE_GRAPH": "false",
"NEO4J_URI": "bolt://localhost:7687",
"NEO4J_USER": "neo4j",
"NEO4J_PASSWORD": "password"
}
}
}
}
```
> **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.
## Knowledge Graph Architecture
The knowledge graph system stores repository code structure in Neo4j with the following components:
### Core Components (`knowledge_graphs/` folder):
- **`parse_repo_into_neo4j.py`**: Clones and analyzes GitHub repositories, extracting Python classes, methods, functions, and imports into Neo4j nodes and relationships
- **`ai_script_analyzer.py`**: Parses Python scripts using AST to extract imports, class instantiations, method calls, and function usage
- **`knowledge_graph_validator.py`**: Validates AI-generated code against the knowledge graph to detect hallucinations (non-existent methods, incorrect parameters, etc.)
- **`hallucination_reporter.py`**: Generates comprehensive reports about detected hallucinations with confidence scores and recommendations
- **`query_knowledge_graph.py`**: Interactive CLI tool for exploring the knowledge graph (functionality now integrated into MCP tools)
### Knowledge Graph Schema:
The Neo4j database stores code structure as:
**Nodes:**
- `Repository`: GitHub repositories
- `File`: Python files within repositories
- `Class`: Python classes with methods and attributes
- `Method`: Class methods with parameter information
- `Function`: Standalone functions
- `Attribute`: Class attributes
**Relationships:**
- `Repository` -[:CONTAINS]-> `File`
- `File` -[:DEFINES]-> `Class`
- `File` -[:DEFINES]-> `Function`
- `Class` -[:HAS_METHOD]-> `Method`
- `Class` -[:HAS_ATTRIBUTE]-> `Attribute`
### Workflow:
1. **Repository Parsing**: Use `parse_github_repository` tool to clone and analyze open-source repositories
2. **Code Validation**: Use `check_ai_script_hallucinations` tool to validate AI-generated Python scripts
3. **Knowledge Exploration**: Use `query_knowledge_graph` tool to explore available repositories, classes, and methods
## Building Your Own Server
This implementation provides a foundation for building more complex MCP servers with web crawling capabilities. To build your own:
1. Add your own tools by creating methods with the `@mcp.tool()` decorator
2. Create your own lifespan function to add your own dependencies
3. Modify the `utils.py` file for any helper functions you need
4. Extend the crawling capabilities by adding more specialized crawlers
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/ConfsReplaced.conf:
--------------------------------------------------------------------------------
```
#dbms.memory.pagecache.size=1g
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/ReadConf.conf:
--------------------------------------------------------------------------------
```
dbms.memory.heap.max_size=512m
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/ConfsNotOverridden.conf:
--------------------------------------------------------------------------------
```
dbms.memory.pagecache.size=1024M
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/EnvVarsOverride.conf:
--------------------------------------------------------------------------------
```
dbms.memory.pagecache.size=1000m
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/ConfsReplaced.conf:
--------------------------------------------------------------------------------
```
#server.memory.pagecache.size=1g
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/ReadConf.conf:
--------------------------------------------------------------------------------
```
server.memory.heap.max_size=512m
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/ConfsNotOverridden.conf:
--------------------------------------------------------------------------------
```
server.memory.pagecache.size=1024M
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/EnvVarsOverride.conf:
--------------------------------------------------------------------------------
```
server.memory.pagecache.size=1000m
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/ExtendedConf.conf:
--------------------------------------------------------------------------------
```
dbms.logs.gc.rotation.keep_number=$(expr 2 * 10)
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/EnterpriseOnlyNotOverwritten.conf:
--------------------------------------------------------------------------------
```
server.cluster.advertised_address=localhost:6060
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/ExtendedConf.conf:
--------------------------------------------------------------------------------
```
server.logs.gc.rotation.keep_number=$(expr 2 * 10)
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/EnterpriseOnlyNotOverwritten.conf:
--------------------------------------------------------------------------------
```
causal_clustering.transaction_advertised_address=localhost:6060
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/JvmAdditionalNotOverridden.conf:
--------------------------------------------------------------------------------
```
dbms.jvm.additional=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/NoNewline.conf:
--------------------------------------------------------------------------------
```
# a configuration file without a trailing newline
dbms.memory.pagecache.size=1000.00MiB
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/JvmAdditionalNotOverridden.conf:
--------------------------------------------------------------------------------
```
server.jvm.additional=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/NoNewline.conf:
--------------------------------------------------------------------------------
```
# a configuration file without a trailing newline
server.memory.pagecache.size=1000.00MiB
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/before50/InvalidExtendedConf.conf:
--------------------------------------------------------------------------------
```
dbms.logs.gc.rotation.keep_number=$(bash -c '>&2 echo "this is an error message from inside neo4j config command expansion" && exit 1')
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/confs/InvalidExtendedConf.conf:
--------------------------------------------------------------------------------
```
server.logs.gc.rotation.keep_number=$(bash -c '>&2 echo "this is an error message from inside neo4j config command expansion" && exit 1')
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
```
log4j.rootLogger=INFO, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/dockersecrets/simple-container-compose.yml:
--------------------------------------------------------------------------------
```yaml
services:
simplecontainer:
image: ${NEO4J_IMAGE}
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_AUTH=neo4j/simplecontainerpassword
- NEO4J_DEBUG=true
volumes:
- ${HOST_ROOT}/neo4j/data:/data
- ${HOST_ROOT}/neo4j/logs:/logs
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/dockersecrets/simple-container-compose-with-external-file-var.yml:
--------------------------------------------------------------------------------
```yaml
services:
simplecontainer:
image: ${NEO4J_IMAGE}
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_AUTH=neo4j/simplecontainerpassword
- NEO4J_DEBUG=true
- CERTIFICATE_FILE="CERTIFICATE CONTENTS"
volumes:
- ${HOST_ROOT}/neo4j/data:/data
- ${HOST_ROOT}/neo4j/logs:/logs
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/generate-stub-plugin/settings.gradle.kts:
--------------------------------------------------------------------------------
```kotlin
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user manual at https://docs.gradle.org/7.6/userguide/multi_project_builds.html
*/
rootProject.name = "myPlugin"
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/dockersecrets/container-compose-with-secrets.yml:
--------------------------------------------------------------------------------
```yaml
services:
secretscontainer:
image: ${NEO4J_IMAGE}
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_AUTH_FILE=/run/secrets/neo4j_auth_file
- NEO4J_DEBUG=true
volumes:
- ${HOST_ROOT}/neo4j/data:/data
- ${HOST_ROOT}/neo4j/logs:/logs
secrets:
- neo4j_auth_file
secrets:
neo4j_auth_file:
file: ./neo4j_auth.txt
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/dockersecrets/container-compose-with-incorrect-secrets.yml:
--------------------------------------------------------------------------------
```yaml
services:
secretscontainer:
image: ${NEO4J_IMAGE}
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_AUTH_FILE="File contents instead of a file path"
- NEO4J_DEBUG=true
volumes:
- ${HOST_ROOT}/neo4j/data:/data
- ${HOST_ROOT}/neo4j/logs:/logs
secrets:
- neo4j_auth_file
secrets:
neo4j_auth_file:
file: ./neo4j_auth.txt
```
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
```toml
[project]
name = "crawl4ai-mcp"
version = "0.1.0"
description = "MCP server for integrating web crawling and RAG into AI agents and AI coding assistants"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"crawl4ai==0.6.2",
"mcp==1.7.1",
"supabase==2.15.1",
"openai==1.71.0",
"dotenv==0.9.9",
"sentence-transformers>=4.1.0",
"neo4j>=5.28.1",
"playwright>=1.40.0",
]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/generate-stub-plugin/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM gradle:7-jdk11
WORKDIR /testplugin
COPY ./*.kts ./ExampleNeo4jPlugin.java /testplugin/
RUN mkdir -p /testplugin/src/main/java/testplugins/ && \
mkdir -p /testplugin/build && \
ln -s -T /output /testplugin/build/libs && \
mv /testplugin/ExampleNeo4jPlugin.java /testplugin/src/main/java/testplugins/ && \
chmod a+rw -R /testplugin
ENV NEO4JVERSION=4.4.38
VOLUME /output
CMD gradle jar -Pversion=$NEO4JVERSION
```
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM python:3.12-slim
ARG PORT=8051
WORKDIR /app
# Install system dependencies including git
RUN apt-get update && apt-get install -y \
git \
&& rm -rf /var/lib/apt/lists/*
# Install uv
RUN pip install uv
# Copy the MCP server files
COPY . .
# Install packages directly to the system (no virtual environment)
# Combining commands to reduce Docker layers
RUN uv pip install --system -e . && \
crawl4ai-setup
EXPOSE ${PORT}
# Command to run the MCP server
CMD ["python", "src/crawl4ai_mcp.py"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/utils/Network.java:
--------------------------------------------------------------------------------
```java
package com.neo4j.docker.utils;
import java.io.IOException;
import java.net.ServerSocket;
import static java.lang.String.format;
public class Network
{
public static int getUniqueHostPort() throws IOException
{
try ( ServerSocket socket = new ServerSocket( 0 ) )
{
socket.setReuseAddress( true );
socket.close();
return socket.getLocalPort();
}
catch ( IOException e )
{
throw new IOException( format( "Could not get a unique port : ", e.getMessage() ) );
}
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/dockersecrets/container-compose-with-secrets-override.yml:
--------------------------------------------------------------------------------
```yaml
services:
secretsoverridecontainer:
image: ${NEO4J_IMAGE}
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_dbms_memory_pagecache_size_FILE=/run/secrets/neo4j_dbms_memory_pagecache_size_file
- NEO4J_dbms_memory_pagecache_size=10M
- NEO4J_DEBUG=true
- NEO4J_AUTH=neo4j/secretsoverridecontainerpassword
volumes:
- ${HOST_ROOT}/neo4j/data:/data
- ${HOST_ROOT}/neo4j/logs:/logs
secrets:
- neo4j_dbms_memory_pagecache_size_file
secrets:
neo4j_dbms_memory_pagecache_size_file:
file: ./neo4j_pagecache.txt
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/generate-stub-plugin/build.gradle.kts:
--------------------------------------------------------------------------------
```kotlin
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java library project to get you started.
* For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
* User Manual available at https://docs.gradle.org/7.6/userguide/building_java_projects.html
*/
//version = "4.3.0"
plugins {
// Apply the java-library plugin for API and implementation separation.
`java-library`
}
repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
}
dependencies {
api("org.neo4j:neo4j:$version")
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/coredb/plugins/Neo4jPluginEnv.java:
--------------------------------------------------------------------------------
```java
package com.neo4j.docker.coredb.plugins;
import com.neo4j.docker.utils.Neo4jVersion;
import com.neo4j.docker.utils.TestSettings;
public class Neo4jPluginEnv
{
public static final String PLUGIN_ENV_4X = "NEO4JLABS_PLUGINS";
public static final String PLUGIN_ENV_5X = "NEO4J_PLUGINS";
public static String get( )
{
return get(TestSettings.NEO4J_VERSION);
}
public static String get( Neo4jVersion version )
{
if( version.isAtLeastVersion( Neo4jVersion.NEO4J_VERSION_500 ) )
{
return PLUGIN_ENV_5X;
}
else return PLUGIN_ENV_4X;
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/coredb/configurations/Setting.java:
--------------------------------------------------------------------------------
```java
package com.neo4j.docker.coredb.configurations;
public enum Setting
{
APOC_EXPORT_FILE_ENABLED,
BACKUP_ENABLED,
BACKUP_LISTEN_ADDRESS,
BROWSER_ALLOW_OUTGOING_CONNECTIONS,
CLUSTER_DISCOVERY_ADDRESS,
CLUSTER_RAFT_ADDRESS,
CLUSTER_ROUTING_ADDRESS,
CLUSTER_TRANSACTION_ADDRESS,
DEFAULT_LISTEN_ADDRESS,
DIRECTORIES_DATA,
DIRECTORIES_LOGS,
DIRECTORIES_METRICS,
JVM_ADDITIONAL,
LOGS_GC_ROTATION_KEEPNUMBER,
MEMORY_HEAP_INITIALSIZE,
MEMORY_HEAP_MAXSIZE,
MEMORY_PAGECACHE_SIZE,
MINIMUM_PASSWORD_LENGTH,
SECURITY_PROCEDURES_UNRESTRICTED,
TXLOG_RETENTION_POLICY
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.0/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM openjdk:8-jre
ENV NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%%
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
COPY ./local-package/* /tmp/
RUN curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum --check --quiet - \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* /var/lib/neo4j \
&& rm ${NEO4J_TARBALL}
ENV PATH /var/lib/neo4j/bin:$PATH
WORKDIR /var/lib/neo4j
RUN mv data /data \
&& ln --symbolic /data
VOLUME /data
COPY docker-entrypoint.sh /docker-entrypoint.sh
EXPOSE 7474 7473 7687
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["neo4j"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/2.3/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM openjdk:8-jre
RUN apt-get update --quiet --quiet \
&& apt-get install --quiet --quiet --no-install-recommends lsof \
&& rm -rf /var/lib/apt/lists/*
ENV NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%%
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
COPY ./local-package/* /tmp/
RUN curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum --check --quiet - \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* /var/lib/neo4j \
&& rm ${NEO4J_TARBALL}
ENV PATH /var/lib/neo4j/bin:$PATH
WORKDIR /var/lib/neo4j
RUN mv data /data \
&& ln --symbolic /data
VOLUME /data
COPY docker-entrypoint.sh /docker-entrypoint.sh
EXPOSE 7474 7473
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["neo4j"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/utils/HostFileHttpHandler.java:
--------------------------------------------------------------------------------
```java
package com.neo4j.docker.utils;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.nio.file.Files;
/**
* HttpHandler that responds to all http requests with the given file from the file system
*/
public class HostFileHttpHandler implements HttpHandler
{
private final File file;
private final String contentType;
public HostFileHttpHandler( File fileToDownload, String contentType )
{
this.file = fileToDownload;
this.contentType = contentType;
}
@Override
public void handle( HttpExchange exchange ) throws IOException
{
exchange.getResponseHeaders().add( "Content-Type", contentType );
exchange.sendResponseHeaders( HttpURLConnection.HTTP_OK, file.length() );
Files.copy( this.file.toPath(), exchange.getResponseBody() );
exchange.close();
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
```markdown
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: jennyowen
---
## Guidelines
Please note that GitHub issues are only meant for bug reports/feature requests.
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.
To help us understand your issue, please specify important details, primarily:
- **Steps to reproduce**. *Not including reproduction steps will mean your bug will take considerably longer to investigate and fix. Please don't skip this*.
- Expected behaviour
- Actual behaviour
- Neo4j image tag being used, eg `neo4j:latest`, `neo4j:enterprise-3.5` etc
- The output of the `docker version` command
- Operating system: (for example Windows 95/Ubuntu 16.04)
Additionally, include (as appropriate) error messages, log-files, stacktraces, and other debug output.
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/utils/SetContainerUser.java:
--------------------------------------------------------------------------------
```java
package com.neo4j.docker.utils;
import com.github.dockerjava.api.command.CreateContainerCmd;
import com.sun.security.auth.module.UnixSystem;
import org.testcontainers.containers.GenericContainer;
import java.util.function.Consumer;
public class SetContainerUser
{
public static void nonRootUser( GenericContainer container )
{
container.withCreateContainerCmdModifier( (Consumer<CreateContainerCmd>) cmd -> cmd.withUser( getNonRootUserString() ) );
}
public static String getNonRootUserString()
{
// check if the non root user environment variable is set, if so use that. Otherwise use current user.
String user = System.getenv( "NON_ROOT_USER_ID" );
if(user == null)
{
return getCurrentlyRunningUser();
}
else
{
return user;
}
}
private static String getCurrentlyRunningUser()
{
UnixSystem fs = new UnixSystem();
return fs.getUid() + ":" + fs.getGid();
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/common/utilities.sh:
--------------------------------------------------------------------------------
```bash
function running_as_root
{
test "$(id -u)" = "0"
}
function secure_mode_enabled
{
test "${SECURE_FILE_PERMISSIONS:=no}" = "yes"
}
function debugging_enabled
{
test "${NEO4J_DEBUG+yes}" = "yes"
}
function debug_msg
{
if debugging_enabled; then
echo "$@"
fi
}
function containsElement
{
local e match="$1"
shift
for e; do [[ "$e" == "$match" ]] && return 0; done
return 1
}
function is_writable
{
${exec_cmd} test -w "${1}"
}
function print_permissions_advice_and_fail
{
local _directory=${1}
local _userid=${2}
local _groupid=${3}
echo >&2 "
Folder ${_directory} is not accessible for user: ${_userid} or group ${_groupid}. This is commonly a file permissions issue on the mounted folder.
Hints to solve the issue:
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.
2) Pass the folder owner's user ID and group ID to docker run, so that docker runs as that user.
If the folder is owned by the current user, this can be done by adding this flag to your docker run command:
--user=\$(id -u):\$(id -g)
"
exit 1
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.1/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM adoptopenjdk/openjdk8:alpine-jre
RUN addgroup -S neo4j && adduser -S -H -h /var/lib/neo4j -G neo4j neo4j
ENV NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%% \
NEO4J_HOME="/var/lib/neo4j"
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
COPY ./local-package/* /tmp/
RUN apk add --no-cache --quiet \
bash \
curl \
tini \
su-exec \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -csw - \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* "${NEO4J_HOME}" \
&& rm ${NEO4J_TARBALL} \
&& mv "${NEO4J_HOME}"/data /data \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& mv "${NEO4J_HOME}"/logs /logs \
&& chown -R neo4j:neo4j /logs \
&& chmod -R 777 /logs \
&& chown -R neo4j:neo4j "${NEO4J_HOME}" \
&& chmod -R 777 "${NEO4J_HOME}" \
&& ln -s /data "${NEO4J_HOME}"/data \
&& ln -s /logs "${NEO4J_HOME}"/logs \
&& apk del curl
ENV PATH "${NEO4J_HOME}"/bin:$PATH
WORKDIR "${NEO4J_HOME}"
VOLUME /data /logs
COPY docker-entrypoint.sh /docker-entrypoint.sh
EXPOSE 7474 7473 7687
ENTRYPOINT ["/sbin/tini", "-g", "--", "/docker-entrypoint.sh"]
CMD ["neo4j"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.2/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM adoptopenjdk/openjdk8:alpine-jre
RUN addgroup -S neo4j && adduser -S -H -h /var/lib/neo4j -G neo4j neo4j
ENV NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%% \
NEO4J_HOME="/var/lib/neo4j"
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
COPY ./local-package/* /tmp/
RUN apk add --no-cache --quiet \
bash \
curl \
tini \
su-exec \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -csw - \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* "${NEO4J_HOME}" \
&& rm ${NEO4J_TARBALL} \
&& mv "${NEO4J_HOME}"/data /data \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& mv "${NEO4J_HOME}"/logs /logs \
&& chown -R neo4j:neo4j /logs \
&& chmod -R 777 /logs \
&& chown -R neo4j:neo4j "${NEO4J_HOME}" \
&& chmod -R 777 "${NEO4J_HOME}" \
&& ln -s /data "${NEO4J_HOME}"/data \
&& ln -s /logs "${NEO4J_HOME}"/logs \
&& apk del curl
ENV PATH "${NEO4J_HOME}"/bin:$PATH
WORKDIR "${NEO4J_HOME}"
VOLUME /data /logs
COPY docker-entrypoint.sh /docker-entrypoint.sh
EXPOSE 7474 7473 7687
ENTRYPOINT ["/sbin/tini", "-g", "--", "/docker-entrypoint.sh"]
CMD ["neo4j"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.0/neo4j-admin/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM %%NEO4J_BASE_IMAGE%%
ENV NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%% \
NEO4J_EDITION=%%NEO4J_EDITION%% \
NEO4J_HOME="/var/lib/neo4j"
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
COPY ./local-package/* /tmp/
RUN apt update \
&& apt install -y curl gosu procps \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* "${NEO4J_HOME}" \
&& rm ${NEO4J_TARBALL} \
&& mv "${NEO4J_HOME}"/data /data \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& mkdir -p /backups \
&& chown -R neo4j:neo4j /backups \
&& chmod -R 777 /backups \
&& chown -R neo4j:neo4j "${NEO4J_HOME}" \
&& chmod -R 777 "${NEO4J_HOME}" \
&& ln -s /data "${NEO4J_HOME}"/data \
&& rm -rf /tmp/* \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get -y purge --auto-remove curl
ENV PATH "${NEO4J_HOME}"/bin:$PATH
VOLUME /data /backups
WORKDIR "${NEO4J_HOME}"
COPY docker-entrypoint.sh /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["neo4j-admin"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.1/neo4j-admin/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM %%NEO4J_BASE_IMAGE%%
ENV NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%% \
NEO4J_EDITION=%%NEO4J_EDITION%% \
NEO4J_HOME="/var/lib/neo4j"
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
COPY ./local-package/* /startup/
RUN apt update \
&& apt install -y curl gosu procps \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* "${NEO4J_HOME}" \
&& rm ${NEO4J_TARBALL} \
&& mv "${NEO4J_HOME}"/data /data \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& mkdir -p /backups \
&& chown -R neo4j:neo4j /backups \
&& chmod -R 777 /backups \
&& chown -R neo4j:neo4j "${NEO4J_HOME}" \
&& chmod -R 777 "${NEO4J_HOME}" \
&& ln -s /data "${NEO4J_HOME}"/data \
&& rm -rf /tmp/* \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get -y purge --auto-remove curl
ENV PATH "${NEO4J_HOME}"/bin:$PATH
VOLUME /data /backups
WORKDIR "${NEO4J_HOME}"
COPY docker-entrypoint.sh /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["neo4j-admin"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/calver/coredb/neo4j-plugins.json:
--------------------------------------------------------------------------------
```json
{
"apoc-extended": {
"versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "apoc.*"
}
},
"apoc": {
"location": "/var/lib/neo4j/labs/apoc-*-core.jar",
"versions": "https://neo4j.github.io/apoc/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "apoc.*"
}
},
"bloom": {
"location": "/var/lib/neo4j/products/bloom-plugin-*.jar",
"versions": "https://bloom-plugins.s3.eu-west-2.amazonaws.com/versions.json",
"properties": {
"server.unmanaged_extension_classes": "com.neo4j.bloom.server=/browser/bloom",
"dbms.security.procedures.unrestricted": "bloom.*",
"dbms.bloom.license_file": "/licenses/bloom.license"
}
},
"graph-data-science": {
"versions": "https://graphdatascience.ninja/versions.json",
"location": "/var/lib/neo4j/products/neo4j-graph-data-science-*.jar",
"properties": {
"dbms.security.procedures.unrestricted": "gds.*"
}
},
"genai": {
"location": "/var/lib/neo4j/products/neo4j-genai-plugin-*.jar",
"properties": {
"dbms.security.procedures.unrestricted": "genai.*"
}
},
"_testing": {
"versions": "http://host.testcontainers.internal:3000/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "com.neo4j.docker.neo4jserver.plugins.*"
}
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.5/neo4j-admin/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM debian:bullseye-slim
ENV JAVA_HOME=/opt/java/openjdk
COPY --from=eclipse-temurin:8 $JAVA_HOME $JAVA_HOME
ENV PATH="${JAVA_HOME}/bin:${PATH}" \
NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%% \
NEO4J_EDITION=%%NEO4J_EDITION%% \
NEO4J_HOME="/var/lib/neo4j"
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
COPY ./local-package/* /startup/
RUN apt update \
&& apt install -y curl procps \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* "${NEO4J_HOME}" \
&& rm ${NEO4J_TARBALL} \
&& rm ${NEO4J_HOME}/bin/neo4j \
&& mv "${NEO4J_HOME}"/data /data \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& mkdir -p /backups \
&& chown -R neo4j:neo4j /backups \
&& chmod -R 777 /backups \
&& chown -R neo4j:neo4j "${NEO4J_HOME}" \
&& chmod -R 777 "${NEO4J_HOME}" \
&& ln -s /data "${NEO4J_HOME}"/data \
&& ln -s /startup/docker-entrypoint.sh /docker-entrypoint.sh \
&& rm -rf /tmp/* \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get -y purge --auto-remove curl
ENV PATH "${NEO4J_HOME}"/bin:$PATH
VOLUME /data /backups
WORKDIR "${NEO4J_HOME}"
ENTRYPOINT ["/startup/docker-entrypoint.sh"]
CMD ["neo4j-admin"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.2/neo4j-admin/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM debian:bullseye-slim
ENV JAVA_HOME=/opt/java/openjdk
COPY --from=eclipse-temurin:11 $JAVA_HOME $JAVA_HOME
ENV PATH="${JAVA_HOME}/bin:${PATH}" \
NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%% \
NEO4J_EDITION=%%NEO4J_EDITION%% \
NEO4J_HOME="/var/lib/neo4j"
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
COPY ./local-package/* /startup/
RUN apt update \
&& apt install -y curl procps \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* "${NEO4J_HOME}" \
&& rm ${NEO4J_TARBALL} \
&& rm ${NEO4J_HOME}/bin/neo4j \
&& mv "${NEO4J_HOME}"/data /data \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& mkdir -p /backups \
&& chown -R neo4j:neo4j /backups \
&& chmod -R 777 /backups \
&& chown -R neo4j:neo4j "${NEO4J_HOME}" \
&& chmod -R 777 "${NEO4J_HOME}" \
&& ln -s /data "${NEO4J_HOME}"/data \
&& ln -s /startup/docker-entrypoint.sh /docker-entrypoint.sh \
&& rm -rf /tmp/* \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get -y purge --auto-remove curl
ENV PATH "${NEO4J_HOME}"/bin:$PATH
VOLUME /data /backups
WORKDIR "${NEO4J_HOME}"
ENTRYPOINT ["/startup/docker-entrypoint.sh"]
CMD ["neo4j-admin"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.3/neo4j-admin/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM debian:bullseye-slim
ENV JAVA_HOME=/opt/java/openjdk
COPY --from=eclipse-temurin:11 $JAVA_HOME $JAVA_HOME
ENV PATH="${JAVA_HOME}/bin:${PATH}" \
NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%% \
NEO4J_EDITION=%%NEO4J_EDITION%% \
NEO4J_HOME="/var/lib/neo4j"
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
COPY ./local-package/* /startup/
RUN apt update \
&& apt install -y curl procps \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* "${NEO4J_HOME}" \
&& rm ${NEO4J_TARBALL} \
&& rm ${NEO4J_HOME}/bin/neo4j \
&& mv "${NEO4J_HOME}"/data /data \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& mkdir -p /backups \
&& chown -R neo4j:neo4j /backups \
&& chmod -R 777 /backups \
&& chown -R neo4j:neo4j "${NEO4J_HOME}" \
&& chmod -R 777 "${NEO4J_HOME}" \
&& ln -s /data "${NEO4J_HOME}"/data \
&& ln -s /startup/docker-entrypoint.sh /docker-entrypoint.sh \
&& rm -rf /tmp/* \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get -y purge --auto-remove curl
ENV PATH "${NEO4J_HOME}"/bin:$PATH
VOLUME /data /backups
WORKDIR "${NEO4J_HOME}"
ENTRYPOINT ["/startup/docker-entrypoint.sh"]
CMD ["neo4j-admin"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.5/coredb/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM debian:bullseye-slim
ENV JAVA_HOME=/opt/java/openjdk
COPY --from=eclipse-temurin:8 $JAVA_HOME $JAVA_HOME
ENV PATH="${JAVA_HOME}/bin:${PATH}" \
NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%% \
NEO4J_EDITION=%%NEO4J_EDITION%% \
NEO4J_HOME="/var/lib/neo4j"
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
RUN addgroup --system neo4j && adduser --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
COPY ./local-package/* /startup/
RUN apt update \
&& apt install -y curl gosu jq tini wget \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* "${NEO4J_HOME}" \
&& rm ${NEO4J_TARBALL} \
&& mv "${NEO4J_HOME}"/data /data \
&& mv "${NEO4J_HOME}"/logs /logs \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& chown -R neo4j:neo4j /logs \
&& chmod -R 777 /logs \
&& chown -R neo4j:neo4j "${NEO4J_HOME}" \
&& chmod -R 777 "${NEO4J_HOME}" \
&& ln -s /data "${NEO4J_HOME}"/data \
&& ln -s /logs "${NEO4J_HOME}"/logs \
&& ln -s /startup/docker-entrypoint.sh /docker-entrypoint.sh \
&& apt-get -y purge --auto-remove curl \
&& rm -rf /var/lib/apt/lists/*
ENV PATH "${NEO4J_HOME}"/bin:$PATH
WORKDIR "${NEO4J_HOME}"
VOLUME /data /logs
EXPOSE 7474 7473 7687
ENTRYPOINT ["tini", "-g", "--", "/startup/docker-entrypoint.sh"]
CMD ["neo4j"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.1/coredb/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM debian:bullseye-slim
ENV JAVA_HOME=/opt/java/openjdk
COPY --from=eclipse-temurin:11 $JAVA_HOME $JAVA_HOME
ENV PATH="${JAVA_HOME}/bin:${PATH}" \
NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%% \
NEO4J_EDITION=%%NEO4J_EDITION%% \
NEO4J_HOME="/var/lib/neo4j"
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
COPY ./local-package/* /startup/
RUN apt update \
&& apt install -y curl wget gosu jq tini \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* "${NEO4J_HOME}" \
&& rm ${NEO4J_TARBALL} \
&& mv "${NEO4J_HOME}"/data /data \
&& mv "${NEO4J_HOME}"/logs /logs \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& chown -R neo4j:neo4j /logs \
&& chmod -R 777 /logs \
&& chown -R neo4j:neo4j "${NEO4J_HOME}" \
&& chmod -R 777 "${NEO4J_HOME}" \
&& ln -s /data "${NEO4J_HOME}"/data \
&& ln -s /logs "${NEO4J_HOME}"/logs \
&& ln -s /startup/docker-entrypoint.sh /docker-entrypoint.sh \
&& apt-get -y purge --auto-remove curl \
&& rm -rf /var/lib/apt/lists/*
ENV PATH "${NEO4J_HOME}"/bin:$PATH
WORKDIR "${NEO4J_HOME}"
VOLUME /data /logs
EXPOSE 7474 7473 7687
ENTRYPOINT ["tini", "-g", "--", "/startup/docker-entrypoint.sh"]
CMD ["neo4j"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.2/coredb/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM debian:bullseye-slim
ENV JAVA_HOME=/opt/java/openjdk
COPY --from=eclipse-temurin:11 $JAVA_HOME $JAVA_HOME
ENV PATH="${JAVA_HOME}/bin:${PATH}" \
NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%% \
NEO4J_EDITION=%%NEO4J_EDITION%% \
NEO4J_HOME="/var/lib/neo4j"
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
COPY ./local-package/* /startup/
RUN apt update \
&& apt install -y curl wget gosu jq tini \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* "${NEO4J_HOME}" \
&& rm ${NEO4J_TARBALL} \
&& mv "${NEO4J_HOME}"/data /data \
&& mv "${NEO4J_HOME}"/logs /logs \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& chown -R neo4j:neo4j /logs \
&& chmod -R 777 /logs \
&& chown -R neo4j:neo4j "${NEO4J_HOME}" \
&& chmod -R 777 "${NEO4J_HOME}" \
&& ln -s /data "${NEO4J_HOME}"/data \
&& ln -s /logs "${NEO4J_HOME}"/logs \
&& ln -s /startup/docker-entrypoint.sh /docker-entrypoint.sh \
&& apt-get -y purge --auto-remove curl \
&& rm -rf /var/lib/apt/lists/*
ENV PATH "${NEO4J_HOME}"/bin:$PATH
WORKDIR "${NEO4J_HOME}"
VOLUME /data /logs
EXPOSE 7474 7473 7687
ENTRYPOINT ["tini", "-g", "--", "/startup/docker-entrypoint.sh"]
CMD ["neo4j"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.3/coredb/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM debian:bullseye-slim
ENV JAVA_HOME=/opt/java/openjdk
COPY --from=eclipse-temurin:11 $JAVA_HOME $JAVA_HOME
ENV PATH="${JAVA_HOME}/bin:${PATH}" \
NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%% \
NEO4J_EDITION=%%NEO4J_EDITION%% \
NEO4J_HOME="/var/lib/neo4j"
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
COPY ./local-package/* /startup/
RUN apt update \
&& apt install -y curl gosu jq procps tini wget \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* "${NEO4J_HOME}" \
&& rm ${NEO4J_TARBALL} \
&& mv "${NEO4J_HOME}"/data /data \
&& mv "${NEO4J_HOME}"/logs /logs \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& chown -R neo4j:neo4j /logs \
&& chmod -R 777 /logs \
&& chown -R neo4j:neo4j "${NEO4J_HOME}" \
&& chmod -R 777 "${NEO4J_HOME}" \
&& ln -s /data "${NEO4J_HOME}"/data \
&& ln -s /logs "${NEO4J_HOME}"/logs \
&& ln -s /startup/docker-entrypoint.sh /docker-entrypoint.sh \
&& apt-get -y purge --auto-remove curl \
&& rm -rf /var/lib/apt/lists/*
ENV PATH "${NEO4J_HOME}"/bin:$PATH
WORKDIR "${NEO4J_HOME}"
VOLUME /data /logs
EXPOSE 7474 7473 7687
ENTRYPOINT ["tini", "-g", "--", "/startup/docker-entrypoint.sh"]
CMD ["neo4j"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/5/coredb/neo4j-plugins.json:
--------------------------------------------------------------------------------
```json
{
"apoc-extended": {
"versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "apoc.*"
}
},
"apoc": {
"location": "/var/lib/neo4j/labs/apoc-*-core.jar",
"versions": "https://neo4j.github.io/apoc/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "apoc.*"
}
},
"bloom": {
"location": "/var/lib/neo4j/products/bloom-plugin-*.jar",
"versions": "https://bloom-plugins.s3.eu-west-2.amazonaws.com/versions.json",
"properties": {
"server.unmanaged_extension_classes": "com.neo4j.bloom.server=/browser/bloom",
"dbms.security.procedures.unrestricted": "bloom.*",
"dbms.bloom.license_file": "/licenses/bloom.license"
}
},
"graph-data-science": {
"versions": "https://graphdatascience.ninja/versions.json",
"location": "/var/lib/neo4j/products/neo4j-graph-data-science-*.jar",
"properties": {
"dbms.security.procedures.unrestricted": "gds.*"
}
},
"n10s": {
"versions": "https://neo4j-labs.github.io/neosemantics/versions.json",
"properties": {
"dbms.security.procedures.unrestricted":"semantics.*"
}
},
"genai": {
"location": "/var/lib/neo4j/products/neo4j-genai-plugin-*.jar",
"properties": {
"dbms.security.procedures.unrestricted": "genai.*"
}
},
"_testing": {
"versions": "http://host.testcontainers.internal:3000/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "com.neo4j.docker.neo4jserver.plugins.*"
}
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.0/coredb/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM debian:bullseye-slim
ENV JAVA_HOME=/opt/java/openjdk
COPY --from=eclipse-temurin:11 $JAVA_HOME $JAVA_HOME
ENV PATH="${JAVA_HOME}/bin:${PATH}" \
NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%% \
NEO4J_EDITION=%%NEO4J_EDITION%% \
NEO4J_HOME="/var/lib/neo4j"
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
RUN addgroup --gid 7474 --system neo4j && adduser --uid 7474 --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
COPY ./local-package/* /tmp/
RUN apt update \
&& apt install -y curl wget gosu jq tini \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* "${NEO4J_HOME}" \
&& rm ${NEO4J_TARBALL} \
&& mv "${NEO4J_HOME}"/data /data \
&& mv "${NEO4J_HOME}"/logs /logs \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& chown -R neo4j:neo4j /logs \
&& chmod -R 777 /logs \
&& chown -R neo4j:neo4j "${NEO4J_HOME}" \
&& chmod -R 777 "${NEO4J_HOME}" \
&& ln -s /data "${NEO4J_HOME}"/data \
&& ln -s /logs "${NEO4J_HOME}"/logs \
&& mv /tmp/neo4j-plugins.json /neo4j-plugins.json \
&& rm -rf /tmp/* \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get -y purge --auto-remove curl
ENV PATH "${NEO4J_HOME}"/bin:$PATH
WORKDIR "${NEO4J_HOME}"
VOLUME /data /logs
COPY docker-entrypoint.sh /docker-entrypoint.sh
EXPOSE 7474 7473 7687
ENTRYPOINT ["tini", "-g", "--", "/docker-entrypoint.sh"]
CMD ["neo4j"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.4/coredb/neo4j-admin-report.sh:
--------------------------------------------------------------------------------
```bash
#!/bin/bash
# load useful utility functions
. /startup/utilities.sh
function find_report_destination
{
local to_flag="--to"
while [[ $# -gt 0 ]]; do
case $1 in
# for arg in "$@"; do
# case $arg in
"${to_flag}"=*)
echo ${1#*=}
return
;;
"${to_flag}")
echo ${2}
return
;;
*)
shift
;;
esac
done
mkdir -p /tmp/reports
echo "/tmp/reports"
}
report_cmd=("neo4j-admin" "report")
# note, these debug messages are unlikely to work in a docker exec, since environment isn't preserved.
debug_msg "Called ${0}"
debug_msg "neo4j-admin report command is:" "${report_cmd[@]}" "$@"
# find report destination. This could be specified by argument to neo4j-admin or it could be the default location.
report_destination=$(find_report_destination "$@")
debug_msg "report_destination will be ${report_destination}"
debug_msg "Determining which user to run neo4j-admin as."
if running_as_root; then
debug_msg "running neo4j-admin report as root"
if [[ ! $(su-exec neo4j:neo4j test -w "${report_destination}") ]]; then
debug_msg "reowning ${report_destination} to neo4j:neo4j"
chown neo4j:neo4j "${report_destination}"
fi
debug_msg su-exec neo4j:neo4j "${report_cmd[@]}" "$@"
su-exec neo4j:neo4j "${report_cmd[@]}" "$@"
else
debug_msg "running neo4j-admin report as user defined by --user flag"
if [[ ! -w "${report_destination}" ]]; then
print_permissions_advice_and_fail "${report_destination}" "$(id -u)" "$(id -g)"
fi
debug_msg "${report_cmd[@]}" "$@"
"${report_cmd[@]}" "$@"
fi
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/5/coredb/neo4j-admin-report.sh:
--------------------------------------------------------------------------------
```bash
#!/bin/bash
# load useful utility functions
. /startup/utilities.sh
function find_report_destination
{
local to_flag="--to-path"
while [[ $# -gt 0 ]]; do
case $1 in
# for arg in "$@"; do
# case $arg in
"${to_flag}"=*)
echo ${1#*=}
return
;;
"${to_flag}")
echo ${2}
return
;;
*)
shift
;;
esac
done
mkdir -p /tmp/reports
echo "/tmp/reports"
}
report_cmd=("neo4j-admin" "server" "report")
# note, these debug messages are unlikely to work in a docker exec, since environment isn't preserved.
debug_msg "Called ${0}"
debug_msg "neo4j-admin report command is:" "${report_cmd[@]}" "$@"
# find report destination. This could be specified by argument to neo4j-admin or it could be the default location.
report_destination=$(find_report_destination "$@")
debug_msg "report_destination will be ${report_destination}"
debug_msg "Determining which user to run neo4j-admin as."
if running_as_root; then
debug_msg "running neo4j-admin report as root"
if [[ ! $(su-exec neo4j:neo4j test -w "${report_destination}") ]]; then
debug_msg "reowning ${report_destination} to neo4j:neo4j"
chown neo4j:neo4j "${report_destination}"
fi
debug_msg su-exec neo4j:neo4j "${report_cmd[@]}" "$@"
su-exec neo4j:neo4j "${report_cmd[@]}" "$@"
else
debug_msg "running neo4j-admin report as user defined by --user flag"
if [[ ! -w "${report_destination}" ]]; then
print_permissions_advice_and_fail "${report_destination}" "$(id -u)" "$(id -g)"
fi
debug_msg "${report_cmd[@]}" "$@"
"${report_cmd[@]}" "$@"
fi
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/calver/coredb/neo4j-admin-report.sh:
--------------------------------------------------------------------------------
```bash
#!/bin/bash
# load useful utility functions
. /startup/utilities.sh
function find_report_destination
{
local to_flag="--to-path"
while [[ $# -gt 0 ]]; do
case $1 in
# for arg in "$@"; do
# case $arg in
"${to_flag}"=*)
echo ${1#*=}
return
;;
"${to_flag}")
echo ${2}
return
;;
*)
shift
;;
esac
done
mkdir -p /tmp/reports
echo "/tmp/reports"
}
report_cmd=("neo4j-admin" "server" "report")
# note, these debug messages are unlikely to work in a docker exec, since environment isn't preserved.
debug_msg "Called ${0}"
debug_msg "neo4j-admin report command is:" "${report_cmd[@]}" "$@"
# find report destination. This could be specified by argument to neo4j-admin or it could be the default location.
report_destination=$(find_report_destination "$@")
debug_msg "report_destination will be ${report_destination}"
debug_msg "Determining which user to run neo4j-admin as."
if running_as_root; then
debug_msg "running neo4j-admin report as root"
if [[ ! $(su-exec neo4j:neo4j test -w "${report_destination}") ]]; then
debug_msg "reowning ${report_destination} to neo4j:neo4j"
chown neo4j:neo4j "${report_destination}"
fi
debug_msg su-exec neo4j:neo4j "${report_cmd[@]}" "$@"
su-exec neo4j:neo4j "${report_cmd[@]}" "$@"
else
debug_msg "running neo4j-admin report as user defined by --user flag"
if [[ ! -w "${report_destination}" ]]; then
print_permissions_advice_and_fail "${report_destination}" "$(id -u)" "$(id -g)"
fi
debug_msg "${report_cmd[@]}" "$@"
"${report_cmd[@]}" "$@"
fi
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/utils/HttpServerTestExtension.java:
--------------------------------------------------------------------------------
```java
package com.neo4j.docker.utils;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import java.net.InetSocketAddress;
/**
* Runs a HTTP Server with to allow integration testing
*/
public class HttpServerTestExtension implements AfterEachCallback, BeforeEachCallback
{
public final int PORT = 3000;
private HttpServer server;
@Override
public void beforeEach(ExtensionContext extensionContext) throws Exception
{
server = HttpServer.create( new InetSocketAddress( PORT ), 0 );
server.setExecutor( null ); // creates a default executor
server.start();
}
@Override
public void afterEach(ExtensionContext extensionContext) throws Exception
{
if ( server != null )
{
server.stop( 5 ); // waits up to 5 seconds to stop serving http requests
}
}
// Register a handler to provide desired behaviour on a specific uri path
public void registerHandler( String uriToHandle, HttpHandler httpHandler )
{
if (!uriToHandle.startsWith( "/" )){
uriToHandle = '/' + uriToHandle;
}
server.createContext( uriToHandle, httpHandler );
}
public void unregisterEndpoint(String endpoint)
{
if (!endpoint.startsWith( "/" )){
endpoint = '/' + endpoint;
}
try
{
server.removeContext(endpoint);
}
catch (IllegalArgumentException iex)
{
// there was nothing registered to that endpoint so action is a NOP.
}
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.3/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM openjdk:8-jre-slim
ENV NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%% \
NEO4J_EDITION=%%NEO4J_EDITION%% \
NEO4J_HOME="/var/lib/neo4j" \
TINI_VERSION="v0.18.0" \
TINI_SHA256="12d20136605531b09a2c2dac02ccee85e1b874eb322ef6baf7561cd93f93c855"
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
RUN addgroup --system neo4j && adduser --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
COPY ./local-package/* /tmp/
RUN apt update \
&& apt install -y curl gosu jq \
&& curl -L --fail --silent --show-error "https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini" > /sbin/tini \
&& echo "${TINI_SHA256} /sbin/tini" | sha256sum -c --strict --quiet \
&& chmod +x /sbin/tini \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* "${NEO4J_HOME}" \
&& rm ${NEO4J_TARBALL} \
&& mv "${NEO4J_HOME}"/data /data \
&& mv "${NEO4J_HOME}"/logs /logs \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& chown -R neo4j:neo4j /logs \
&& chmod -R 777 /logs \
&& chown -R neo4j:neo4j "${NEO4J_HOME}" \
&& chmod -R 777 "${NEO4J_HOME}" \
&& ln -s /data "${NEO4J_HOME}"/data \
&& ln -s /logs "${NEO4J_HOME}"/logs \
&& mv /tmp/neo4j-plugins.json /neo4j-plugins.json \
&& rm -rf /tmp/* \
&& rm -rf /var/lib/apt/lists/*
ENV PATH "${NEO4J_HOME}"/bin:$PATH
WORKDIR "${NEO4J_HOME}"
VOLUME /data /logs
COPY docker-entrypoint.sh /docker-entrypoint.sh
EXPOSE 7474 7473 7687
ENTRYPOINT ["/sbin/tini", "-g", "--", "/docker-entrypoint.sh"]
CMD ["neo4j"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.4/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM openjdk:8-jre-slim
ENV NEO4J_SHA256=%%NEO4J_SHA%% \
NEO4J_TARBALL=%%NEO4J_TARBALL%% \
NEO4J_EDITION=%%NEO4J_EDITION%% \
NEO4J_HOME="/var/lib/neo4j" \
TINI_VERSION="v0.18.0" \
TINI_SHA256="12d20136605531b09a2c2dac02ccee85e1b874eb322ef6baf7561cd93f93c855"
ARG NEO4J_URI=%%NEO4J_DIST_SITE%%/%%NEO4J_TARBALL%%
RUN addgroup --system neo4j && adduser --system --no-create-home --home "${NEO4J_HOME}" --ingroup neo4j neo4j
COPY ./local-package/* /tmp/
RUN apt update \
&& apt install -y curl wget gosu jq \
&& curl -L --fail --silent --show-error "https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini" > /sbin/tini \
&& echo "${TINI_SHA256} /sbin/tini" | sha256sum -c --strict --quiet \
&& chmod +x /sbin/tini \
&& curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
&& echo "${NEO4J_SHA256} ${NEO4J_TARBALL}" | sha256sum -c --strict --quiet \
&& tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
&& mv /var/lib/neo4j-* "${NEO4J_HOME}" \
&& rm ${NEO4J_TARBALL} \
&& mv "${NEO4J_HOME}"/data /data \
&& mv "${NEO4J_HOME}"/logs /logs \
&& chown -R neo4j:neo4j /data \
&& chmod -R 777 /data \
&& chown -R neo4j:neo4j /logs \
&& chmod -R 777 /logs \
&& chown -R neo4j:neo4j "${NEO4J_HOME}" \
&& chmod -R 777 "${NEO4J_HOME}" \
&& ln -s /data "${NEO4J_HOME}"/data \
&& ln -s /logs "${NEO4J_HOME}"/logs \
&& mv /tmp/neo4j-plugins.json /neo4j-plugins.json \
&& rm -rf /tmp/* \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get -y purge --auto-remove curl
ENV PATH "${NEO4J_HOME}"/bin:$PATH
WORKDIR "${NEO4J_HOME}"
VOLUME /data /logs
COPY docker-entrypoint.sh /docker-entrypoint.sh
EXPOSE 7474 7473 7687
ENTRYPOINT ["/sbin/tini", "-g", "--", "/docker-entrypoint.sh"]
CMD ["neo4j"]
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/neo4jadmin/TestReport.java:
--------------------------------------------------------------------------------
```java
package com.neo4j.docker.neo4jadmin;
import com.neo4j.docker.utils.WaitStrategies;
import com.neo4j.docker.utils.TestSettings;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.ContainerLaunchException;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import java.time.Duration;
public class TestReport
{
private final Logger log = LoggerFactory.getLogger( TestReport.class );
private GenericContainer createAdminContainer()
{
GenericContainer container = new GenericContainer( TestSettings.ADMIN_IMAGE_ID )
.withEnv( "NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes" ).withEnv( "NEO4J_DEBUG", "yes" )
.withCommand( "neo4j-admin", "server", "report" )
.withLogConsumer( new Slf4jLogConsumer( log ) );
WaitStrategies.waitUntilContainerFinished( container, Duration.ofSeconds( 20 ) );
return container;
}
@Test
void shouldErrorHelpfullyIfAdminReport()
{
try(GenericContainer container = createAdminContainer())
{
Assertions.assertThrows( ContainerLaunchException.class, container::start );
Assertions.assertTrue( container.getLogs().contains( "To run the report tool inside a neo4j container, do:" ),
"did not error about needing to run in the same container as the database." +
" Actual logs:"+container.getLogs() );
Assertions.assertTrue( container.getLogs().contains( "docker exec <CONTAINER NAME> neo4j-admin-report" ),
"did not error about needing to run in the same container as the database." +
" Actual logs:"+container.getLogs() );
}
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.5/coredb/neo4j-plugins.json:
--------------------------------------------------------------------------------
```json
{
"apoc": {
"versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "apoc.*"
}
},
"apoc-core": {
"location": "/var/lib/neo4j/labs/apoc-*-core.jar",
"versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "apoc.*"
}
},
"bloom": {
"location": "/var/lib/neo4j/products/bloom-plugin-*.jar",
"versions": "https://bloom-plugins.s3.eu-west-2.amazonaws.com/versions.json",
"properties": {
"dbms.unmanaged_extension_classes": "com.neo4j.bloom.server=/browser/bloom",
"dbms.security.procedures.unrestricted": "bloom.*",
"neo4j.bloom.license_file": "/licenses/bloom.license"
}
},
"streams": {
"versions": "https://neo4j-contrib.github.io/neo4j-streams/versions.json",
"properties": {}
},
"graphql": {
"versions": "https://neo4j-graphql.github.io/neo4j-graphql/versions.json",
"properties": {
"dbms.unmanaged_extension_classes": "org.neo4j.graphql=/graphql",
"dbms.security.procedures.unrestricted": "graphql.*"
}
},
"graph-algorithms": {
"versions": "https://neo4j-contrib.github.io/neo4j-graph-algorithms/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "algo.*"
}
},
"graph-data-science": {
"versions": "https://graphdatascience.ninja/versions.json",
"location": "/var/lib/neo4j/products/neo4j-graph-data-science-*.jar",
"properties": {
"dbms.security.procedures.unrestricted": "gds.*"
}
},
"n10s": {
"versions": "https://neo4j-labs.github.io/neosemantics/versions.json",
"properties": {
"dbms.security.procedures.unrestricted":"semantics.*"
}
},
"_testing": {
"versions": "http://host.testcontainers.internal:3000/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "com.neo4j.docker.neo4jserver.plugins.*"
}
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.2/coredb/neo4j-plugins.json:
--------------------------------------------------------------------------------
```json
{
"apoc": {
"versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "apoc.*"
}
},
"apoc-core": {
"location": "/var/lib/neo4j/labs/apoc-*-core.jar",
"versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "apoc.*"
}
},
"bloom": {
"location": "/var/lib/neo4j/products/bloom-plugin-*.jar",
"versions": "https://bloom-plugins.s3.eu-west-2.amazonaws.com/versions.json",
"properties": {
"dbms.unmanaged_extension_classes": "com.neo4j.bloom.server=/browser/bloom",
"dbms.security.procedures.unrestricted": "bloom.*",
"neo4j.bloom.license_file": "/licenses/bloom.license"
}
},
"streams": {
"versions": "https://neo4j-contrib.github.io/neo4j-streams/versions.json",
"properties": {}
},
"graphql": {
"versions": "https://neo4j-graphql.github.io/neo4j-graphql/versions.json",
"properties": {
"dbms.unmanaged_extension_classes": "org.neo4j.graphql=/graphql",
"dbms.security.procedures.unrestricted": "graphql.*"
}
},
"graph-algorithms": {
"versions": "https://neo4j-contrib.github.io/neo4j-graph-algorithms/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "algo.*"
}
},
"graph-data-science": {
"versions": "https://graphdatascience.ninja/versions.json",
"location": "/var/lib/neo4j/products/neo4j-graph-data-science-*.jar",
"properties": {
"dbms.security.procedures.unrestricted": "gds.*"
}
},
"n10s": {
"versions": "https://neo4j-labs.github.io/neosemantics/versions.json",
"properties": {
"dbms.security.procedures.unrestricted":"semantics.*"
}
},
"_testing": {
"versions": "http://host.testcontainers.internal:3000/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "com.neo4j.docker.neo4jserver.plugins.*"
}
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.3/coredb/neo4j-plugins.json:
--------------------------------------------------------------------------------
```json
{
"apoc": {
"versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "apoc.*"
}
},
"apoc-core": {
"location": "/var/lib/neo4j/labs/apoc-*-core.jar",
"versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "apoc.*"
}
},
"bloom": {
"location": "/var/lib/neo4j/products/bloom-plugin-*.jar",
"versions": "https://bloom-plugins.s3.eu-west-2.amazonaws.com/versions.json",
"properties": {
"dbms.unmanaged_extension_classes": "com.neo4j.bloom.server=/browser/bloom",
"dbms.security.procedures.unrestricted": "bloom.*",
"neo4j.bloom.license_file": "/licenses/bloom.license"
}
},
"streams": {
"versions": "https://neo4j-contrib.github.io/neo4j-streams/versions.json",
"properties": {}
},
"graphql": {
"versions": "https://neo4j-graphql.github.io/neo4j-graphql/versions.json",
"properties": {
"dbms.unmanaged_extension_classes": "org.neo4j.graphql=/graphql",
"dbms.security.procedures.unrestricted": "graphql.*"
}
},
"graph-algorithms": {
"versions": "https://neo4j-contrib.github.io/neo4j-graph-algorithms/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "algo.*"
}
},
"graph-data-science": {
"versions": "https://graphdatascience.ninja/versions.json",
"location": "/var/lib/neo4j/products/neo4j-graph-data-science-*.jar",
"properties": {
"dbms.security.procedures.unrestricted": "gds.*"
}
},
"n10s": {
"versions": "https://neo4j-labs.github.io/neosemantics/versions.json",
"properties": {
"dbms.security.procedures.unrestricted":"semantics.*"
}
},
"_testing": {
"versions": "http://host.testcontainers.internal:3000/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "com.neo4j.docker.neo4jserver.plugins.*"
}
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/ha-cluster-compose.yml:
--------------------------------------------------------------------------------
```yaml
version: '2.1'
networks:
lan:
services:
master:
user: "%%USERIDGROUPID%%"
image: "%%IMAGE%%"
volumes:
- "%%LOGS_DIR%%/master:/logs"
networks:
- lan
ports:
- 7474
- 7687
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_dbms_memory_pagecache_size=10M
- NEO4J_dbms_memory_heap_initial__size=10M
- NEO4J_AUTH=neo4j/neo
- NEO4J_ha_serverId=1
- NEO4J_dbms_mode=HA
- NEO4J_ha_initialHosts=master:5001,slave1:5555,slave2:5001
# Use this to make sure master pushes TXs to both slaves, by default it will be only one
# - NEO4J_ha_tx__push__factor=2
slave1:
user: "%%USERIDGROUPID%%"
image: "%%IMAGE%%"
volumes:
- "%%LOGS_DIR%%/slave1:/logs"
networks:
- lan
ports:
- 7474
- 7687
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_dbms_memory_pagecache_size=10M
- NEO4J_dbms_memory_heap_initial__size=10M
- NEO4J_AUTH=neo4j/neo
- NEO4J_dbms_mode=HA
- NEO4J_ha_serverId=2
- NEO4J_ha_initialHosts=master:5001,slave1:5555,slave2:5001
- NEO4J_ha_host_coordination=slave1:5555
- NEO4J_ha_host_data=slave1:6666
- NEO4J_ha_slave__only=true
- NEO4J_ha_pull__interval=5s # Default value is disabled but we want slave to poll master for test
slave2:
user: "%%USERIDGROUPID%%"
image: "%%IMAGE%%"
volumes:
- "%%LOGS_DIR%%/slave2:/logs"
networks:
- lan
ports:
- 7474
- 7687
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_dbms_memory_pagecache_size=10M
- NEO4J_dbms_memory_heap_initial__size=10M
- NEO4J_AUTH=neo4j/neo
- NEO4J_dbms_mode=HA
- NEO4J_ha_serverId=3
- NEO4J_ha_initialHosts=master:5001,slave1:5555,slave2:5001
- NEO4J_ha_host_coordination=slave2:5001
- NEO4J_ha_host_data=slave2:6001
- NEO4J_ha_slave__only=true
- NEO4J_ha_pull__interval=5s # Default value is disabled but we want slave to poll master for test
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.4/coredb/neo4j-plugins.json:
--------------------------------------------------------------------------------
```json
{
"apoc": {
"versions": "https://neo4j-contrib.github.io/neo4j-apoc-procedures/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "apoc.*"
}
},
"apoc-core": {
"location": "/var/lib/neo4j/labs/apoc-*-core.jar",
"versions": "https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/refs/heads/master/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "apoc.*"
}
},
"bloom": {
"location": "/var/lib/neo4j/products/bloom-plugin-*.jar",
"versions": "https://bloom-plugins.s3.eu-west-2.amazonaws.com/versions.json",
"properties": {
"dbms.unmanaged_extension_classes": "com.neo4j.bloom.server=/browser/bloom",
"dbms.security.procedures.unrestricted": "bloom.*",
"neo4j.bloom.license_file": "/licenses/bloom.license"
}
},
"streams": {
"versions": "https://neo4j-contrib.github.io/neo4j-streams/versions.json",
"properties": {}
},
"graphql": {
"versions": "https://neo4j-graphql.github.io/neo4j-graphql/versions.json",
"properties": {
"dbms.unmanaged_extension_classes": "org.neo4j.graphql=/graphql",
"dbms.security.procedures.unrestricted": "graphql.*"
}
},
"graph-algorithms": {
"versions": "https://neo4j-contrib.github.io/neo4j-graph-algorithms/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "algo.*"
}
},
"graph-data-science": {
"versions": "https://graphdatascience.ninja/versions.json",
"location": "/var/lib/neo4j/products/neo4j-graph-data-science-*.jar",
"properties": {
"dbms.security.procedures.unrestricted": "gds.*"
}
},
"n10s": {
"versions": "https://neo4j-labs.github.io/neosemantics/versions.json",
"properties": {
"dbms.security.procedures.unrestricted":"semantics.*"
}
},
"_testing": {
"versions": "http://host.testcontainers.internal:3000/versions.json",
"properties": {
"dbms.security.procedures.unrestricted": "com.neo4j.docker.neo4jserver.plugins.*"
}
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/generate-stub-plugin/ExampleNeo4jPlugin.java:
--------------------------------------------------------------------------------
```java
package com.neo4j.docker.test.myplugin;
import java.util.stream.Stream;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.logging.Log;
import org.neo4j.procedure.Context;
import org.neo4j.procedure.Name;
import org.neo4j.procedure.Procedure;
/*
This class is a basic Neo4J plugin that defines a procedure which can be called via Cypher.
*/
public class ExampleNeo4jPlugin
{
// Output data class containing primitive types
public static class PrimitiveOutput
{
public String string;
public long integer;
public double aFloat;
public boolean aBoolean;
public PrimitiveOutput( String string, long integer, double aFloat, boolean aBoolean )
{
this.string = string;
this.integer = integer;
this.aFloat = aFloat;
this.aBoolean = aBoolean;
}
}
// @ServiceProvider
// public static class ExampleConfigurationSetting implements SettingsDeclaration
// {
// public static final String CONF_NAME = "com.neo4j.docker.neo4jserver.plugins.loaded_verison";
//
// @Description("Unique setting to identify which semver field was matched")
// public static final Setting<String> loadedVersionValue = SettingImpl.newBuilder(
// CONF_NAME,
// SettingValueParsers.STRING,
// "unset"
// ).build();
// }
@Context
public GraphDatabaseService db;
@Context
public Log log;
// A Neo4j procedure that always returns fixed values
@Procedure
public Stream<PrimitiveOutput> defaultValues( @Name( value = "string", defaultValue = "a string" ) String string,
@Name( value = "integer", defaultValue = "42" ) long integer,
@Name( value = "float", defaultValue = "3.14" ) double aFloat,
@Name( value = "boolean", defaultValue = "true" ) boolean aBoolean )
{
return Stream.of( new PrimitiveOutput( string, integer, aFloat, aBoolean ) );
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/build-utils-common-functions.sh:
--------------------------------------------------------------------------------
```bash
# Common functions used by build-docker-image.sh and publish-neo4j-admin-image.sh
function contains_element
{
local e match="$1"
shift
for e; do [[ "$e" == "$match" ]] && return 0; done
return 1
}
function get_branch_from_version
{
local version=$1
local major=$(echo "${version}" | sed -E 's/^([0-9]+)\.([0-9]+)\..*/\1/')
local minor=$(echo "${version}" | sed -E 's/^([0-9]+)\.([0-9]+)\..*/\2/')
case ${major} in
1|2|3|4)
echo "${major}.${minor}"
return
;;
5)
echo "${major}"
return
;;
*)
echo "calver"
return
esac
}
function get_major_from_version
{
echo "$1" | sed -E 's/^([0-9]+)\.([0-9]+)\..*/\1/'
}
function get_compatible_dockerfile_for_os_or_error
{
local branch=${1}
local requested_os=${2}
case ${branch} in
calver | 5 | 4.4 )
local SUPPORTED_IMAGE_OS=("debian" "ubi9")
if contains_element "${requested_os}" "${SUPPORTED_IMAGE_OS[@]}"; then
echo "Dockerfile-${requested_os}"
return 0
fi
;;
*)
local SUPPORTED_IMAGE_OS=("debian")
if contains_element "${requested_os}" "${SUPPORTED_IMAGE_OS[@]}"; then
echo "Dockerfile"
return 0
else
echo >&2 "${requested_os} is not a supported operating system for ${branch}."
return 1
fi
;;
esac
}
function tarball_name
{
local version=${1}
local edition=${2}
echo "neo4j-${2}-${1}-unix.tar.gz"
}
function cached_tarball
{
local version=${1}
local edition=${2}
echo "${TAR_CACHE}/$(tarball_name ${version} ${edition})"
}
function fetch_tarball
{
local version=${1}
local edition=${2}
local tar_name=$(tarball_name "${version}" "${edition}")
mkdir -p ${TAR_CACHE}
if [[ ! -f $(cached_tarball "${version}" "${edition}") ]]; then
echo "Downloading ${tar_name} from ${DISTRIBUTION_SITE} to $(cached_tarball ${version} ${edition})"
wget ${DISTRIBUTION_SITE}/${tar_name} -O "$(cached_tarball ${version} ${edition})"
fi
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/neo4jadmin/TestAdminBasic.java:
--------------------------------------------------------------------------------
```java
package com.neo4j.docker.neo4jadmin;
import com.neo4j.docker.utils.WaitStrategies;
import com.neo4j.docker.utils.TestSettings;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.ContainerLaunchException;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import java.time.Duration;
public class TestAdminBasic
{
private final Logger log = LoggerFactory.getLogger( TestAdminBasic.class );
@Test
void testCannotRunNeo4j()
{
GenericContainer admin = new GenericContainer( TestSettings.ADMIN_IMAGE_ID );
admin.withEnv( "NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes" )
.withExposedPorts( 7474, 7687 )
.withLogConsumer( new Slf4jLogConsumer( log ) )
.withCommand( "neo4j", "console" );
WaitStrategies.waitUntilContainerFinished( admin, Duration.ofSeconds( 30) );
Assertions.assertThrows( ContainerLaunchException.class, admin::start );
admin.stop();
}
@Test
void testLicenseAcceptanceRequired_Neo4jAdmin()
{
Assumptions.assumeTrue( TestSettings.EDITION == TestSettings.Edition.ENTERPRISE,
"No license checks for community edition");
String logsOut;
try(GenericContainer container = new GenericContainer( TestSettings.ADMIN_IMAGE_ID )
.withLogConsumer( new Slf4jLogConsumer( log ) ) )
{
WaitStrategies.waitUntilContainerFinished( container, Duration.ofSeconds( 30) );
// container start should fail due to licensing.
Assertions.assertThrows( ContainerLaunchException.class, container::start,
"Neo4j did not notify about accepting the license agreement" );
logsOut = container.getLogs();
}
// double check the container didn't warn and start neo4j anyway
Assertions.assertTrue( logsOut.contains( "must accept the license" ),
"Neo4j did not notify about accepting the license agreement" );
Assertions.assertFalse( logsOut.contains( "Remote interface available" ),
"Neo4j was started even though the license was not accepted" );
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/publish-neo4j-admin-images.sh:
--------------------------------------------------------------------------------
```bash
#!/bin/bash
set -eu -o pipefail
ROOT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
source "$ROOT_DIR/build-utils-common-functions.sh"
if [[ $# -eq 2 ]]; then
NEO4JVERSION=${1}
REPOSITORY=${2}
elif [[ -z ${NEO4JVERSION:-""} ]]; then
echo >&2 "NEO4JVERSION is unset. Either set it in the environment or pass as argument to this script."
exit 1
elif [[ -z ${REPOSITORY:-""} ]]; then
echo >&2 "REPOSITORY is unset. Either set it in the environment or pass as argument to this script."
exit 1
fi
echo "Verifying access or failing fast, by re-tagging neo4j-admin:5, when successful it's a noop."
docker buildx imagetools create "${REPOSITORY}":5-community \
--tag "${REPOSITORY}:5"
echo "Publishing ${REPOSITORY}:${NEO4JVERSION}"
"${ROOT_DIR}/publish-neo4j-admin-image.sh" "${NEO4JVERSION}" "enterprise" "ubi9" "${REPOSITORY}"
"${ROOT_DIR}/publish-neo4j-admin-image.sh" "${NEO4JVERSION}" "community" "ubi9" "${REPOSITORY}"
"${ROOT_DIR}/publish-neo4j-admin-image.sh" "${NEO4JVERSION}" "enterprise" "debian" "${REPOSITORY}"
"${ROOT_DIR}/publish-neo4j-admin-image.sh" "${NEO4JVERSION}" "community" "debian" "${REPOSITORY}"
echo "Adding extra tags..."
MAJOR=$(get_major_from_version "${NEO4JVERSION}")
if [[ "$MAJOR" == "5" ]]; then
echo "Tagging ${MAJOR}..."
docker buildx imagetools create "${REPOSITORY}:${NEO4JVERSION}-community-debian" \
--tag "${REPOSITORY}:5-community" \
--tag "${REPOSITORY}:5"
docker buildx imagetools create "${REPOSITORY}:${NEO4JVERSION}-enterprise-debian" \
--tag "${REPOSITORY}:5-enterprise"
elif [[ "$MAJOR" -gt 2024 ]]; then
echo "Tagging calver ${MAJOR}..."
docker buildx imagetools create "${REPOSITORY}:${NEO4JVERSION}-community-debian" \
--tag "${REPOSITORY}:${MAJOR}" \
--tag "${REPOSITORY}:${MAJOR}-community" \
--tag "${REPOSITORY}:community-debian" \
--tag "${REPOSITORY}:community" \
--tag "${REPOSITORY}:debian" \
--tag "${REPOSITORY}:latest"
docker buildx imagetools create "${REPOSITORY}:${NEO4JVERSION}-community-ubi9" \
--tag "${REPOSITORY}:community-ubi9" \
--tag "${REPOSITORY}:ubi9" \
docker buildx imagetools create "${REPOSITORY}:${NEO4JVERSION}-enterprise-debian" \
--tag "${REPOSITORY}:${MAJOR}-enterprise" \
--tag "${REPOSITORY}:enterprise-debian" \
--tag "${REPOSITORY}:enterprise"
docker buildx imagetools create "${REPOSITORY}:${NEO4JVERSION}-enterprise-ubi9" \
--tag "${REPOSITORY}:enterprise-ubi9"
fi
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/utils/WaitStrategies.java:
--------------------------------------------------------------------------------
```java
package com.neo4j.docker.utils;
import com.github.dockerjava.api.command.InspectContainerResponse;
import org.rnorth.ducttape.unreliables.Unreliables;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy;
import org.testcontainers.containers.wait.strategy.AbstractWaitStrategy;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.containers.wait.strategy.WaitStrategy;
import org.testcontainers.utility.DockerStatus;
import java.time.Duration;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
public class WaitStrategies
{
private final static Duration STARTUP_TIMEOUT_SECONDS = Duration.ofSeconds(180);
private WaitStrategies() {}
public static WaitStrategy waitForNeo4jReady( String username, String password, String database, Duration timeout )
{
if (TestSettings.EDITION == TestSettings.Edition.ENTERPRISE &&
TestSettings.NEO4J_VERSION.isAtLeastVersion(Neo4jVersion.NEO4J_VERSION_500)) {
return Wait.forHttp("/db/" + database + "/cluster/available")
.withBasicCredentials(username, password)
.forPort(7474)
.forStatusCode(200)
.withStartupTimeout(timeout);
} else
{
return waitForBoltReady();
}
}
public static WaitStrategy waitForNeo4jReady( String password ) {
return waitForNeo4jReady( "neo4j", password, "neo4j", STARTUP_TIMEOUT_SECONDS);
}
public static WaitStrategy waitForBoltReady()
{
return Wait.forHttp("/")
.forPort(7687)
.forStatusCode(200)
.withStartupTimeout(STARTUP_TIMEOUT_SECONDS);
}
/**For containers that will just run a command and exit automatically.
* With this wait strategy, starting a container will block until the container has closed itself.
* The container could have succeeded or failed, we just wait for it to close.
* If the container fails to start, it will still throw an exception, this just prevents us from having to wait the full timeout.
* @param container the container to set the wait strategy on
* @param timeout how long to wait
* @return container in the modified state.
* */
public static GenericContainer waitUntilContainerFinished( GenericContainer container, Duration timeout)
{
container.setStartupCheckStrategy( new OneShotStartupCheckStrategy().withTimeout( timeout ) );
container.setWaitStrategy( new AbstractWaitStrategy()
{
@Override
protected void waitUntilReady()
{
Callable<Boolean> isFinished = () -> {
InspectContainerResponse.ContainerState x = waitStrategyTarget.getCurrentContainerInfo().getState();
return DockerStatus.isContainerStopped( x );
};
Unreliables.retryUntilTrue( (int)timeout.getSeconds(), TimeUnit.SECONDS, isFinished );
}
});
return container;
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/utils/TestSettings.java:
--------------------------------------------------------------------------------
```java
package com.neo4j.docker.utils;
import org.junit.jupiter.api.Assertions;
import org.testcontainers.utility.DockerImageName;
import java.nio.file.Path;
import java.nio.file.Paths;
public class TestSettings
{
public static final Neo4jVersion NEO4J_VERSION = getVersion();
public static final DockerImageName IMAGE_ID = getImage();
public static final DockerImageName ADMIN_IMAGE_ID = getNeo4jAdminImage();
public static final Path TEST_TMP_FOLDER = Paths.get("local-mounts" );
public static final Edition EDITION = getEdition();
public static final BaseOS BASE_OS = getBaseOS();
public static final boolean SKIP_MOUNTED_FOLDER_TARBALLING = getSkipTarballingFromEnv();
public enum Edition
{
COMMUNITY,
ENTERPRISE;
}
public enum BaseOS
{
BULLSEYE,
UBI9,
UBI8;
}
private static String getValueFromPropertyOrEnv(String propertyName, String envName)
{
String verStr = System.getProperty( propertyName );
if(verStr == null)
{
verStr = System.getenv( envName );
}
Assertions.assertNotNull( String.format( "Neo4j %s has not been specified. " +
"Either use mvn argument -D%s or set env %s",
propertyName, propertyName, envName),
verStr);
return verStr;
}
private static Neo4jVersion getVersion()
{
return Neo4jVersion.fromVersionString( getValueFromPropertyOrEnv( "version", "NEO4JVERSION" ));
}
private static DockerImageName getImage()
{
return DockerImageName.parse(getValueFromPropertyOrEnv("image", "NEO4J_IMAGE"));
}
private static DockerImageName getNeo4jAdminImage()
{
return DockerImageName.parse(getValueFromPropertyOrEnv("adminimage", "NEO4JADMIN_IMAGE"));
}
private static Edition getEdition()
{
String edition = getValueFromPropertyOrEnv("edition", "NEO4J_EDITION");
switch ( edition.toLowerCase() )
{
case "community":
return Edition.COMMUNITY;
case "enterprise":
return Edition.ENTERPRISE;
default:
Assertions.fail( edition + " is not a valid Neo4j edition. Options are \"community\" or \"enterprise\"." );
}
return null;
}
private static BaseOS getBaseOS()
{
String os = getValueFromPropertyOrEnv("baseos", "BASE_OS");
switch ( os.toLowerCase() )
{
case "debian":
return BaseOS.BULLSEYE;
case "ubi9":
return BaseOS.UBI9;
case "ubi8":
return BaseOS.UBI8;
default:
Assertions.fail( os + " is not a valid Neo4j base operating system. Options are \"debian\", \"ubi9\" or \"ubi8\"." );
}
return null;
}
private static boolean getSkipTarballingFromEnv()
{
// defaults to false. Tarballing test artifacts must be opt-out not opt-in.
String skipTar = System.getenv( "NEO4J_SKIP_MOUNTED_FOLDER_TARBALLING" );
if(skipTar == null) return false;
else return (skipTar.equals( "true" ));
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/resources/causal-cluster-compose.yml:
--------------------------------------------------------------------------------
```yaml
version: '2.1'
networks:
lan:
services:
core1:
user: "%%USERIDGROUPID%%"
image: "%%IMAGE%%"
volumes:
- "%%LOGS_DIR%%/core1:/logs"
networks:
- lan
ports:
- 7474
- 7687
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_dbms_memory_pagecache_size=10M
- NEO4J_dbms_memory_heap_initial__size=10M
- NEO4J_AUTH=neo4j/neo
- NEO4J_dbms_mode=CORE
- NEO4J_causalClustering_discoveryAdvertisedAddress=core1:5000
- NEO4J_causalClustering_transactionAdvertisedAddress=core1:6000
- NEO4J_causalClustering_raftAdvertisedAddress=core1:7000
- NEO4J_causalClustering_expectedCoreClusterSize=3
- NEO4J_causalClustering_initialDiscoveryMembers=core1:5000,core2:5000,core3:5000
- NEO4J_causal__clustering_disable__middleware__logging=false
core2:
user: "%%USERIDGROUPID%%"
image: "%%IMAGE%%"
volumes:
- "%%LOGS_DIR%%/core2:/logs"
networks:
- lan
ports:
- 7474
- 7687
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_dbms_memory_pagecache_size=10M
- NEO4J_dbms_memory_heap_initial__size=10M
- NEO4J_AUTH=neo4j/neo
- NEO4J_dbms_mode=CORE
- NEO4J_causalClustering_discoveryAdvertisedAddress=core2:5000
- NEO4J_causalClustering_transactionAdvertisedAddress=core2:6000
- NEO4J_causalClustering_raftAdvertisedAddress=core2:7000
- NEO4J_causalClustering_expectedCoreClusterSize=3
- NEO4J_causalClustering_initialDiscoveryMembers=core1:5000,core2:5000,core3:5000
- NEO4J_causalClustering_refuseToBeLeader=true
core3:
user: "%%USERIDGROUPID%%"
image: "%%IMAGE%%"
volumes:
- "%%LOGS_DIR%%/core3:/logs"
- "%%LOGS_DIR%%/core3/backups:/backups"
networks:
- lan
ports:
- 6362
- 7474
- 7687
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_dbms_memory_pagecache_size=10M
- NEO4J_dbms_memory_heap_initial__size=10M
- NEO4J_AUTH=neo4j/neo
- NEO4J_dbms_mode=CORE
- NEO4J_causalClustering_discoveryAdvertisedAddress=core3:5000
- NEO4J_causalClustering_transactionAdvertisedAddress=core3:6000
- NEO4J_causalClustering_raftAdvertisedAddress=core3:7000
- NEO4J_causalClustering_expectedCoreClusterSize=3
- NEO4J_causalClustering_initialDiscoveryMembers=core1:5000,core2:5000,core3:5000
- NEO4J_causalClustering_refuseToBeLeader=true
- NEO4J_dbms_backup_enabled=true
- NEO4J_dbms_backup_address=0.0.0.0:6362
readreplica1:
user: "%%USERIDGROUPID%%"
image: "%%IMAGE%%"
volumes:
- "%%LOGS_DIR%%/readreplica1:/logs"
networks:
- lan
ports:
- 7474
- 7687
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_dbms_memory_pagecache_size=10M
- NEO4J_dbms_memory_heap_initial__size=10M
- NEO4J_AUTH=neo4j/neo
- NEO4J_dbms_mode=READ_REPLICA
- NEO4J_causalClustering_discoveryAdvertisedAddress=readreplica1:5000
- NEO4J_causalClustering_transactionAdvertisedAddress=readreplica1:6000
- NEO4J_causalClustering_raftAdvertisedAddress=readreplica1:7000
- NEO4J_causalClustering_initialDiscoveryMembers=core1:5000,core2:5000,core3:5000
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/utils/Neo4jVersion.java:
--------------------------------------------------------------------------------
```java
package com.neo4j.docker.utils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Neo4jVersion
{
public static final Neo4jVersion NEO4J_VERSION_400 = new Neo4jVersion( 4, 0, 0 );
public static final Neo4jVersion NEO4J_VERSION_440 = new Neo4jVersion( 4, 4, 0 );
public static final Neo4jVersion NEO4J_VERSION_500 = new Neo4jVersion( 5, 0, 0 );
public static final Neo4jVersion NEO4J_VERSION_527 = new Neo4jVersion( 5, 27, 0 );
public final int major;
public final int minor;
public final int patch;
public final String label;
public static Neo4jVersion fromVersionString( String version )
{
Pattern pattern = Pattern.compile( "(?<major>[\\d]+)\\.(?<minor>[\\d]+)\\.(?<patch>[\\d]+)(?<label>-(.*))?" );
Matcher x = pattern.matcher( version );
x.find();
return new Neo4jVersion(
Integer.parseInt( x.group( "major" ) ),
Integer.parseInt( x.group( "minor" ) ),
Integer.parseInt( x.group( "patch" ) ),
(x.group( "label" ) == null) ? "" : x.group( "label" )
);
}
public static String makeVersionString(int major, int minor)
{
if ( major > 2023 )
{
return String.format( "%d.%02d", major, minor);
}
return String.format( "%d.%d", major, minor);
}
public static String makeVersionString(int major, int minor, int patch)
{
return makeVersionString( major, minor) + String.format(".%d", patch);
}
public Neo4jVersion( int major, int minor, int patch )
{
this( major, minor, patch, "" );
}
public Neo4jVersion( int major, int minor, int patch, String label )
{
this.major = major;
this.minor = minor;
this.patch = patch;
this.label = label;
}
public boolean isNewerThan(Neo4jVersion that)
{
if ( this.major != that.major )
{
return (this.major > that.major);
}
else
{
if ( this.minor != that.minor )
{
return (this.minor > that.minor);
}
else
{
return (this.patch > that.patch);
}
}
// Not comparing the alpha/beta label because it's still the *same* major minor patch version and a very unlikely upgrade path
}
public boolean isOlderThan( Neo4jVersion that )
{
return !isAtLeastVersion( that );
}
public boolean isAtLeastVersion( Neo4jVersion that )
{
boolean isNewer = this.isNewerThan( that );
if ( !isNewer )
{
return isEqual( that );
}
else
{
return true;
}
}
public boolean isEqual( Neo4jVersion that )
{
return (major == that.major) && (minor == that.minor) && (patch == that.patch);
}
@Override
public String toString()
{
return makeVersionString( major, minor, patch ) + label;
}
public String toReleaseString()
{
return makeVersionString( major, minor, patch );
}
@Override
public boolean equals( Object o )
{
if ( this == o )
{
return true;
}
if ( o == null || getClass() != o.getClass() )
{
return false;
}
return isEqual( (Neo4jVersion) o );
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/2.3/docker-entrypoint.sh:
--------------------------------------------------------------------------------
```bash
#!/bin/bash -eu
setting() {
setting="${1}"
value="${2}"
file="${3}"
if [ -n "${value}" ]; then
if grep --quiet --fixed-strings "${setting}=" "${NEO4J_HOME}/conf/${file}"; then
sed --in-place "s|.*${setting}=.*|${setting}=${value}|" "${NEO4J_HOME}/conf/${file}"
else
echo "${setting}=${value}" >>"${NEO4J_HOME}/conf/${file}"
fi
fi
}
if [ "$1" == "neo4j" ]; then
setting "keep_logical_logs" "${NEO4J_KEEP_LOGICAL_LOGS:-100M size}" neo4j.properties
setting "dbms.pagecache.memory" "${NEO4J_CACHE_MEMORY:-512M}" neo4j.properties
setting "wrapper.java.additional=-Dneo4j.ext.udc.source" "${NEO4J_UDC_SOURCE:-docker}" neo4j-wrapper.conf
setting "wrapper.java.initmemory" "${NEO4J_HEAP_MEMORY:-512}" neo4j-wrapper.conf
setting "wrapper.java.maxmemory" "${NEO4J_HEAP_MEMORY:-512}" neo4j-wrapper.conf
setting "org.neo4j.server.thirdparty_jaxrs_classes" "${NEO4J_THIRDPARTY_JAXRS_CLASSES:-}" neo4j-server.properties
setting "allow_store_upgrade" "${NEO4J_ALLOW_STORE_UPGRADE:-}" neo4j.properties
if [ "${NEO4J_AUTH:-}" == "none" ]; then
setting "dbms.security.auth_enabled" "false" neo4j-server.properties
elif [[ "${NEO4J_AUTH:-}" == neo4j/* ]]; then
password="${NEO4J_AUTH#neo4j/}"
setting "org.neo4j.server.webserver.address" "127.0.0.1" neo4j-server.properties
bin/neo4j start || \
(cat data/log/console.log && echo "Neo4j failed to start" && exit 1)
if ! curl --fail --silent --user "neo4j:${password}" http://localhost:7474/db/data/ >/dev/null ; then
curl --fail --silent --show-error --user neo4j:neo4j \
--data '{"password": "'"${password}"'"}' \
--header 'Content-Type: application/json' \
http://localhost:7474/user/neo4j/password
fi
bin/neo4j stop
elif [ -n "${NEO4J_AUTH:-}" ]; then
echo "Invalid value for NEO4J_AUTH: '${NEO4J_AUTH}'"
exit 1
fi
setting "org.neo4j.server.webserver.address" "0.0.0.0" neo4j-server.properties
setting "org.neo4j.server.database.mode" "${NEO4J_DATABASE_MODE:-}" neo4j-server.properties
setting "ha.server_id" "${NEO4J_SERVER_ID:-}" neo4j.properties
setting "ha.server" "${NEO4J_HA_ADDRESS:-}:6001" neo4j.properties
setting "ha.cluster_server" "${NEO4J_HA_ADDRESS:-}:5001" neo4j.properties
setting "ha.initial_hosts" "${NEO4J_INITIAL_HOSTS:-}" neo4j.properties
[ -f "${EXTENSION_SCRIPT:-}" ] && . ${EXTENSION_SCRIPT}
if [ -d /conf ]; then
find /conf -type f -exec cp {} "${NEO4J_HOME}/conf" \;
fi
if [ -d /ssl ]; then
num_certs=$(ls /ssl/*.cert 2>/dev/null | wc -l)
num_keys=$(ls /ssl/*.key 2>/dev/null | wc -l)
if [ $num_certs == "1" -a $num_keys == "1" ]; then
cert=$(ls /ssl/*.cert)
key=$(ls /ssl/*.key)
setting "dbms.security.tls_certificate_file" $cert neo4j-server.properties
setting "dbms.security.tls_key_file" $key neo4j-server.properties
else
echo "You must provide exactly one *.cert and exactly one *.key in /ssl."
exit 1
fi
fi
if [ -d /plugins ]; then
find /plugins -type f -exec cp {} plugins \;
fi
exec bin/neo4j console
elif [ "$1" == "dump-config" ]; then
if [ -d "${NEO4J_HOME}/conf" ]; then
cp --recursive "${NEO4J_HOME}"/conf/* /conf
else
echo >&2 "You must provide a /conf volume"
exit 1
fi
else
exec "$@"
fi
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/3.5/neo4j-admin/docker-entrypoint.sh:
--------------------------------------------------------------------------------
```bash
#!/bin/bash -eu
function running_as_root
{
test "$(id -u)" = "0"
}
function is_writable
{
${exec_cmd} test -w "${1}"
}
function print_permissions_advice_and_fail
{
local _directory=${1}
echo >&2 "
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.
Hints to solve the issue:
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.
2) Pass the folder owner's user ID and group ID to docker run, so that docker runs as that user.
If the folder is owned by the current user, this can be done by adding this flag to your docker run command:
--user=\$(id -u):\$(id -g)
"
exit 1
}
function check_mounted_folder_writable_with_chown
{
local mountFolder=${1}
if running_as_root; then
# check folder permissions
if ! is_writable "${mountFolder}" ; then
# warn that we're about to chown the folder and then chown it
echo "Warning: Folder mounted to \"${mountFolder}\" is not writable from inside container. Changing folder owner to ${userid}."
chown -R "${userid}":"${groupid}" "${mountFolder}"
# check permissions on files in the folder
elif [ $(${exec_cmd} find "${mountFolder}" -not -writable | wc -l) -gt 0 ]; then
echo "Warning: Some files inside \"${mountFolder}\" are not writable from inside container. Changing folder owner to ${userid}."
chown -R "${userid}":"${groupid}" "${mountFolder}"
fi
else
if [[ ! -w "${mountFolder}" ]] && [[ "$(stat -c %U ${mountFolder})" != "neo4j" ]]; then
print_permissions_advice_and_fail "${mountFolder}"
fi
fi
}
# ==== SETUP WHICH USER TO RUN AS ====
if running_as_root; then
userid="neo4j"
groupid="neo4j"
groups=($(id -G neo4j))
exec_cmd="runuser -p -u neo4j -g neo4j --"
else
userid="$(id -u)"
groupid="$(id -g)"
groups=($(id -G))
exec_cmd="exec"
fi
# ==== CHECK LICENSE AGREEMENT ====
if [ "${NEO4J_EDITION}" == "enterprise" ]; then
if [ "${NEO4J_ACCEPT_LICENSE_AGREEMENT:=no}" != "yes" ]; then
echo >&2 "
In order to use Neo4j Enterprise Edition you must accept the license agreement.
(c) Neo4j Sweden AB. 2022. All Rights Reserved.
Use of this Software without a proper commercial license with Neo4j,
Inc. or its affiliates is prohibited.
Email inquiries can be directed to: [email protected]
More information is also available at: https://neo4j.com/licensing/
To accept the license agreement set the environment variable
NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
To do this you can use the following docker argument:
--env=NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
"
exit 1
fi
fi
# ==== ENSURE MOUNT FOLDER READ/WRITABILITY ====
if [ -d /data ]; then
check_mounted_folder_writable_with_chown "/data"
if [ -d /data/databases ]; then
check_mounted_folder_writable_with_chown "/data/databases"
fi
if [ -d /data/dbms ]; then
check_mounted_folder_writable_with_chown "/data/dbms"
fi
fi
if [ -d /backups ]; then
check_mounted_folder_writable_with_chown "/backups"
fi
# ==== MAKE SURE NEO4J CANNOT BE RUN FROM THIS CONTAINER ====
if [[ "${1}" == "neo4j" ]]; then
correct_image="neo4j:"$(neo4j-admin --version)"-${NEO4J_EDITION}"
echo >&2 "
This is a neo4j-admin only image, and usage of Neo4j server is not supported from here.
If you wish to start a Neo4j database, use:
docker run ${correct_image}
"
exit 1
fi
# ==== START NEO4J-ADMIN COMMAND ====
${exec_cmd} "${@}"
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.3/neo4j-admin/docker-entrypoint.sh:
--------------------------------------------------------------------------------
```bash
#!/bin/bash -eu
function running_as_root
{
test "$(id -u)" = "0"
}
function is_writable
{
${exec_cmd} test -w "${1}"
}
function print_permissions_advice_and_fail
{
local _directory=${1}
echo >&2 "
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.
Hints to solve the issue:
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.
2) Pass the folder owner's user ID and group ID to docker run, so that docker runs as that user.
If the folder is owned by the current user, this can be done by adding this flag to your docker run command:
--user=\$(id -u):\$(id -g)
"
exit 1
}
function check_mounted_folder_writable_with_chown
{
local mountFolder=${1}
if running_as_root; then
# check folder permissions
if ! is_writable "${mountFolder}" ; then
# warn that we're about to chown the folder and then chown it
echo "Warning: Folder mounted to \"${mountFolder}\" is not writable from inside container. Changing folder owner to ${userid}."
chown -R "${userid}":"${groupid}" "${mountFolder}"
# check permissions on files in the folder
elif [ $(${exec_cmd} find "${mountFolder}" -not -writable | wc -l) -gt 0 ]; then
echo "Warning: Some files inside \"${mountFolder}\" are not writable from inside container. Changing folder owner to ${userid}."
chown -R "${userid}":"${groupid}" "${mountFolder}"
fi
else
if [[ ! -w "${mountFolder}" ]] && [[ "$(stat -c %U ${mountFolder})" != "neo4j" ]]; then
print_permissions_advice_and_fail "${mountFolder}"
fi
fi
}
# ==== SETUP WHICH USER TO RUN AS ====
if running_as_root; then
userid="neo4j"
groupid="neo4j"
groups=($(id -G neo4j))
exec_cmd="runuser -p -u neo4j -g neo4j --"
else
userid="$(id -u)"
groupid="$(id -g)"
groups=($(id -G))
exec_cmd="exec"
fi
# ==== CHECK LICENSE AGREEMENT ====
if [ "${NEO4J_EDITION}" == "enterprise" ]; then
if [ "${NEO4J_ACCEPT_LICENSE_AGREEMENT:=no}" != "yes" ]; then
echo >&2 "
In order to use Neo4j Enterprise Edition you must accept the license agreement.
(c) Neo4j Sweden AB. 2022. All Rights Reserved.
Use of this Software without a proper commercial license with Neo4j,
Inc. or its affiliates is prohibited.
Email inquiries can be directed to: [email protected]
More information is also available at: https://neo4j.com/licensing/
To accept the license agreement set the environment variable
NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
To do this you can use the following docker argument:
--env=NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
"
exit 1
fi
fi
# ==== ENSURE MOUNT FOLDER READ/WRITABILITY ====
if [ -d /data ]; then
check_mounted_folder_writable_with_chown "/data"
if [ -d /data/databases ]; then
check_mounted_folder_writable_with_chown "/data/databases"
fi
if [ -d /data/dbms ]; then
check_mounted_folder_writable_with_chown "/data/dbms"
fi
if [ -d /data/transactions ]; then
check_mounted_folder_writable_with_chown "/data/transactions"
fi
fi
if [ -d /backups ]; then
check_mounted_folder_writable_with_chown "/backups"
fi
# ==== MAKE SURE NEO4J CANNOT BE RUN FROM THIS CONTAINER ====
if [[ "${1}" == "neo4j" ]]; then
correct_image="neo4j:"$(neo4j-admin --version)"-${NEO4J_EDITION}"
echo >&2 "
This is a neo4j-admin only image, and usage of Neo4j server is not supported from here.
If you wish to start a Neo4j database, use:
docker run ${correct_image}
"
exit 1
fi
# ==== START NEO4J-ADMIN COMMAND ====
${exec_cmd} "${@}"
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.0/neo4j-admin/docker-entrypoint.sh:
--------------------------------------------------------------------------------
```bash
#!/bin/bash -eu
function running_as_root
{
test "$(id -u)" = "0"
}
function is_writable
{
gosu "${userid}":"${groupid}" test -w "${1}"
}
function print_permissions_advice_and_fail
{
local _directory=${1}
echo >&2 "
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.
Hints to solve the issue:
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.
2) Pass the folder owner's user ID and group ID to docker run, so that docker runs as that user.
If the folder is owned by the current user, this can be done by adding this flag to your docker run command:
--user=\$(id -u):\$(id -g)
"
exit 1
}
function check_mounted_folder_writable_with_chown
{
local mountFolder=${1}
if running_as_root; then
# check folder permissions
if ! is_writable "${mountFolder}" ; then
# warn that we're about to chown the folder and then chown it
echo "Warning: Folder mounted to \"${mountFolder}\" is not writable from inside container. Changing folder owner to ${userid}."
chown -R "${userid}":"${groupid}" "${mountFolder}"
# check permissions on files in the folder
elif [ $(gosu "${userid}":"${groupid}" find "${mountFolder}" -not -writable | wc -l) -gt 0 ]; then
echo "Warning: Some files inside \"${mountFolder}\" are not writable from inside container. Changing folder owner to ${userid}."
chown -R "${userid}":"${groupid}" "${mountFolder}"
fi
else
if [[ ! -w "${mountFolder}" ]] && [[ "$(stat -c %U ${mountFolder})" != "neo4j" ]]; then
print_permissions_advice_and_fail "${mountFolder}"
fi
fi
}
# ==== SETUP WHICH USER TO RUN AS ====
if running_as_root; then
userid="neo4j"
groupid="neo4j"
groups=($(id -G neo4j))
exec_cmd="exec gosu neo4j:neo4j"
else
userid="$(id -u)"
groupid="$(id -g)"
groups=($(id -G))
exec_cmd="exec"
fi
# ==== CHECK LICENSE AGREEMENT ====
if [ "${NEO4J_EDITION}" == "enterprise" ]; then
if [ "${NEO4J_ACCEPT_LICENSE_AGREEMENT:=no}" != "yes" ]; then
echo >&2 "
In order to use Neo4j Enterprise Edition you must accept the license agreement.
(c) Neo4j Sweden AB. 2021. All Rights Reserved.
Use of this Software without a proper commercial license with Neo4j,
Inc. or its affiliates is prohibited.
Email inquiries can be directed to: [email protected]
More information is also available at: https://neo4j.com/licensing/
To accept the license agreement set the environment variable
NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
To do this you can use the following docker argument:
--env=NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
"
exit 1
fi
fi
# ==== ENSURE MOUNT FOLDER READ/WRITABILITY ====
if [ -d /data ]; then
check_mounted_folder_writable_with_chown "/data"
if [ -d /data/databases ]; then
check_mounted_folder_writable_with_chown "/data/databases"
fi
if [ -d /data/dbms ]; then
check_mounted_folder_writable_with_chown "/data/dbms"
fi
if [ -d /data/transactions ]; then
check_mounted_folder_writable_with_chown "/data/transactions"
fi
fi
if [ -d /backups ]; then
check_mounted_folder_writable_with_chown "/backups"
fi
# ==== MAKE SURE NEO4J CANNOT BE RUN FROM THIS CONTAINER ====
rm ${NEO4J_HOME}/bin/neo4j
if [[ "${1}" == "neo4j" ]]; then
correct_image="neo4j:"$(neo4j-admin --version)"-${NEO4J_EDITION}"
echo >&2 "
This is a neo4j-admin only image, and usage of Neo4j server is not supported from here.
If you wish to start a Neo4j database, use:
docker run ${correct_image}
"
exit 1
fi
# ==== START NEO4J-ADMIN COMMAND ====
${exec_cmd} "${@}"
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.1/neo4j-admin/docker-entrypoint.sh:
--------------------------------------------------------------------------------
```bash
#!/bin/bash -eu
function running_as_root
{
test "$(id -u)" = "0"
}
function is_writable
{
gosu "${userid}":"${groupid}" test -w "${1}"
}
function print_permissions_advice_and_fail
{
local _directory=${1}
echo >&2 "
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.
Hints to solve the issue:
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.
2) Pass the folder owner's user ID and group ID to docker run, so that docker runs as that user.
If the folder is owned by the current user, this can be done by adding this flag to your docker run command:
--user=\$(id -u):\$(id -g)
"
exit 1
}
function check_mounted_folder_writable_with_chown
{
local mountFolder=${1}
if running_as_root; then
# check folder permissions
if ! is_writable "${mountFolder}" ; then
# warn that we're about to chown the folder and then chown it
echo "Warning: Folder mounted to \"${mountFolder}\" is not writable from inside container. Changing folder owner to ${userid}."
chown -R "${userid}":"${groupid}" "${mountFolder}"
# check permissions on files in the folder
elif [ $(gosu "${userid}":"${groupid}" find "${mountFolder}" -not -writable | wc -l) -gt 0 ]; then
echo "Warning: Some files inside \"${mountFolder}\" are not writable from inside container. Changing folder owner to ${userid}."
chown -R "${userid}":"${groupid}" "${mountFolder}"
fi
else
if [[ ! -w "${mountFolder}" ]] && [[ "$(stat -c %U ${mountFolder})" != "neo4j" ]]; then
print_permissions_advice_and_fail "${mountFolder}"
fi
fi
}
# ==== SETUP WHICH USER TO RUN AS ====
if running_as_root; then
userid="neo4j"
groupid="neo4j"
groups=($(id -G neo4j))
exec_cmd="exec gosu neo4j:neo4j"
else
userid="$(id -u)"
groupid="$(id -g)"
groups=($(id -G))
exec_cmd="exec"
fi
# ==== CHECK LICENSE AGREEMENT ====
if [ "${NEO4J_EDITION}" == "enterprise" ]; then
if [ "${NEO4J_ACCEPT_LICENSE_AGREEMENT:=no}" != "yes" ]; then
echo >&2 "
In order to use Neo4j Enterprise Edition you must accept the license agreement.
(c) Neo4j Sweden AB. 2021. All Rights Reserved.
Use of this Software without a proper commercial license with Neo4j,
Inc. or its affiliates is prohibited.
Email inquiries can be directed to: [email protected]
More information is also available at: https://neo4j.com/licensing/
To accept the license agreement set the environment variable
NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
To do this you can use the following docker argument:
--env=NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
"
exit 1
fi
fi
# ==== ENSURE MOUNT FOLDER READ/WRITABILITY ====
if [ -d /data ]; then
check_mounted_folder_writable_with_chown "/data"
if [ -d /data/databases ]; then
check_mounted_folder_writable_with_chown "/data/databases"
fi
if [ -d /data/dbms ]; then
check_mounted_folder_writable_with_chown "/data/dbms"
fi
if [ -d /data/transactions ]; then
check_mounted_folder_writable_with_chown "/data/transactions"
fi
fi
if [ -d /backups ]; then
check_mounted_folder_writable_with_chown "/backups"
fi
# ==== MAKE SURE NEO4J CANNOT BE RUN FROM THIS CONTAINER ====
rm ${NEO4J_HOME}/bin/neo4j
if [[ "${1}" == "neo4j" ]]; then
correct_image="neo4j:"$(neo4j-admin --version)"-${NEO4J_EDITION}"
echo >&2 "
This is a neo4j-admin only image, and usage of Neo4j server is not supported from here.
If you wish to start a Neo4j database, use:
docker run ${correct_image}
"
exit 1
fi
# ==== START NEO4J-ADMIN COMMAND ====
${exec_cmd} "${@}"
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.2/neo4j-admin/docker-entrypoint.sh:
--------------------------------------------------------------------------------
```bash
#!/bin/bash -eu
function running_as_root
{
test "$(id -u)" = "0"
}
function is_writable
{
gosu "${userid}":"${groupid}" test -w "${1}"
}
function print_permissions_advice_and_fail
{
local _directory=${1}
echo >&2 "
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.
Hints to solve the issue:
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.
2) Pass the folder owner's user ID and group ID to docker run, so that docker runs as that user.
If the folder is owned by the current user, this can be done by adding this flag to your docker run command:
--user=\$(id -u):\$(id -g)
"
exit 1
}
function check_mounted_folder_writable_with_chown
{
local mountFolder=${1}
if running_as_root; then
# check folder permissions
if ! is_writable "${mountFolder}" ; then
# warn that we're about to chown the folder and then chown it
echo "Warning: Folder mounted to \"${mountFolder}\" is not writable from inside container. Changing folder owner to ${userid}."
chown -R "${userid}":"${groupid}" "${mountFolder}"
# check permissions on files in the folder
elif [ $(gosu "${userid}":"${groupid}" find "${mountFolder}" -not -writable | wc -l) -gt 0 ]; then
echo "Warning: Some files inside \"${mountFolder}\" are not writable from inside container. Changing folder owner to ${userid}."
chown -R "${userid}":"${groupid}" "${mountFolder}"
fi
else
if [[ ! -w "${mountFolder}" ]] && [[ "$(stat -c %U ${mountFolder})" != "neo4j" ]]; then
print_permissions_advice_and_fail "${mountFolder}"
fi
fi
}
# ==== SETUP WHICH USER TO RUN AS ====
if running_as_root; then
userid="neo4j"
groupid="neo4j"
groups=($(id -G neo4j))
exec_cmd="exec gosu neo4j:neo4j"
else
userid="$(id -u)"
groupid="$(id -g)"
groups=($(id -G))
exec_cmd="exec"
fi
# ==== CHECK LICENSE AGREEMENT ====
if [ "${NEO4J_EDITION}" == "enterprise" ]; then
if [ "${NEO4J_ACCEPT_LICENSE_AGREEMENT:=no}" != "yes" ]; then
echo >&2 "
In order to use Neo4j Enterprise Edition you must accept the license agreement.
(c) Neo4j Sweden AB. 2021. All Rights Reserved.
Use of this Software without a proper commercial license with Neo4j,
Inc. or its affiliates is prohibited.
Email inquiries can be directed to: [email protected]
More information is also available at: https://neo4j.com/licensing/
To accept the license agreement set the environment variable
NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
To do this you can use the following docker argument:
--env=NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
"
exit 1
fi
fi
# ==== ENSURE MOUNT FOLDER READ/WRITABILITY ====
if [ -d /data ]; then
check_mounted_folder_writable_with_chown "/data"
if [ -d /data/databases ]; then
check_mounted_folder_writable_with_chown "/data/databases"
fi
if [ -d /data/dbms ]; then
check_mounted_folder_writable_with_chown "/data/dbms"
fi
if [ -d /data/transactions ]; then
check_mounted_folder_writable_with_chown "/data/transactions"
fi
fi
if [ -d /backups ]; then
check_mounted_folder_writable_with_chown "/backups"
fi
# ==== MAKE SURE NEO4J CANNOT BE RUN FROM THIS CONTAINER ====
rm ${NEO4J_HOME}/bin/neo4j
if [[ "${1}" == "neo4j" ]]; then
correct_image="neo4j:"$(neo4j-admin --version)"-${NEO4J_EDITION}"
echo >&2 "
This is a neo4j-admin only image, and usage of Neo4j server is not supported from here.
If you wish to start a Neo4j database, use:
docker run ${correct_image}
"
exit 1
fi
# ==== START NEO4J-ADMIN COMMAND ====
${exec_cmd} "${@}"
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/publish-neo4j-admin-image.sh:
--------------------------------------------------------------------------------
```bash
#!/bin/bash
set -eu -o pipefail
EDITIONS=("community" "enterprise")
ROOT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
source "$ROOT_DIR/build-utils-common-functions.sh"
BUILD_DIR=${ROOT_DIR}/build
SRC_DIR=${ROOT_DIR}/docker-image-src
# shellcheck disable=SC2034 # Used in docker-common-functions.sh
TAR_CACHE=${ROOT_DIR}/in
function usage
{
echo >&2 "USAGE: $0 <version> <edition> <operating system> <repository>
For example:
$0 4.4.10 community debian neo/neo4j-admin
$0 5.10.0 enterprise ubi9 neo/neo4j-admin
Version and operating system can also be set in the environment.
For example:
NEO4JVERSION=4.4.10 NEO4JEDITION=community IMAGE_OS=debian REPOSITORY=neo/neo4j-admin $0
NEO4JVERSION=5.10.0 NEO4JEDITION=enterprise IMAGE_OS=ubi9 REPOSITORY=neo/neo4j-admin $0
"
exit 1
}
## ==========================================
## get and sanitise script inputs
if [[ $# -eq 4 ]]; then
NEO4JVERSION=${1}
NEO4JEDITION=${2}
IMAGE_OS=${3}
REPOSITORY=${4}
elif [[ -z ${NEO4JVERSION:-""} ]]; then
echo >&2 "NEO4JVERSION is unset. Either set it in the environment or pass as argument to this script."
usage
elif [[ -z ${NEO4JEDITION:-""} ]]; then
echo >&2 "NEO4JEDITION is unset. Either set it in the environment or pass as argument to this script."
usage
elif [[ -z ${IMAGE_OS:-""} ]]; then
echo >&2 "IMAGE_OS is unset. Either set it in the environment or pass as argument to this script."
usage
elif [[ -z ${REPOSITORY:-""} ]]; then
echo >&2 "REPOSITORY is unset. Either set it in the environment or pass as argument to this script."
usage
fi
# verify edition
if ! contains_element "${NEO4JEDITION}" "${EDITIONS[@]}"; then
echo >&2 "${NEO4JEDITION} is not a supported edition."
usage
fi
# verify compatible neo4j version
if [[ ! "${NEO4JVERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
echo "\"${NEO4JVERSION}\" is not a valid version number."
usage
fi
# get source files
BRANCH=$(get_branch_from_version ${NEO4JVERSION})
DOCKERFILE_NAME=$(get_compatible_dockerfile_for_os_or_error "${BRANCH}" "${IMAGE_OS}")
echo "Building local context for docker build"
ADMIN_LOCALCXT_DIR=${BUILD_DIR}/${IMAGE_OS}/neo4j-admin/${NEO4JEDITION}
mkdir -p ${ADMIN_LOCALCXT_DIR}
# copy neo4j-admin sources
mkdir -p ${ADMIN_LOCALCXT_DIR}/local-package
cp ${SRC_DIR}/common/* ${ADMIN_LOCALCXT_DIR}/local-package
cp "$(cached_tarball "${NEO4JVERSION}" "${NEO4JEDITION}")" ${ADMIN_LOCALCXT_DIR}/local-package/
cp ${SRC_DIR}/${BRANCH}/neo4j-admin/*.sh ${ADMIN_LOCALCXT_DIR}/local-package
# create neo4j-admin Dockerfile
cp "${SRC_DIR}/${BRANCH}/neo4j-admin/${DOCKERFILE_NAME}" "${ADMIN_LOCALCXT_DIR}/Dockerfile"
coredb_sha=$(shasum --algorithm=256 "$(cached_tarball "${NEO4JVERSION}" "${NEO4JEDITION}")" | cut -d' ' -f1)
sed -i -e "s|%%NEO4J_SHA%%|${coredb_sha}|" "${ADMIN_LOCALCXT_DIR}/Dockerfile"
sed -i -e "s|%%NEO4J_TARBALL%%|$(tarball_name ${NEO4JVERSION} ${NEO4JEDITION})|" "${ADMIN_LOCALCXT_DIR}/Dockerfile"
sed -i -e "s|%%NEO4J_EDITION%%|${NEO4JEDITION}|" "${ADMIN_LOCALCXT_DIR}/Dockerfile"
# build and push neo4j-admin
MAJOR=$(get_major_from_version "${NEO4JVERSION}")
full_version_admin_image_tag="${REPOSITORY}:${NEO4JVERSION}-${NEO4JEDITION}-${IMAGE_OS}"
major_minor_admin_image_tag="${REPOSITORY}:${NEO4JVERSION%.*}-${NEO4JEDITION}-${IMAGE_OS}"
major_admin_image_tag="${REPOSITORY}:${MAJOR}-${NEO4JEDITION}-${IMAGE_OS}"
echo "Building neo4j-admin docker image for neo4j-admin-${NEO4JVERSION} ${NEO4JEDITION} on ${IMAGE_OS}."
echo "With tags: ${full_version_admin_image_tag},${major_minor_admin_image_tag},${major_admin_image_tag}"
docker buildx build --tag="${full_version_admin_image_tag}" --tag="${major_minor_admin_image_tag}" --tag="${major_admin_image_tag}" \
--build-arg="NEO4J_URI=file:///startup/$(tarball_name "${NEO4JVERSION}" "${NEO4JEDITION}")" \
"${ADMIN_LOCALCXT_DIR}" --platform linux/amd64,linux/arm64 --push
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/pom.xml:
--------------------------------------------------------------------------------
```
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.neo4j</groupId>
<artifactId>docker-neo4j-tests</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<java.version>17</java.version>
<junit.version>5.11.0</junit.version>
<neo4j.driver.version>5.24.0</neo4j.driver.version>
<surefire.version>3.1.2</surefire.version>
<testcontainers.version>1.20.1</testcontainers.version>
</properties>
<profiles>
<profile>
<!-- This sets what test groups will run by default if you don't specify any maven profiles when running mvn test -->
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<profile.include></profile.include>
<profile.exclude>BundleTest</profile.exclude>
</properties>
</profile>
<profile>
<id>bundle</id>
<properties>
<profile.include>BundleTest</profile.include>
</properties>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire.version}</version>
<configuration>
<groups>${profile.include}</groups>
<excludedGroups>${profile.exclude}</excludedGroups>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<!-- logging library -->
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.32</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.neo4j.driver</groupId>
<artifactId>neo4j-java-driver</artifactId>
<version>${neo4j.driver.version}</version>
<scope>test</scope>
</dependency>
<!-- Gson: Java to Json conversion -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
<scope>test</scope>
</dependency>
<!-- For creating archives of test data -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.24.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/4.4/neo4j-admin/docker-entrypoint.sh:
--------------------------------------------------------------------------------
```bash
#!/bin/bash -eu
# load useful utility functions
. /startup/utilities.sh
function check_mounted_folder_writable_with_chown
{
local mountFolder=${1}
debug_msg "checking ${mountFolder} is writable"
if running_as_root; then
# check folder permissions
if ! is_writable "${mountFolder}" ; then
# warn that we're about to chown the folder and then chown it
echo "Warning: Folder mounted to \"${mountFolder}\" is not writable from inside container. Changing folder owner to ${userid}."
chown -R "${userid}":"${groupid}" "${mountFolder}"
# check permissions on files in the folder
elif [ $(${exec_cmd} find "${mountFolder}" -not -writable | wc -l) -gt 0 ]; then
echo "Warning: Some files inside \"${mountFolder}\" are not writable from inside container. Changing folder owner to ${userid}."
chown -R "${userid}":"${groupid}" "${mountFolder}"
fi
else
if [[ ! -w "${mountFolder}" ]] && [[ "$(stat -c %U ${mountFolder})" != "neo4j" ]]; then
print_permissions_advice_and_fail "${mountFolder}"
fi
fi
}
# ==== SETUP WHICH USER TO RUN AS ====
debug_msg "DEBUGGING ENABLED"
if running_as_root; then
userid="neo4j"
groupid="neo4j"
groups=($(id -G neo4j))
exec_cmd="runuser -p -u neo4j -g neo4j --"
debug_msg "Running as root user inside neo4j-admin image"
else
userid="$(id -u)"
groupid="$(id -g)"
groups=($(id -G))
exec_cmd="exec"
debug_msg "Running as user ${userid} inside neo4j-admin image"
fi
# ==== MAKE SURE NEO4J CANNOT BE RUN FROM THIS CONTAINER ====
debug_msg "checking neo4j was not requested"
if [[ "${1}" == "neo4j" ]]; then
correct_image="neo4j:"$(neo4j-admin --version)"-${NEO4J_EDITION}"
echo >&2 "
This is a neo4j-admin only image, and usage of Neo4j server is not supported from here.
If you wish to start a Neo4j database, use:
docker run ${correct_image}
"
exit 1
fi
# ==== MAKE SURE NEO4J-ADMIN REPORT CANNOT BE RUN FROM THIS CONTAINER ====
debug_msg "checking neo4j-admin report was not requested"
# maybe make sure the command is neo4j-admin server report rather than just anything mentioning reports?
if containsElement "report" "${@}"; then
echo >&2 \
"neo4j-admin report must be run in the same container as neo4j
otherwise the report tool cannot access relevant files and processes required for generating the report.
To run the report tool inside a neo4j container, do:
docker exec <CONTAINER NAME> neo4j-admin-report
"
exit 1
fi
# ==== CHECK LICENSE AGREEMENT ====
debug_msg "checking license"
if [ "${NEO4J_EDITION}" == "enterprise" ]; then
if [ "${NEO4J_ACCEPT_LICENSE_AGREEMENT:=no}" != "yes" ]; then
echo >&2 "
In order to use Neo4j Enterprise Edition you must accept the license agreement.
The license agreement is available at https://neo4j.com/terms/licensing/
If you have a support contract the following terms apply https://neo4j.com/terms/support-terms/
(c) Neo4j Sweden AB. All Rights Reserved.
Use of this Software without a proper commercial license
with Neo4j, Inc. or its affiliates is prohibited.
Neo4j has the right to terminate your usage if you are not compliant.
More information is also available at: https://neo4j.com/licensing/
If you have further inquiries about licensing, please contact us via https://neo4j.com/contact-us/
To accept the commercial license agreement set the environment variable
NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
To do this you can use the following docker argument:
--env=NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
"
exit 1
fi
fi
# ==== ENSURE MOUNT FOLDER READ/WRITABILITY ====
debug_msg "Checking for mounted folder writability"
if [ -d /data ]; then
check_mounted_folder_writable_with_chown "/data"
if [ -d /data/databases ]; then
check_mounted_folder_writable_with_chown "/data/databases"
fi
if [ -d /data/dbms ]; then
check_mounted_folder_writable_with_chown "/data/dbms"
fi
if [ -d /data/transactions ]; then
check_mounted_folder_writable_with_chown "/data/transactions"
fi
fi
if [ -d /backups ]; then
check_mounted_folder_writable_with_chown "/backups"
fi
# ==== START NEO4J-ADMIN COMMAND ====
if debugging_enabled; then
echo ${exec_cmd} "${@}" --verbose
${exec_cmd} "${@}" --verbose
else
${exec_cmd} "${@}"
fi
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/src/test/java/com/neo4j/docker/coredb/TestCausalCluster.java:
--------------------------------------------------------------------------------
```java
package com.neo4j.docker.coredb;
import com.neo4j.docker.utils.SetContainerUser;
import com.neo4j.docker.utils.TemporaryFolderManager;
import com.neo4j.docker.utils.TestSettings;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.neo4j.driver.*;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.testcontainers.containers.DockerComposeContainer;
import org.testcontainers.containers.wait.strategy.*;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
@Disabled
public class TestCausalCluster
{
private static final int DEFAULT_BOLT_PORT = 7687;
@RegisterExtension
public static TemporaryFolderManager temporaryFolderManager = new TemporaryFolderManager();
@Disabled
@Test
void testCausalClusteringBasic() throws Exception
{
Assumptions.assumeTrue(TestSettings.EDITION == TestSettings.Edition.ENTERPRISE,
"No causal clustering for community edition");
Path tmpDir = temporaryFolderManager.createFolder( "CC_cluster_" );
File compose_file = new File(tmpDir.toString(), "causal-cluster-compose.yml");
Files.copy(getResource("causal-cluster-compose.yml"), Paths.get(compose_file.getPath()));
Files.createDirectories( tmpDir.resolve( "core1" ) );
Files.createDirectories( tmpDir.resolve( "core2" ) );
Files.createDirectories( tmpDir.resolve( "core3" ) );
Files.createDirectories( tmpDir.resolve( "readreplica1" ) );
String content = new String(Files.readAllBytes(Paths.get(compose_file.getPath())));
String[] contentLines = content.split(System.getProperty("line.separator"));
String[] editedLines = new String[contentLines.length];
int i = 0;
for (String line : contentLines) {
editedLines[i] = line.replaceAll("%%IMAGE%%", TestSettings.IMAGE_ID.asCanonicalNameString());
editedLines[i] = editedLines[i].replaceAll("%%LOGS_DIR%%", tmpDir.toAbsolutePath().toString());
editedLines[i] = editedLines[i].replaceAll("%%USERIDGROUPID%%", SetContainerUser.getNonRootUserString());
i++;
}
String editedContent = String.join("\n", editedLines);
DataOutputStream outstream = new DataOutputStream(new FileOutputStream(compose_file,false));
outstream.write(editedContent.getBytes());
outstream.close();
System.out.println("logs: " + compose_file.getName() + " and " + tmpDir.toString());
DockerComposeContainer clusteringContainer = new DockerComposeContainer(compose_file)
.withLocalCompose(true)
.withExposedService("core1", DEFAULT_BOLT_PORT )
.withExposedService("core1", 7474,
Wait.forHttp( "/" )
.forPort( 7474 )
.forStatusCode( 200 )
.withStartupTimeout( Duration.ofSeconds( 300 ) ))
.withExposedService("readreplica1", DEFAULT_BOLT_PORT);
clusteringContainer.start();
String core1Uri = "bolt://" + clusteringContainer.getServiceHost("core1", DEFAULT_BOLT_PORT)
+ ":" +
clusteringContainer.getServicePort("core1", DEFAULT_BOLT_PORT);
String rrUri = "bolt://" + clusteringContainer.getServiceHost("readreplica1", DEFAULT_BOLT_PORT)
+ ":" +
clusteringContainer.getServicePort("readreplica1", DEFAULT_BOLT_PORT);
try ( Driver coreDriver = GraphDatabase.driver( core1Uri, AuthTokens.basic( "neo4j", "neo")))
{
Session session = coreDriver.session();
Result rs = session.run( "CREATE (arne:dog {name:'Arne'})-[:SNIFFS]->(bosse:dog {name:'Bosse'}) RETURN arne.name");
Assertions.assertEquals( "Arne", rs.single().get( 0 ).asString(), "did not receive expected result from cypher CREATE query" );
}
catch (Exception e)
{
clusteringContainer.stop();
return;
}
try ( Driver rrDriver = GraphDatabase.driver(rrUri, AuthTokens.basic("neo4j", "neo")))
{
Session session = rrDriver.session();
Result rs = session.run( "MATCH (a:dog)-[:SNIFFS]->(b:dog) RETURN a.name");
Assertions.assertEquals( "Arne", rs.single().get( 0 ).asString(), "did not receive expected result from cypher MATCH query" );
}
catch (Exception e)
{
clusteringContainer.stop();
return;
}
clusteringContainer.stop();
}
private InputStream getResource(String path) {
InputStream resource = getClass().getClassLoader().getResourceAsStream(path);
return resource;
}
}
```
--------------------------------------------------------------------------------
/neo4j/docker-neo4j/docker-image-src/5/neo4j-admin/docker-entrypoint.sh:
--------------------------------------------------------------------------------
```bash
#!/bin/bash -eu
# load useful utility functions
. /startup/utilities.sh
function check_mounted_folder_writable_with_chown
{
local mountFolder=${1}
debug_msg "checking ${mountFolder} is writable"
if running_as_root; then
# check folder permissions
if ! is_writable "${mountFolder}" ; then
# warn that we're about to chown the folder and then chown it
echo "Warning: Folder mounted to \"${mountFolder}\" is not writable from inside container. Changing folder owner to ${userid}."
chown -R "${userid}":"${groupid}" "${mountFolder}"
# check permissions on files in the folder
elif [ $(${exec_cmd} find "${mountFolder}" -not -writable | wc -l) -gt 0 ]; then
echo "Warning: Some files inside \"${mountFolder}\" are not writable from inside container. Changing folder owner to ${userid}."
chown -R "${userid}":"${groupid}" "${mountFolder}"
fi
else
if [[ ! -w "${mountFolder}" ]] && [[ "$(stat -c %U ${mountFolder})" != "neo4j" ]]; then
print_permissions_advice_and_fail "${mountFolder}" "${userid}" "${groupid}"
fi
fi
}
# ==== SETUP WHICH USER TO RUN AS ====
debug_msg "DEBUGGING ENABLED"
if running_as_root; then
userid="neo4j"
groupid="neo4j"
groups=($(id -G neo4j))
exec_cmd="runuser -p -u neo4j -g neo4j --"
debug_msg "Running as root user inside neo4j-admin image"
else
userid="$(id -u)"
groupid="$(id -g)"
groups=($(id -G))
exec_cmd="exec"
debug_msg "Running as user ${userid} inside neo4j-admin image"
fi
#%%DEPRECATION_WARNING_PLACEHOLDER%%
# ==== MAKE SURE NEO4J CANNOT BE RUN FROM THIS CONTAINER ====
debug_msg "checking neo4j was not requested"
if [[ "${1}" == "neo4j" ]]; then
correct_image="neo4j:"$(neo4j-admin --version)"-${NEO4J_EDITION}"
echo >&2 "
This is a neo4j-admin only image, and usage of Neo4j server is not supported from here.
If you wish to start a Neo4j database, use:
docker run ${correct_image}
"
exit 1
fi
# ==== MAKE SURE NEO4J-ADMIN REPORT CANNOT BE RUN FROM THIS CONTAINER ====
debug_msg "checking neo4j-admin report was not requested"
# maybe make sure the command is neo4j-admin server report rather than just anything mentioning reports?
if containsElement "report" "${@}"; then
echo >&2 \
"neo4j-admin report must be run in the same container as neo4j
otherwise the report tool cannot access relevant files and processes required for generating the report.
To run the report tool inside a neo4j container, do:
docker exec <CONTAINER NAME> neo4j-admin-report
"
exit 1
fi
# ==== CHECK LICENSE AGREEMENT ====
debug_msg "checking license"
# Only prompt for license agreement if command contains "neo4j" in it
if [[ "${1}" == *"neo4j"* ]]; then
if [ "${NEO4J_EDITION}" == "enterprise" ]; then
: ${NEO4J_ACCEPT_LICENSE_AGREEMENT:="not accepted"}
if [[ "$NEO4J_ACCEPT_LICENSE_AGREEMENT" != "yes" && "$NEO4J_ACCEPT_LICENSE_AGREEMENT" != "eval" ]]; then
echo >&2 "
In order to use Neo4j Enterprise Edition you must accept the license agreement.
The license agreement is available at https://neo4j.com/terms/licensing/
If you have a support contract the following terms apply https://neo4j.com/terms/support-terms/
If you do not have a commercial license and want to evaluate the Software
please read the terms of the evaluation agreement before you accept.
https://neo4j.com/terms/enterprise_us/
(c) Neo4j Sweden AB. All Rights Reserved.
Use of this Software without a proper commercial license, or evaluation license
with Neo4j, Inc. or its affiliates is prohibited.
Neo4j has the right to terminate your usage if you are not compliant.
More information is also available at: https://neo4j.com/licensing/
If you have further inquiries about licensing, please contact us via https://neo4j.com/contact-us/
To accept the commercial license agreement set the environment variable
NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
To accept the terms of the evaluation agreement set the environment variable
NEO4J_ACCEPT_LICENSE_AGREEMENT=eval
To do this you can use the following docker argument:
--env=NEO4J_ACCEPT_LICENSE_AGREEMENT=<yes|eval>
"
exit 1
fi
fi
fi
# ==== ENSURE MOUNT FOLDER READ/WRITABILITY ====
debug_msg "Checking for mounted folder writability"
if [ -d /data ]; then
check_mounted_folder_writable_with_chown "/data"
if [ -d /data/databases ]; then
check_mounted_folder_writable_with_chown "/data/databases"
fi
if [ -d /data/dbms ]; then
check_mounted_folder_writable_with_chown "/data/dbms"
fi
if [ -d /data/transactions ]; then
check_mounted_folder_writable_with_chown "/data/transactions"
fi
fi
if [ -d /backups ]; then
check_mounted_folder_writable_with_chown "/backups"
fi
# ==== START NEO4J-ADMIN COMMAND ====
if debugging_enabled; then
echo ${exec_cmd} "${@}" --verbose
${exec_cmd} "${@}" --verbose
else
${exec_cmd} "${@}"
fi
```