Skip to content

feat: allow namespace override per image (#4725)#4762

Open
ffabss wants to merge 1 commit intosupabase:developfrom
ffabss:develop
Open

feat: allow namespace override per image (#4725)#4762
ffabss wants to merge 1 commit intosupabase:developfrom
ffabss:develop

Conversation

@ffabss
Copy link

@ffabss ffabss commented Jan 27, 2026

What kind of change does this PR introduce?

Feature

What is the current behavior?

There is currently no support for overriding the namespace used when resolving container image references.
This makes it impossible to pull certain images (e.g. kong) via the GitLab CI Dependency Proxy, which only supports images from docker.io.

Related issue: #4725

What is the new behavior?

This PR introduces support for per-image namespace configuration via environment variables such as SUPABASE_INTERNAL_IMAGE_NAMESPACE_KONG=library.

With this change, users can explicitly control the resolved image namespace, enabling images like kong to be pulled through the GitLab CI Dependency Proxy.

Additional context

The image resolution logic was updated to apply the configured namespace when constructing the full image reference, and tests were added to cover the new behavior.

@ffabss ffabss requested a review from a team as a code owner January 27, 2026 21:37
@sweatybridge
Copy link
Contributor

The env var you are looking for is SUPABASE_INTERNAL_IMAGE_REGISTRY=docker.io

append this before supabase start and it will pull images from dockerhub

@ffabss
Copy link
Author

ffabss commented Jan 30, 2026

The issue is not that I can’t set the registry.

The issue is that the method I changed explicitly checks for docker.io and then adjusts the Docker image namespace differently.

This behavior is inherently necessary because Supabase does not re-publish all images under the supabase/* namespace (for example: kong is not published as supabase/kong).

For the Kong image on docker.io, there is no image under the namespace supabase/kong.
On docker.io, the correct namespace would be either:

  • library/kong, or
  • kong

So if someone is using a custom pull-through cache (still using docker.io) or the GitLab Dependency Proxy, the method GetRegistryImageUrl currently returns a URL for an image that does not exist.

What my changes add

My changes introduce the possibility to override the namespace per image, so users can configure the correct namespace for cases like GitLab Dependency Proxy.

For example, Kong can be fixed by setting:

SUPABASE_INTERNAL_IMAGE_NAMESPACE_KONG=library

Example

The method GetRegistryImageUrl receives the input:

library/kong:2.8.1
  • If SUPABASE_INTERNAL_IMAGE_REGISTRY is set to docker.io, the method returns:
docker.io/library/kong:2.8.1
  • For any other value of SUPABASE_INTERNAL_IMAGE_REGISTRY, the method returns basically:
$SUPABASE_INTERNAL_IMAGE_REGISTRY/supabase/kong:2.8.1

With the new namespace override, users can ensure the method returns valid image URLs even when images are not available under supabase/*.

@sweatybridge sweatybridge reopened this Jan 30, 2026
@coveralls
Copy link

coveralls commented Jan 30, 2026

Pull Request Test Coverage Report for Build 22073003576

Details

  • 25 of 26 (96.15%) changed or added relevant lines in 1 file are covered.
  • 8 unchanged lines in 3 files lost coverage.
  • Overall coverage increased (+0.02%) to 61.819%

Changes Missing Coverage Covered Lines Changed/Added Lines %
internal/utils/docker.go 25 26 96.15%
Files with Coverage Reduction New Missed Lines %
internal/utils/docker.go 1 77.33%
internal/storage/rm/rm.go 2 80.61%
internal/utils/git.go 5 57.14%
Totals Coverage Status
Change from base Build 22064360554: 0.02%
Covered Lines: 7723
Relevant Lines: 12493

💛 - Coveralls

@sweatybridge
Copy link
Contributor

sweatybridge commented Jan 30, 2026

This behavior is inherently necessary because Supabase does not re-publish all images under the supabase/* namespace (for example: kong is not published as supabase/kong).

Could you let me know which registry are you using? We have kong published under supabase namespace for GHCR and ECR. These are the only ones we support officially right now.

We are only making an exception for docker.io because we don't control some of the namespaces there.

@ffabss
Copy link
Author

ffabss commented Jan 31, 2026

Im using the GitLab Dependency Proxy, which acts as a pull-through cache for docker.io. As far as I know, its not possible to use a different upstream registry with it.
See: https://docs.gitlab.com/user/packages/dependency_proxy/#use-the-dependency-proxy-for-docker-images

The only real workaround would be to set up and maintain a separate pull-through cache that targets a different upstream registry (e.g. GHCR or AWS ECR). However, that adds operational overhead (infrastructure + configuration + ongoing maintenance).

Images required for running all services locally

I checked which images are needed to run all services locally and found the following list:

  • axllent/mailpit:v1.22.3
  • darthsim/imgproxy:v3.8.0
  • library/kong:2.8.1
  • postgrest/postgrest:v14.3
  • supabase/edge-runtime:v1.70.0
  • supabase/gotrue:v2.185.0
  • supabase/logflare:1.30.3
  • supabase/postgres-meta:v0.95.2
  • supabase/postgres:17.6.1.074
  • supabase/postgres:17.6.1.074
  • supabase/realtime:v2.72.0
  • supabase/storage-api:v1.33.5
  • supabase/studio:2026.01.26-sha-1b6582e
  • supabase/supavisor:2.7.4
  • timberio/vector:0.28.1-alpine

These are the configured image names the CLI uses.

Why the current behavior breaks with GitLab Dependency Proxy

The old logic for constructing the image URL effectively enforced the namespace supabase whenever the registry was not docker.io.

Proposed solution

With the proposed code changes, the following environment variables can be used to ensure images are pulled from the correct namespaces:

  • SUPABASE_INTERNAL_IMAGE_NAMESPACE_MAILPIT=axllent
  • SUPABASE_INTERNAL_IMAGE_NAMESPACE_IMGPROXY=darthsim
  • SUPABASE_INTERNAL_IMAGE_NAMESPACE_KONG=library
  • SUPABASE_INTERNAL_IMAGE_NAMESPACE_POSTGREST=postgrest
  • SUPABASE_INTERNAL_IMAGE_NAMESPACE_VECTOR=timberio

Additionally, the following would be used to direct Supabase to use the GitLab Dependency Proxy:

SUPABASE_INTERNAL_IMAGE_REGISTRY=${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}

This will set the registry to something like:

gitlab.example.com:443/my-group/dependency_proxy/containers

See: https://docs.gitlab.com/user/packages/dependency_proxy/#authenticate-within-cicd

@coderabbitai
Copy link

coderabbitai bot commented Feb 16, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 8237d56 and 1695dd7.

📒 Files selected for processing (2)
  • internal/utils/docker.go
  • internal/utils/docker_test.go

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Support for per-image namespace overrides via configuration keys; non-docker.io registries default to the "supabase" namespace unless overridden
    • Improved handling and validation of image references, preserving docker.io/library semantics and returning invalid formats unchanged
  • Tests

    • Added comprehensive tests covering registry-specific behavior, namespace fallbacks, overrides, and invalid inputs

Walkthrough

The pull request modifies the image reference handling in the Docker utility module. The GetRegistryImageUrl function is enhanced to build fully-qualified image URLs from namespace/image:tag inputs, supporting per-image namespace overrides via configuration keys in the format INTERNAL_IMAGE_NAMESPACE_<IMAGE>. For non-docker.io registries without overrides, it defaults to the "supabase" namespace. The implementation includes input validation and returns the original input on invalid formats. Corresponding test coverage validates the function's behavior across docker.io registries, non-docker.io registries, namespace overrides, and malformed inputs.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as Caller
    participant Func as GetRegistryImageUrl
    participant Config as Viper/Config
    participant Result as Result

    Caller->>Func: Call GetRegistryImageUrl(imageRef)
    Func->>Func: Parse imageRef (registry?/namespace/image:tag)
    alt invalid format
        Func->>Result: Return original imageRef
    else valid format
        Func->>Config: Read INTERNAL_IMAGE_REGISTRY
        Func->>Config: Read INTERNAL_IMAGE_NAMESPACE_<IMAGE> (override)
        alt override present
            Func->>Func: Apply override namespace
        else no override
            alt registry == docker.io
                Func->>Func: Preserve provided namespace (e.g., library)
            else
                Func->>Func: Use default namespace "supabase"
            end
        end
        Func->>Result: Build registry/namespace/image:tag and return
    end
Loading

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants