GoodMemGoodMem
How-To Guides

Install and Upgrade GoodMem

Upgrade an existing GoodMem installation, or install and upgrade using registry mirrors and offline packages.

Upgrading an installation

Update the CLI first, then upgrade each installed server profile:

goodmem upgrade
goodmem system upgrade --profile-name <profile-name>

The first command updates the CLI; the second updates the selected server installation and checks that it is ready. Your credentials, ports, and database data are preserved. Plan for a server restart.

If you pinned the server to a specific image tag or digest, add --image <new-server-image> to select the new version. Otherwise, the upgrade uses the image reference already configured. For restricted networks, use the mirror-based or offline instructions below.

Document storage

For standard installer-managed deployments, the upgrade adds disk-backed temporary storage for document processing. Database migrations run automatically when the server starts. You do not need to convert or re-ingest existing documents. Keep enough free space in Docker's storage for the documents you process, including concurrent uploads.

If you have customized the Compose file or temporary directory, the CLI preserves those choices and warns when it needs you to review them. See document-ingestion scratch storage for the mount configuration and storage requirements. Updating only the server image does not update an older Compose file.

Earlier database migrations

If you are upgrading from before the V1_17 authorization migration, users must replace any API keys created for them by an administrator with keys they create themselves before upgrading.

Installing in a network-restricted environment

The default installer fetches from these upstream hosts:

  • get.goodmem.ai — the GoodMem CLI tarball
  • get.docker.com — the Docker engine installer (only when Docker is not yet installed)
  • ghcr.io — the GoodMem server image
  • docker.io — the PostgreSQL+pgvector image
  • sigstore.dev — signature material for cosign verification

When any of these is unreachable — typically inside a corporate firewall or in mainland China — the installer accepts a small set of flags that let you complete an install using a pre-staged CLI tarball plus a reachable registry mirror.

The examples use ghcr.nju.edu.cn for the server image and mirror.gcr.io for the database image. Substitute registries that are reachable and trusted in your environment.

That mirror-based flow is described first. If the target machine has no reachable registry at all — a true air-gap — see Fully offline install (air-gapped) below, which pre-stages the container images as well as the CLI tarball.

Prerequisites

  1. Docker engine is already installed and reachable. The installer's auto-install path calls get.docker.com, which may also be blocked. On Debian/Ubuntu inside China, configure a Docker Hub mirror in /etc/docker/daemon.json once (e.g. https://docker.nju.edu.cn) and sudo systemctl restart docker.

  2. Two files delivered out of band (email, scp, internal object storage):

    • install.sh — the bash entry point (the same file served at https://get.goodmem.ai).
    • goodmem-<os>-<arch>.tar.gz — the CLI tarball matching the target platform (e.g. goodmem-linux-amd64.tar.gz).
  3. A reachable mirror of ghcr.io that proxies pair-systems-inc/goodmem/server, such as ghcr.nju.edu.cn.

  4. A reachable mirror of docker.io that proxies pgvector/pgvector, such as mirror.gcr.io.

    Verify that your chosen mirror serves the required image before installing:

    docker pull <your-mirror>/pgvector/pgvector:pg17

    If that fails, pick a different mirror or rely on a daemon-level registry-mirrors config in /etc/docker/daemon.json instead.

Install command

bash install.sh \
  --local-cli-tarball ./goodmem-linux-amd64.tar.gz \
  --goodmem-image ghcr.nju.edu.cn/pair-systems-inc/goodmem/server:latest \
  --pgvector-image mirror.gcr.io/pgvector/pgvector:pg17 \
  --skip-verify \
  --handsfree --db-password "your-secure-password-min-14-chars" \
  --tls-disabled

What each flag does:

FlagEffect
--local-cli-tarball <path>Use this tarball instead of downloading from get.goodmem.ai.
--goodmem-image <ref>Override the GoodMem server image — point at a mirrored registry (e.g. ghcr.nju.edu.cn/...).
--pgvector-image <ref>Override the pgvector image — point at a mirrored Docker Hub (e.g. mirror.gcr.io/...).
--skip-verifySkip cosign SLSA verification, which requires sigstore.dev. See the security note below.

The image choices are sticky: they get stamped into the per-profile .env file under ~/.goodmem/installs/local-docker/<profile>/. Subsequent goodmem system upgrade runs reuse the same images automatically — no need to repeat the flags on every upgrade.

Security note about --skip-verify

--skip-verify turns off the cosign SLSA-provenance check that normally proves the image you pulled was built by GoodMem's CI from this repository. Without it, you are trusting whatever bytes the mirror serves.

The mirror caching is content-addressable (an OCI manifest digest can't be forged without breaking SHA-256), so a benign mirror cannot serve a different image. The remaining risk is a stale mirror serving an older version, or a malicious mirror serving its own build. Two ways to harden:

  • Pin a digest. Pass --goodmem-image ghcr.nju.edu.cn/pair-systems-inc/goodmem/server@sha256:... with the digest you cross-checked against upstream. The installer then pulls that exact content.
  • Manually verify. If your network reaches sigstore.dev intermittently (e.g., via a VPN), run cosign verify-attestation --type slsaprovenance ... against the mirror before approving the install for production use.

Upgrading

First, obtain the new CLI tarball. Ask your contact at PAIR Systems for the latest release.

Update the CLI from that tarball:

goodmem upgrade --local-cli-tarball ./goodmem-linux-amd64.tar.gz --yes

Pull the desired server image from the configured mirror, then apply it. For the example installation above:

docker pull ghcr.nju.edu.cn/pair-systems-inc/goodmem/server:latest
goodmem system upgrade --skip-cli-check --skip-verify

--skip-cli-check bypasses the online CLI version check. With Docker Compose, --skip-verify also skips the installer's image pull, so run docker pull first to refresh the local image. If selecting a different tag or digest, pass that reference with --image as well.

Version discovery

Without get.goodmem.ai, the CLI cannot tell you "a new version is available". You'll need to learn about new releases out of band (mailing list, internal portal, GitHub Releases on a reachable network) and bring the new CLI tarball over to the target machine. Follow the upgrade steps above to update both the CLI and the server.

Fully offline install (air-gapped)

The network-restricted flow above still pulls the two container images — just from a mirror instead of the default registries. When the target machine has no reachable registry at all, pre-stage those images too: pull them on a connected machine, docker save them to a file, copy it across, and docker load on the target. No mirror hosts and no --goodmem-image / --pgvector-image flags are needed.

Prerequisites

  1. Docker engine already installed on the target. The installer's auto-install path calls get.docker.com, which is unreachable here, so install Docker out of band first.
  2. Three files delivered out of band (scp, USB, internal object storage):
    • install.sh — the bash entry point (the same file served at https://get.goodmem.ai).
    • goodmem-<os>-<arch>.tar.gz — the CLI tarball matching the target platform (e.g. goodmem-linux-amd64.tar.gz).
    • goodmem-images.tar.gz — the saved container images, built in the next step.

Save and load the images

On a connected machine, pull both images for the target's architecture, then save them into a single file:

docker pull --platform linux/amd64 ghcr.io/pair-systems-inc/goodmem/server:latest
docker pull --platform linux/amd64 pgvector/pgvector:pg17

docker save \
  ghcr.io/pair-systems-inc/goodmem/server:latest \
  pgvector/pgvector:pg17 \
  | gzip > goodmem-images.tar.gz

On the target machine, load them into the local Docker store:

gunzip -c goodmem-images.tar.gz | docker load
docker images | grep -E 'goodmem/server|pgvector'   # both tags should appear

Match the execution architecture. Use a CLI tarball for the host and images compatible with the container platform. The examples use linux/amd64; Apple Silicon installations use the installer's linux/amd64 emulation overlay for the server.

Install command

Because the loaded images already carry the tags the installer expects, omit the --goodmem-image / --pgvector-image flags entirely:

bash install.sh \
  --local-cli-tarball ./goodmem-linux-amd64.tar.gz \
  --skip-verify \
  --handsfree --db-password "your-secure-password-min-14-chars" \
  --tls-disabled

--skip-verify lets Docker Compose use the locally loaded images without pulling or verifying them online. The CLI includes the Compose configuration, so that needs no download either. This offline procedure does not cover Google Container-Optimized OS (COS), whose installer requires a registry connection.

If you re-tag the images while loading them, they no longer match the defaults; pass --goodmem-image / --pgvector-image with your tags so the installer and Compose find them.

Upgrading

There is no registry to pull from, so stage the new artifacts by hand — the same save/load pattern as the install.

First, upgrade the CLI from a new tarball (obtain it as described under Version discovery below):

goodmem upgrade --local-cli-tarball ./goodmem-linux-amd64.tar.gz --yes

Then stage and load the new server image on the target, exactly as at install time:

# On a connected machine:
docker pull --platform linux/amd64 ghcr.io/pair-systems-inc/goodmem/server:latest
docker save ghcr.io/pair-systems-inc/goodmem/server:latest | gzip > goodmem-server.tar.gz

# Copy over, then on the target:
gunzip -c goodmem-server.tar.gz | docker load

Finally, roll the server onto the freshly-loaded image:

goodmem system upgrade --skip-cli-check --skip-verify

--skip-cli-check bypasses the version gate that contacts get.goodmem.ai; --skip-verify skips the registry pull and cosign check, so the upgrade uses the image you just loaded. The pgvector image rarely changes between releases — if it does, docker load the new one the same way before upgrading.

Version discovery

With no network, the CLI cannot tell you when a new version is available. Track releases out of band (mailing list, internal portal, or GitHub Releases on a reachable network), then bring both the new goodmem-<os>-<arch>.tar.gz and the new server image over to the target and follow the Upgrading steps above.

On this page