# Local stand-ins for the AWS services, for development and local mode only. # # docker compose -f docker/compose.local.yaml up -d --wait # stores # docker compose -f docker/compose.local.yaml --profile models up -d --wait # + Ollama # docker compose -f docker/compose.local.yaml down -v # # - OpenSearch: single node, security plugin disabled (plain http, no auth), # with the analysis-nori plugin that the Korean text mappings use (an Amazon # OpenSearch Service domain has it only once its optional Nori package is # associated; the IaC maps Korean to the built-in cjk analyzer instead). # Version matches the IaC domain. # - Gremlin Server: in-memory TinkerGraph over plain ws:// with no auth. Its # TinkerPop line (3.7) matches the gremlinpython client. Its init script # indexes the "id" property the indexer looks vertices and edges up by, and # its graph takes string vertex ids (indexing.neptune.vertex_ids: custom). # TinkerGraph has no transactions: keep indexing.neptune.index_concurrency # at 1 (the default), or a retried edge rewrite can leave a duplicate edge. # # - Ollama (profile "models", so the stores alone start without it): serves # the language and embedding models of local mode. No model is pulled # automatically; pull the ones docker/config.local.yaml names, e.g. # docker compose -f docker/compose.local.yaml exec ollama ollama pull qwen2.5:7b-instruct # docker compose -f docker/compose.local.yaml exec ollama ollama pull bge-m3 # Models persist in the ollama-models volume. CPU only as written; for an # NVIDIA GPU add a `gpus: all` key to the service (needs the NVIDIA # Container Toolkit), or run Ollama on the host instead. # # docker/config.local.yaml points the framework at them. Each container # drops all Linux capabilities and cannot gain privileges, but the stores # have no auth or TLS: ports bind to 127.0.0.1 only, the graph lives in # memory, and the OpenSearch and model volumes are removed by `down -v`. name: unified-kg-rag-local services: opensearch: build: dockerfile_inline: | FROM opensearchproject/opensearch:2.13.0@sha256:2e954ff0e8c9d0f4868b4818150b3aecc92fbb0cc4a24d00dace38ada227291d RUN /usr/share/opensearch/bin/opensearch-plugin install --batch analysis-nori environment: discovery.type: single-node DISABLE_SECURITY_PLUGIN: "true" DISABLE_INSTALL_DEMO_CONFIG: "true" OPENSEARCH_JAVA_OPTS: -Xms1g -Xmx1g security_opt: ["no-new-privileges:true"] cap_drop: [ALL] ports: - 127.0.0.1:9200:9200 volumes: - opensearch-data:/usr/share/opensearch/data healthcheck: test: ["CMD-SHELL", "curl -fs http://localhost:9200/_cluster/health?wait_for_status=yellow"] interval: 5s timeout: 5s retries: 30 gremlin-server: image: tinkerpop/gremlin-server:3.7.7@sha256:afc395b5e96cfeea72b6d0b59d22ad5cee502c31bfdad6f4d3b2de070d905e0f security_opt: ["no-new-privileges:true"] cap_drop: [ALL] ports: - 127.0.0.1:8182:8182 configs: # Replaces the image's init script (which only binds "g"). Every # indexer write finds its vertex or edge by the "id" property first; # without an index TinkerGraph scans them all for each lookup (10,000 # entities and their communities: about 60 s instead of 20 s). - source: gremlin-init target: /opt/gremlin-server/scripts/empty-sample.groovy # The image's graph takes Long vertex ids only; ANY also takes the # string ids of vertex_ids: custom (and still generates Longs). - source: gremlin-graph target: /opt/gremlin-server/conf/tinkergraph-empty.properties healthcheck: test: ["CMD-SHELL", "bash -c 'exec 3<>/dev/tcp/$$(hostname -i)/8182'"] interval: 5s timeout: 5s retries: 30 ollama: image: ollama/ollama:0.40.13@sha256:b2f0122c476bc9fe7ce679d8bb4bd555351e25e2554eefb156f61cb0a89cf429 profiles: ["models"] environment: # Keep a model loaded between the pipeline's bursts of calls. OLLAMA_KEEP_ALIVE: 30m security_opt: ["no-new-privileges:true"] cap_drop: [ALL] ports: - 127.0.0.1:11434:11434 volumes: - ollama-models:/root/.ollama healthcheck: test: ["CMD", "ollama", "list"] interval: 5s timeout: 5s retries: 30 configs: gremlin-init: content: | graph.createIndex("id", Vertex.class) graph.createIndex("id", Edge.class) def globals = [:] globals << [g : traversal().withEmbedded(graph)] gremlin-graph: content: | gremlin.graph=org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph gremlin.tinkergraph.vertexIdManager=ANY volumes: opensearch-data: ollama-models: