Several variants of the container
This commit is contained in:
1 parent
f0fb9ddc74
commit
e7ef15fc79
6 files changed
+202
-48
No files matched your search
@@ -6,7 +6,7 @@ graph engine.
|
||||
|
||||
peo is a small Python server that speaks Neo4j's Bolt protocol and translates Cypher
|
||||
into AGE `cypher()` calls. It can also serve neo4j-browser. A [container
|
||||
image](#container-image) bundles everything, together with
|
||||
image](#container-images) bundles everything, together with
|
||||
[pgAdmin](https://www.pgadmin.org/) for working with the same data in SQL.
|
||||
|
||||
```
|
||||
@@ -37,7 +37,8 @@ and password.
|
||||
peo does not include neo4j-browser itself. To serve it, install the `browser` extra
|
||||
([Starlette](https://www.starlette.io/) and [uvicorn](https://www.uvicorn.org/)),
|
||||
build neo4j-browser and point `PEO_BROWSER_DIR` at its `dist` directory; it is then
|
||||
served on <http://localhost:7474/>. The container image does all of this for you.
|
||||
served on <http://localhost:7474/>. The [container images](#container-images) do all of
|
||||
this for you.
|
||||
|
||||
```sh
|
||||
pip install 'peo[binary,browser]'
|
||||
@@ -65,7 +66,7 @@ peo is configured through environment variables:
|
||||
|
||||
- **Databases are AGE graphs.** Every AGE graph shows up as a Neo4j database, and
|
||||
`:use <name>` switches between them. Clients that do not pick a database get `PEO_DEFAULT_GRAPH`
|
||||
(`neo4j`); the container image creates that graph on first start. `CREATE DATABASE x` and `DROP DATABASE x` on the `system`
|
||||
(`neo4j`); the full container image and the compose setup create that graph on first start. `CREATE DATABASE x` and `DROP DATABASE x` on the `system`
|
||||
database call `create_graph` / `drop_graph`; AGE requires names of at least 3 characters.
|
||||
- **Queries** are sent to AGE as `SELECT * FROM cypher('<graph>', $$ <query> $$) AS (...)`.
|
||||
peo works out the result columns from the final `RETURN` clause and inlines
|
||||
@@ -108,38 +109,21 @@ and `REMOVE`, and they can be indexed. Some things to keep in mind:
|
||||
- AGE has no date or time types, so store those as ISO 8601 strings and cast them in
|
||||
SQL.
|
||||
|
||||
## Querying the graph from SQL
|
||||
## Container images
|
||||
|
||||
AGE stores each node label and relationship type as a table in the graph's schema,
|
||||
with all properties in one `agtype` column, `properties`; `properties ->> 'key'::text`
|
||||
returns a property as text. For typed columns, add them yourself, either as a view or
|
||||
as a generated column:
|
||||
The [`Containerfile`](Containerfile) builds two images:
|
||||
|
||||
```sql
|
||||
CREATE VIEW neo4j.people AS
|
||||
SELECT id, properties ->> 'name'::text AS name, (properties ->> 'age'::text)::bigint AS age
|
||||
FROM neo4j."Person";
|
||||
- **full** (the default): PostgreSQL with AGE, peo, neo4j-browser and pgAdmin in one
|
||||
container.
|
||||
- **slim** (`--target slim`): only peo and neo4j-browser, for a PostgreSQL server
|
||||
with AGE that runs elsewhere. [`compose.yaml`](compose.yaml) runs it next to
|
||||
separate PostgreSQL and pgAdmin containers.
|
||||
|
||||
ALTER TABLE neo4j."Person"
|
||||
ADD COLUMN age bigint GENERATED ALWAYS AS ((properties ->> 'age'::text)::bigint) STORED;
|
||||
```
|
||||
Any OCI-compatible build tool works. Docker does not pick up a `Containerfile` by
|
||||
itself, so pass it explicitly: `docker build -f Containerfile -t peo .`. `docker`
|
||||
takes the same options as `podman` in the commands below.
|
||||
|
||||
PostgreSQL keeps generated columns up to date on every Cypher `CREATE`, `MERGE`, `SET`
|
||||
and `REMOVE`, and they can be indexed. Some things to keep in mind:
|
||||
|
||||
- A value that does not fit the column's type makes the Cypher write fail: with the
|
||||
column above, `CREATE (:Person {age: 'old'})` is rejected. A view only fails when it
|
||||
is read.
|
||||
- AGE does not allow dropping columns from its label tables, so a generated column
|
||||
cannot be removed again.
|
||||
- Adding a stored generated column rewrites the table and locks it while doing so.
|
||||
- AGE has no date or time types, so store those as ISO 8601 strings and cast them in
|
||||
SQL.
|
||||
|
||||
## Container image
|
||||
|
||||
The container image runs PostgreSQL with AGE, peo, neo4j-browser and pgAdmin in one
|
||||
container:
|
||||
### Everything in one container
|
||||
|
||||
```sh
|
||||
podman build -t peo .
|
||||
@@ -159,10 +143,6 @@ pgAdmin comes with the bundled PostgreSQL server already registered as "peo";
|
||||
it asks for the PostgreSQL password the first time you open it. AGE stores each
|
||||
graph as a schema of the same name, with one table per label.
|
||||
|
||||
Any OCI-compatible build tool works. With Docker, pass the file name explicitly:
|
||||
`docker build -f Containerfile -t peo .`; `docker run` takes the same options as
|
||||
`podman run`.
|
||||
|
||||
Besides peo's own variables above, the image uses these:
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
@@ -174,12 +154,52 @@ Besides peo's own variables above, the image uses these:
|
||||
| `PEO_PGADMIN` | `true` | Set to `false` to not start pgAdmin. |
|
||||
| `PEO_PGADMIN_PORT` | `5050` | Port pgAdmin listens on inside the container. |
|
||||
|
||||
Build arguments: `AGE_IMAGE` (base image, default `apache/age:release_PG18_1.8.0`),
|
||||
`NEO4J_BROWSER_REF` (neo4j-browser commit to build) and `PGADMIN_VERSION` (default `9.18`).
|
||||
|
||||
pgAdmin keeps its users and settings in `/var/lib/pgadmin`; changing
|
||||
`PGADMIN_DEFAULT_*` after the first start has no effect unless that directory is empty.
|
||||
|
||||
### peo with a separate PostgreSQL server
|
||||
|
||||
The slim image runs peo and serves neo4j-browser, and is configured with the
|
||||
variables in [Configuration](#configuration). Point it at any PostgreSQL server
|
||||
that has AGE installed and loaded (`shared_preload_libraries=age`):
|
||||
|
||||
```sh
|
||||
podman build --target slim -t peo:slim .
|
||||
podman run -d --name peo -p 7474:7474 -p 7687:7687 \
|
||||
-e PEO_PG_HOST=db.example.com -e PEO_PG_DATABASE=graphs peo:slim
|
||||
```
|
||||
|
||||
peo creates no graphs of its own. If the database has none yet, run
|
||||
`CREATE DATABASE neo4j` on the `system` database (`:use system` in neo4j-browser),
|
||||
or `SELECT ag_catalog.create_graph('neo4j');` in SQL.
|
||||
|
||||
### Compose: peo, PostgreSQL and pgAdmin as separate containers
|
||||
|
||||
[`compose.yaml`](compose.yaml) builds the slim image and runs it with
|
||||
[`apache/age`](https://hub.docker.com/r/apache/age) for PostgreSQL and the official
|
||||
[`dpage/pgadmin4`](https://hub.docker.com/r/dpage/pgadmin4) image:
|
||||
|
||||
```sh
|
||||
echo POSTGRES_PASSWORD=secret > .env
|
||||
podman compose up -d
|
||||
```
|
||||
|
||||
It works with `podman compose` and `docker compose`, and publishes the same ports and
|
||||
logins as the full image: neo4j-browser on 7474, Bolt on 7687, pgAdmin on 5050 and
|
||||
PostgreSQL on 5432. Set `PEO_POSTGRES_PORT` to publish PostgreSQL on another host
|
||||
port. The default graph (`PEO_DEFAULT_GRAPH`, `neo4j`) is created when the database
|
||||
is initialised, and pgAdmin comes with the server already registered as "peo".
|
||||
`PGADMIN_DEFAULT_EMAIL`, `PGADMIN_DEFAULT_PASSWORD` and `PEO_LOG_LEVEL` can be set
|
||||
in `.env` too. Data is kept in the `postgres-data` and `pgadmin-data` volumes;
|
||||
`podman compose down -v` removes them.
|
||||
|
||||
### Build arguments
|
||||
|
||||
`AGE_IMAGE` (base of the full image, default `apache/age:release_PG18_1.8.0`),
|
||||
`SLIM_BASE_IMAGE` (base of the slim image, default `debian:trixie-slim`),
|
||||
`NEO4J_BROWSER_REF` (neo4j-browser commit to build) and `PGADMIN_VERSION` (pgAdmin in
|
||||
the full image, default `9.18`).
|
||||
|
||||
## Limitations
|
||||
|
||||
This is a first version. Things that do not work (yet):
|
||||
@@ -215,8 +235,8 @@ python tests/smoke_test.py neo4j://localhost:7687 postgres secret
|
||||
## License
|
||||
|
||||
peo is free software, licensed under the GNU General Public License v3.0 or
|
||||
later; see [LICENSE](LICENSE). The container image bundles third-party software
|
||||
under its own licenses, including neo4j-browser (GPL-3.0), Apache AGE
|
||||
later; see [LICENSE](LICENSE). The container images bundle third-party software
|
||||
under their own licenses, including neo4j-browser (GPL-3.0), Apache AGE
|
||||
(Apache-2.0), PostgreSQL and pgAdmin (PostgreSQL License). See
|
||||
[THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) for the full list and where
|
||||
each license text and source archive is in the image.
|
||||
|
||||
Reference in new issue
Block a user