Docker images ship no extension update scripts: docker/Dockerfile drops the age--*--*.sql that make install produces
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 88/100
Research direction
Start with docker/Dockerfile and compare its final-stage COPY entries with the update scripts installed by Makefile. Build the PG18 image, verify that age--1.7.0--1.8.0.sql is present in the extension directory, and confirm that ALTER EXTENSION age UPDATE succeeds on a cluster initialized with AGE 1.7.0.
Written by the indexing model from the issue text.
Description
Describe the bug
The official Docker images ship no extension update scripts, so ALTER EXTENSION age UPDATE can never work inside them.
Makefile installs every tracked update script:
# Git-tracked upgrade scripts shipped with the extension (e.g., age--1.6.0--1.7.0.sql).
# Excludes the upgrade template (y.y.y) and the synthetic stamped test file.
DATA = $(filter-out age--%--y.y.y.sql $(age_upgrade_test_sql),$(wildcard age--*--*.sql))
but docker/Dockerfile enumerates the files it copies out of the build stage individually, and lists only three:
COPY --from=build /usr/lib/postgresql/18/lib/age.so /usr/lib/postgresql/18/lib/
COPY --from=build /usr/share/postgresql/18/extension/age--1.8.0.sql /usr/share/postgresql/18/extension/
COPY --from=build /usr/share/postgresql/18/extension/age.control /usr/share/postgresql/18/extension/
make install in the build stage does place age--1.7.0--1.8.0.sql in the extension directory, but the final-stage COPY list drops it.
This is the same class of problem as #2257 (Makefile not installing age--1.5.0--1.6.0.sql), one layer further out: the Makefile is now correct, but the image build discards what it produced.
How are you accessing AGE (Command line, driver, etc.)?
psql, inside the published apache/age Docker images.
What data setup do we need to do?
A cluster initialised under an older AGE, then started under a newer image.
What is the command that caused the error?
ALTER EXTENSION age UPDATE;
ERROR: extension "age" has no update path from version "1.7.0" to version "1.8.0"
Reproduction
The images contain no update scripts at all:
$ docker run --rm --entrypoint find apache/age:release_PG18_1.8.0 / -name 'age--*' 2>/dev/null
/usr/share/postgresql/18/extension/age--1.8.0.sql
$ docker run --rm --entrypoint find apache/age:release_PG18_1.7.0 / -name 'age--*' 2>/dev/null
/usr/share/postgresql/18/extension/age--1.7.0.sql
Full path to the failure:
# 1. initialise a volume under 1.7.0 and create a graph
$ docker volume create agetest
$ docker run -d --name age17 -e POSTGRES_PASSWORD=t -e POSTGRES_DB=t \
-v agetest:/var/lib/postgresql apache/age:release_PG18_1.7.0
$ docker exec age17 psql -U postgres -d t -c "CREATE EXTENSION IF NOT EXISTS age;" \
-c "LOAD 'age'; SET search_path=ag_catalog,\"\$user\",public;
SELECT create_graph('testgraph');
SELECT * FROM cypher('testgraph', \$\$
CREATE (a:Concept {label:'alpha'})-[:IMPLIES]->(b:Concept {label:'beta'}) RETURN a
\$\$) AS (a agtype);"
# 2. stop it and start 1.8.0 on the same volume
$ docker rm -f age17
$ docker run -d --name age18 -e POSTGRES_PASSWORD=t -e POSTGRES_DB=t \
-v agetest:/var/lib/postgresql apache/age:release_PG18_1.8.0
The catalog is still 1.7.0 and cannot be updated:
SELECT extversion FROM pg_extension WHERE extname='age'; -- 1.7.0
ALTER EXTENSION age UPDATE;
ERROR: extension "age" has no update path from version "1.7.0" to version "1.8.0"
Writes still succeed, but every read fails:
--- MATCH (c:Concept) RETURN c.label
ERROR: type with OID 0 does not exist
--- MATCH (c:Concept) RETURN count(c)
ERROR: type with OID 0 does not exist
--- MATCH (c:Concept) RETURN c
ERROR: cache lookup failed for type 0
--- MATCH ()-[r]->() RETURN type(r)
ERROR: type() argument must be an edge or null
That is consistent with the signature changes in age--1.7.0--1.8.0.sql — _agtype_build_vertex and _agtype_build_edge now take agtype where they took cstring, and _label_name now RETURNS agtype where it returned cstring. The 1.8.0 library is being called through 1.7.0 catalog entries.
Confirmation that the script itself is fine
Copying the repo's own age--1.7.0--1.8.0.sql into the image's extension directory makes everything work:
$ docker cp age--1.7.0--1.8.0.sql age18:/usr/share/postgresql/18/extension/
$ docker exec age18 psql -U postgres -d t -c "ALTER EXTENSION age UPDATE;"
ALTER EXTENSION
SELECT extversion FROM pg_extension WHERE extname='age'; -- 1.8.0
--- MATCH (c:Concept) RETURN c.label "alpha", "beta"
--- MATCH (c:Concept) RETURN count(c) 2
--- MATCH (c:Concept) RETURN c {"id": 844424930131969, "label": "Concept",
"properties": {"label": "alpha"}}::vertex
--- MATCH ()-[r]->() RETURN type(r) "IMPLIES"
Pre-existing data is intact, original graphids preserved. So nothing is wrong with the update script — it just isn't in the image.
Expected behavior
The published images should contain the age--*--*.sql update scripts that make install produces, so ALTER EXTENSION age UPDATE works for users upgrading an existing cluster to a new image of the same PostgreSQL major version.
Suggested fix
Copy the extension directory rather than enumerating files, e.g.:
COPY --from=build /usr/share/postgresql/18/extension/age*.sql /usr/share/postgresql/18/extension/
COPY --from=build /usr/share/postgresql/18/extension/age.control /usr/share/postgresql/18/extension/
Environment
- Image:
apache/age:release_PG18_1.8.0(sha256:47a0b054c3663a3e64a25fc0c5a982f1b58348019274b326a691cdf77f78eb58), andrelease_PG18_1.7.0 - PostgreSQL 18.6 / 18.1 (Debian, from the images)
- Source checked at tag
PG18/v1.8.0-rc0
Additional context
Same root shape as #2257, #1508 and #132, which were all about update paths not being reachable. Those were fixed in the build; this one is in the image packaging.
- Dominant language
- C
- Stars
- 4.9k
- Forks
- 529
- Avg merge
- 8d 15h
- Merged PRs (30d)
- 3
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from apache/age
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
apache/age#2576 · 1 reaction ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
apache/age#2520 · 3 comments ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
apache/age#2514 · 4 comments ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 30/100
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
Maintainers usually reply within 1 day
Similar issues
-
area/ysql kind/bug priority/medium
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
yugabyte/yugabyte-db#34584 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
ExpressLRS/ExpressLRS#3806 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
Maintainers usually reply within 1 day