Model or dataset
docker/genai-stack avatar
docker/genai-stack

docker/genai-stack: a runnable LangChain, Neo4j and Ollama reference stack

Langchain + Docker + Neo4j + Ollama

5,412 stars1,237 forksPythonCC0-1.0

At a glance

What is it?
The GenAI Stack wires a support bot, a Stack Overflow loader, a PDF reader and a standalone streaming API into one docker compose project. It is a teaching scaffold for retrieval augmented generation, not a production service.
Who is it for?
Adopt it if you want a working LangChain plus Neo4j plus Ollama example to read and modify, and you accept that the compose file is the specification. Do not adopt it as a production support system: the default Neo4j password is password, the data volume is bound to $PWD/data, and the README documents no upgrade path between Neo4j 5.26 and a later major.
Can I use it commercially?
Yes. CC0-1.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 27 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What docker/genai-stack actually gives you

This is a reference application, not a library. The repository exists so that a developer can see retrieval augmented generation working end to end without assembling LangChain, a vector store, an LLM runtime and a UI from scratch. The README calls the demo applications "inspiration or a starting point", which is an accurate description of the scope.

The target reader is someone who already knows Python and Docker and wants to understand how a knowledge graph and a vector index cooperate inside one retrieval pipeline. Five applications ship in the repository: a support bot on port 8501, a Stack Overflow loader on 8502, a PDF reader on 8503, a standalone HTTP API with server-sent events on 8504, and a Svelte front end on 8505. Neo4j Browser sits on 7474.

The support bot is the main use case, and the README frames it as a comparison: RAG disabled returns a pure LLM answer, RAG enabled adds vector and knowledge graph context. That toggle is the reason to open the repository at all. Everything else is plumbing around it.

How the retrieval pipeline is put together

The loader is the entry point for data. According to the README, it imports recent Stack Overflow data for chosen tags into a knowledge graph, embeds questions and answers, and stores those embeddings in a vector index. A second pass loads high ranked questions regardless of tag, which feeds the ticket generation feature in the support bot.

At query time the bot retrieves from both structures. The vector index supplies semantically similar text; the graph supplies relationships that a flat embedding store cannot express. The README describes the result as "summarized answers with sources", so citations come from the retrieved nodes rather than from the model.

The model layer is pluggable through environment variables. LLM accepts any Ollama model tag, or gpt-4, gpt-3.5 or claudev2. EMBEDDING_MODEL accepts sentence_transformer, openai, aws, ollama or google-genai-embedding-001. Each choice pulls in a different dependency from requirements.txt: langchain-ollama, langchain-openai, langchain-aws, langchain-google-genai or langchain-huggingface. That is a real design decision, and it is also where the stack gets heavy, since all five provider packages are pinned in one requirements file whether you use them or not.

The compose file shows the rest. Neo4j runs as image neo4j:5.26 with the apoc plugin, NEO4J_AUTH built from NEO4J_USERNAME and NEO4J_PASSWORD, and unrestricted apoc procedures. The loader mounts $PWD/embedding_model into the container, which is how the sentence transformer weights persist between runs.

Installing and running the stack for the first time

The README says to create a .env file from env.example. The compose file supplies defaults for every variable, but the defaults point at a Neo4j instance with the password password, so set your own values before anything else.

A minimal .env for a Mac or Linux host using Ollama looks like this. OLLAMA_BASE_URL must point at a reachable Ollama API, and LLM must be a valid Ollama tag.

bash
cp env.example .env
# then edit .env
# OLLAMA_BASE_URL=http://host.docker.internal:11434
# NEO4J_URI=neo4j://database:7687
# NEO4J_USERNAME=neo4j
# NEO4J_PASSWORD=password
# LLM=llama2
# EMBEDDING_MODEL=sentence_transformer

On macOS and Windows the README instructs you to install Ollama and start it in a separate terminal with ollama serve before bringing up the stack. On Linux you can skip the manual install and let the profile run Ollama in a container, but then you must change OLLAMA_BASE_URL to http://llm:11434. For GPU passthrough the profile is linux-gpu and the URL becomes http://llm-gpu:11434.

Start everything with the command below. The README warns that Docker Desktop 4.24.x has a performance issue affecting Python applications in this stack, so upgrade before you try it.

bash
docker compose up

After the containers are healthy, open http://localhost:8502 and run the loader for a tag you care about. It reports progress and shows statistics for what landed in the database. Then open http://localhost:8501, ask a support question with RAG disabled, and ask the same question with RAG enabled. The difference between the two answers is the thing this repository is built to demonstrate. The database itself is browsable at http://localhost:7474.

Where the stack will disappoint you

The default configuration is not safe to expose. NEO4J_AUTH falls back to neo4j/password, and the compose file publishes both 7687 and 7474 on the host. If you run this on a machine with a public interface and leave the defaults, you have an open graph database. The README does not discuss this.

The data directory is bound to $PWD/data, so the database lives in whatever directory you ran compose from. Move the project, or run it from a different shell path, and you get a fresh empty Neo4j. There is no named volume and no documented backup procedure.

Version pinning is uneven. Streamlit is pinned to 1.32.1 and the LangChain provider packages carry exact versions, but the Ollama image is ollama/ollama:latest. A pull can change the runtime under you. The README also documents no upgrade path for the Neo4j 5.26 container, and no migration story if you later move to a different major version.

The loader's data source is Stack Overflow, which makes the support bot a demo about programming questions. Point it at your own corpus and you are writing new ingestion code, not configuring the existing one. The README does not document rollback for a bad import either, so a mistaken tag run means deleting nodes by hand in Neo4j Browser.

Finally, this is a single-host development stack. Nothing in the compose file describes replication, TLS, authentication in front of the Streamlit apps, or a reverse proxy. It is the wrong tool for a customer-facing deployment.

The alternative: a plain vector store with no graph

The obvious comparison is a retrieval pipeline built on a vector database alone, using something like Chroma or pgvector behind LangChain with no graph layer. That approach stores chunks and embeddings and retrieves by similarity. It is simpler to operate: one datastore, no Cypher, no APOC plugin, no graph schema to design.

The difference that matters is what the retrieval can express. In this stack the loader writes Stack Overflow questions and answers into a knowledge graph and simultaneously embeds them, so a query can follow relationships between nodes as well as compare vectors. The support bot's ticket generation feature depends on that: the README says it drafts a ticket "based on the style of highly rated questions in the database", which is a query over ranked nodes, not a nearest-neighbour lookup.

If your retrieval is genuinely flat, meaning you only ever want the top-k most similar chunks, the graph adds operational cost for no benefit. If you want to filter by relationship, rank, or provenance across linked entities, a vector-only store forces you to denormalize that information into metadata and filter on it. That is the trade-off, and the stack sits on one side of it deliberately.

Maintenance, licence and the cost of keeping it running

The repository is not archived, and the last push was on 2026-09-03. There are no retrieved releases, so there is no tagged version to pin against. You track main.

That has a concrete consequence. Without releases, you cannot diff between versions to see what changed, and you cannot roll back to a known good commit without doing it yourself. For a reference stack this is tolerable. For anything you build on top, fork it and pin your fork.

The dependencies are the real maintenance surface. requirements.txt pins langchain-openai 0.3.8, langchain-community 0.3.19, langchain-google-genai 2.0.11, langchain-ollama 0.2.3, langchain-huggingface 0.1.2, langchain-aws 0.2.15 and langchain-neo4j 0.4.0. LangChain provider packages move quickly and their APIs change between minor versions, so any upgrade here is a code change in chains.py or utils.py, not just a version bump.

The licence is CC0-1.0, which places the work in the public domain. That is unusually permissive for a project of this kind, and it means you can copy code out of it into a commercial product without an attribution requirement. It is not legal advice, and it does not cover the third-party dependencies or the models you point it at. The Stack Overflow data the loader imports carries its own terms, and the Ollama model tags you choose carry their own licences. Those are the things to check before shipping anything derived from this.

Editorial conclusion

Adopt it if you want a working LangChain plus Neo4j plus Ollama example to read and modify, and you accept that the compose file is the specification. Do not adopt it as a production support system: the default Neo4j password is password, the data volume is bound to $PWD/data, and the README documents no upgrade path between Neo4j 5.26 and a later major. Before you build on it, check the .env values for NEO4J_URI, OLLAMA_BASE_URL and LLM, and confirm the Neo4j 5.26 container starts its health check on port 7474.

Frequently asked questions

What is docker/genai-stack?

It is a Docker Compose reference stack that combines LangChain, Neo4j and Ollama to demonstrate retrieval augmented generation, shipping a support bot, a Stack Overflow loader, a PDF reader, a standalone streaming API and a Svelte front end.

How do I install and run docker/genai-stack?

Copy env.example to .env, set OLLAMA_BASE_URL, NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD, LLM and EMBEDDING_MODEL, then run docker compose up. On Linux you can instead run docker compose --profile linux up and point OLLAMA_BASE_URL at http://llm:11434.

Which ports does the GenAI Stack expose?

The README lists the support bot on 8501, the loader on 8502, the PDF reader on 8503, the standalone API on 8504, the front end on 8505, and Neo4j Browser on 7474. The compose file also publishes the Neo4j Bolt port 7687.

Can docker/genai-stack use OpenAI or Claude instead of Ollama?

Yes. The README states the LLM variable accepts gpt-4, gpt-3.5 or claudev2 in addition to any Ollama model tag, and that Windows users can generate an OpenAI API key instead of installing Ollama. AWS credentials are required only when LLM is claudev2 or the embedding model is aws.

Does docker/genai-stack need a GPU?

No. The linux-gpu profile exists for NVIDIA passthrough and uses OLLAMA_BASE_URL=http://llm-gpu:11434, but the plain linux profile runs Ollama in a container without a GPU reservation, and macOS and Windows users run Ollama on the host.

Official sources

  1. docker/genai-stack on GitHub
  2. Issues
  3. License: CC0-1.0
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/docker-genai-stack.svg)](https://hysenlabs.com/projects/docker-genai-stack)