Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Docker images ship no extension update scripts: docker/Dockerfile drops the age--*--*.sql that make install produces

Open Beginner friendly
#2,570 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
88/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
docker, postgresql
Domain
databases, devops

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), and release_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

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from apache/age

All issues in apache/age

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.