{"id":16162489,"url":"https://github.com/sunsided/janusgraph-docker","last_synced_at":"2025-06-23T15:35:02.557Z","repository":{"id":141992928,"uuid":"97633308","full_name":"sunsided/janusgraph-docker","owner":"sunsided","description":"Yet another JanusGraph, Cassandra/Scylla and Elasticsearch in Docker Compose setup","archived":false,"fork":false,"pushed_at":"2020-03-05T13:01:08.000Z","size":182,"stargazers_count":59,"open_issues_count":0,"forks_count":24,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-02T19:41:34.350Z","etag":null,"topics":["cassandra","cypher","cypher-query-language","docker","docker-compose","elasticsearch","graph-database","gremlin","janusgraph","scylla","tinkerpop","titan"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sunsided.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-07-18T18:57:09.000Z","updated_at":"2024-12-14T15:34:59.000Z","dependencies_parsed_at":"2024-04-18T08:03:41.575Z","dependency_job_id":null,"html_url":"https://github.com/sunsided/janusgraph-docker","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sunsided/janusgraph-docker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunsided%2Fjanusgraph-docker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunsided%2Fjanusgraph-docker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunsided%2Fjanusgraph-docker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunsided%2Fjanusgraph-docker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sunsided","download_url":"https://codeload.github.com/sunsided/janusgraph-docker/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunsided%2Fjanusgraph-docker/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261505178,"owners_count":23168973,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cassandra","cypher","cypher-query-language","docker","docker-compose","elasticsearch","graph-database","gremlin","janusgraph","scylla","tinkerpop","titan"],"created_at":"2024-10-10T02:30:21.680Z","updated_at":"2025-06-23T15:35:02.531Z","avatar_url":"https://github.com/sunsided.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JanusGraph (in Docker) - Lessons learned\n\n![JanusGraph logo](.readme/janusgraph.png)\n\nDocker deployment of [JanusGraph](http://janusgraph.org/). To run,\n\n```bash\ndocker-compose up --build\n```\n\nNote that a version of [Docker Compose](https://github.com/docker/compose) with support for version `3` schemas is required, e.g. `1.15.0` or newer.\n\nAfterwards, you can connect to the local Gremlin shell using\n\n```bash\ndocker-compose exec janus ./bin/gremlin.sh\n```\n\nThe `python-test` subdirectories contains some simplistic Python scripts to test communication with JanusGraph.\n\nSources for the `Dockerfile` and their surroundings were basically taken straight from Titan setups:\n\n* [efaurie/docker-titan-cassandra](https://github.com/efaurie/docker-titan-cassandra)\n* [elubow/titan-gremlin](https://github.com/elubow/titan-gremlin)\n\nFor multiple graphs in Titan (and likely also JanusGraph), follow these links:\n\n* [How many graphs can i create in one Titan DB?](https://stackoverflow.com/a/40545537/195651)\n* [Serving multiple Titan graphs over Gremlin Server (TinkerPop 3)](https://medium.com/@jbmusso/serving-multiple-titan-graphs-over-gremlin-server-tinkerpop-3-d3c971d07964)\n* [One graph in one Titan instance](https://jaceklaskowski.gitbooks.io/titan-scala/content/one_graph_in_one_titan_instance.html)\n\n## Scylla/Cassandra and Elasticsearch\n\nAs per [compatibility matrix](https://docs.janusgraph.org/changelog/#version-compatibility-matrix), the supported Cassandra version is 3.11 and the supported Elasticsearch version is 6.6.\nThis repository uses [Scylla](http://www.scylladb.com/) instead of Cassandra, and according to the [Scylla Cassandra Compatibility](http://docs.scylladb.com/cassandra-compatibility/) matrix we find that Scylla 3.0 is a drop-in replacement for Cassandra 3.11.\n\nThe latest commit using Cassandra in this repo is 39c537de03a1bb7a65138b535df1ff003e8c4ec6, if you are interested in that.\n\n## Gremlin Shell\n\n![](.readme/gremlin.png)\n\nThis Docker example loads an [airline graph](janusgraph/data/air-routes-small.graphml) and\nexposes it as graph `g` in `scripts/airlines-sample.groovy`.\n\nAfter opening the Gremlin shell in Docker by running e.g.\n\n```bash\ndocker-compose exec janus ./bin/gremlin.sh\n```\n\nYou should be greeted by the Gremlin REPL shell:\n\n```\n         \\,,,/\n         (o o)\n-----oOOo-(3)-oOOo-----\nplugin activated: tinkerpop.server\nplugin activated: tinkerpop.hadoop\nplugin activated: tinkerpop.utilities\nplugin activated: aurelius.titan\nplugin activated: tinkerpop.tinkergraph\ngremlin\u003e\n```\n\nFrom here, connect to JanusGraph with a session, then forward all commands\nto the remote server using `:remote console` (this allows skipping the `:\u003e` syntax that's\nrequired otherwise):\n\n```\n:remote connect tinkerpop.server conf/remote.yaml session\n:remote console\n```\n\nYou will find the airlines data exposed as graph `g`. We can inspect the vertex count by running e.g.\n\n```\ng.V().count()\n```\n\nThis should return a value of `47`. Note that after restarting, the graph is imported again, resulting in\ndata duplication. To drop all vertices and edges - and then re-import from scratch - we can run\n\n```\ng.V().drop().iterate()\nairlines.io(graphml()).readGraph('data/air-routes-small.graphml')\ng.tx().commit()\n```\n\nTo build an index over the `code` property, run\n\n```\nmgmt = airlines.openManagement()\ncode = mgmt.getPropertyKey('code')\nmgmt.buildIndex('byCodeUnique', Vertex.class).addKey(code).unique().buildCompositeIndex()\nmgmt.commit()\nairlines.tx().commit()\n```\n\nWe can then - for example - get all properties of the vertex with code `JFK`:\n\n```\ng.V().has('code', 'JFK').valueMap()\n```\n\nThis should return:\n\n```\n==\u003e{code=[JFK], type=[airport], desc=[New York John F. Kennedy International Airport], country=[US], longest=[14511], city=[New York], elev=[12], icao=[KJFK], lon=[-73.77890015], region=[US-NY], runways=[4], lat=[40.63980103]}\n```\n\nWe could now run path queries, e.g. [find a path](http://tinkerpop.apache.org/docs/3.0.0-incubating/#simplepath-step)\nbetween _Honolulu International_ and _Houston Hobby_ and return the airport codes and city names:\n\n```\ng.V().has('code', 'HNL').repeat(out().simplePath()).until(has('code', 'HOU')).path().by(valueMap('code', 'city')).limit(1)\n```\n\nThis should return:\n\n```\n==\u003epath[{code=[HNL], city=[Honolulu]}, {code=[DFW], city=[Dallas]}, {code=[HOU], city=[Houston]}]\n```\n\nTo leave the shell, type `:quit`.\n\n## Channelizers\n\nYou [have to choose the Channelizer](https://docs.janusgraph.org/basics/server/#janusgraph-server-as-both-a-websocket-and-http-endpoint) to work with, e.g. `HttpChannelizer`, `WebSocketChannelizer` or `WsAndHttpChannelizer`/`JanusGraphWsAndHttpChannelizer`.\n\nUsing the `JanusGraphWsAndHttpChannelizer`\n\n```yaml\nchannelizer: org.janusgraph.channelizers.JanusGraphWsAndHttpChannelizer\n```\n\nallows for HTTP access to JanusGraph, allowing to e.g. determine `100 - 1` (hint: it's `99`)\n\n```bash\ncurl \"http://localhost:8182/?gremlin=100-1\"\n```\n\nor running complete queries (URL encoded):\n\n```bash\ncurl http://localhost:8182/?gremlin=g.V().has(%27code%27,%20%27JFK%27).valueMap()\n```\n\n... which is a bit clearer when using a JSON `POST`:\n\n```bash\ncurl -X POST http://localhost:8182/ \\\n  -H 'Content-Length: 52' \\\n  -H 'Content-Type: application/json' \\\n  -H 'Host: localhost:8182' \\\n  -d '{ \"gremlin\": \"g.V().has('\\''code'\\'', '\\''JFK'\\'').valueMap()\" }'\n```\n\n## Python connectivity\n\nTo test connectivity with Python, try out the scripts in the [`python-test/`](python-test/) directory.\nA conda environment is provided in [environment.yaml](python-test/environment.yaml):\n\n```bash\nconda env create -f environment.yaml\nconda activate janusgraph\n```\n\nTry running the [gremlinpython](https://pypi.org/project/gremlinpython/) example:\n\n```bash\npython test_gremlin_python.py\n```\n\nThis should output:\n\n```\nHop 1: HNL - Honolulu\nHop 2: DFW - Dallas\nHop 3: HOU - Houston\n```\n\nNote that the [aiogremlin](https://aiogremlin.readthedocs.io/en/latest/) example is notoriously\nbroken; that's presumably because the package lags behind the TinkerPop version quite a bit.\n\n## Cypher support\n\nWith [Cypher for Gremlin](https://github.com/opencypher/cypher-for-gremlin) (Opencypher), you can query Janusgraph using\nthe Cypher query language originating from Neo4j.\nThis repo provides a configuration that installs the required plugins.\n\n![Cypher for Gremlin](.readme/cypher-gremlin.svg)\n\nNote that while the examples in this section work out of the box, some Java drivers will fail with\nserialization issues such as `Encountered unregistered class ID: 65536`.\nThis happens especially in Gremlin- or Cypher-enabled applications that do not register JanusGraph's serializers,\ne.g. in the Intellij [Graph Database support](https://plugins.jetbrains.com/plugin/8087-graph-database-support) plugin (see [this ticket](https://github.com/neueda/jetbrains-plugin-graph-database-support/issues/162)).\nIn order to have Cypher support working in those situations, you will need to \"undo\" Janusgraph specifics by doing the following changes.\n\nIn `gremlin-server.yaml`, replace\n\n- `org.janusgraph.channelizers.JanusGraphWsAndHttpChannelizer` with `org.apache.tinkerpop.gremlin.server.channel.WsAndHttpChannelizer`, and\n- `org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry` with `org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3d0`.\n\nThen, **use the GraphSON v3 serializer**, since both Gyro and GraphBinary will require\nyou to register the exact types. After this, you should be good to go.\n\n### Using the Cypher Traversal Source\n\nTo use Cypher alongside with Gremlin, connect to the Gremlin console and run:\n\n```\n:plugin use opencypher.gremlin\ng = EmptyGraph.instance().traversal(CypherTraversalSource.class).withRemote('conf/remote-airlines.properties')\n```\n\nNext, run your Cypher command using `g.cypher()`:\n\n```\ng.cypher('MATCH (p:airport) RETURN p.desc AS name')\n```\n\nYou can also mix and match Cypher and Gremlin:\n\n```\ng.cypher('MATCH (p:airport) RETURN p').select('p').by(valueMap().select('desc').project('name')).dedup()\n```\n\nOr only use Gremlin:\n\n```\ng.V().hasLabel('airport').as('p').select('p').by(valueMap().select('desc').project('name')).dedup()\n```\n\n### Using Cypher directly (in the Gremlin Shell)\n\nIn the Gremlin shell, you can also run Cypher queries directly. To do so, run\n\n```\n:plugin use opencypher.gremlin\n:remote connect opencypher.gremlin conf/remote-objects.yaml translate gremlin\n```\n\nAlternatively, server-side translations can be used (note the `:remote config alias g airlines` command!):\n\n```\n:plugin use opencypher.gremlin\n:remote connect opencypher.gremlin conf/remote-objects.yaml\n:remote config alias g airlines\n```\n\nYou can then run Cypher commands directly on the remote source:\n\n```\n:\u003e MATCH (p:airport) RETURN p.desc AS name\n```\n\nNote that `:remote console` does not work in this case.\n\nThe Cypher `EXPLAIN` command can be used to inspect the equivalent Gremlin query:\n\n```\ngremlin\u003e :\u003e EXPLAIN MATCH (p:airport) RETURN p.desc AS name\n==\u003e[translation:g.V().hasLabel('airport').project('name').by(__.choose(__.values('desc'), __.values('desc'), __.constant('  cypher.null'))),options:[EXPLAIN]]\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunsided%2Fjanusgraph-docker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsunsided%2Fjanusgraph-docker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunsided%2Fjanusgraph-docker/lists"}