Skip to main content

sng registry

Beta

Being rolled out. The interface described here is the one of the next release: it may still change, and may not be enabled on your tenant yet.

The sng registry commands are being rolled out in the CLI.

The sng registry group pushes, pulls, builds, and deletes images in your tenant's registry, <cluster>.registry.dev.stackngo.fr (for example ovh-gra-0.registry.dev.stackngo.fr). Images live under <registre>/<tenant>/<dépôt>:<tag>; you only give <dépôt>:<tag>, and sng adds the registry and the tenant. Authentication uses your tenant session: there is no registry password.

The global flags (--config, --json, -v, --version) are described in the CLI index.

Common prerequisites: sng sso login (otherwise not authenticated: run `sng sso login` ), then a tenant session sng tenant use NAME (otherwise tenant session required: run `sng tenant use NAME` ).

Group flag:

FlagTypeDefaultDescription
--tenantstringcurrent tenanttenant targeted by pull, build, login, delete of an image, and `access-key credentials

Image reference (REPO[:TAG|@DIGEST]): REPO is a single lowercase component (a-z, 0-9, ., _, - separators), without /. Without a tag or digest, the tag is latest. Otherwise: invalid repository "…": one lowercase component (a-z, 0-9, . _ -), no slash.

Registry host: the one of the cluster selected by sng config use-cluster <cluster> (the registry_url key of the sng configuration, for example ovh-gra-0.registry.dev.stackngo.fr), overridden by the STNG_REGISTRY_URL variable. With no cluster selected, the command fails with registry host unknown: run "sng config use-cluster <cluster>". A host other than localhost must use HTTPS. The registry of another cluster cannot be used with the current cluster's session: run sng config use-cluster again.

IAM actions:

CommandIAM actionResource
createdeploy:write (writing the desired state)POST /v1/apply
delete REPOdeploy:deleteDELETE /v1/resources/RegistryRepository/{name}
buildregistry:push (and registry:pull)repository/<dépôt>
pullregistry:pullrepository/<dépôt>
delete REPO:TAG, delete REPO@DIGESTregistry:deleterepository/<dépôt>
loginvalid session (no particular action)—
access-key credentials NAMEregistry:adminaccesskey/<name>
access-key rotate NAMEregistry:rotateaccesskey/<name>

A refusal by the registry is explained as follows:

registry refused the access (401): the repository must be declared (sng registry create NAME) and a policy of the tenant must allow registry:pull / registry:push / registry:delete (sng tenant policy list); if the session expired, run `sng tenant use NAME`: …

sng registry create​

sng registry create NAME [--description TEXT] [--public] [--keep-last N] [--keep-days N]
[--keep-tag REGEX]... [--keep-untagged] [--deletion-policy Block|Delete] [--dry-run]

Writes a RegistryRepository manifest to the tenant's desired state (current tenant), then the platform applies it. Until then, the registry refuses all access to the repository. Running the command again on an existing name replaces its declaration.

ArgumentDescription
NAMErepository name
FlagTypeDefaultDescription
--descriptionstringfree-form description, at most 512 characters
--publicboolfalseallows anonymous pull
--keep-lastint0keeps the last N pushed tags (0 to 100,000)
--keep-daysint0keeps tags pushed within the last N days (0 to 3650)
--keep-tagstring, repeatablekeeps tags matching this Go regex (at most 16)
--keep-untaggedboolfalsekeeps untagged images (erased by default)
--deletion-policystringBlockBlock or Delete (case-insensitive): purge of the images when the repository is deleted
--dry-runboolfalseshows the manifest without applying it

Without any retention flag, the manifest has no retention: all tags are kept.

sng registry create web --keep-last 20 --keep-days 90 --keep-tag '^v\d+\.\d+\.\d+$'
sng registry create docs --public
sng registry create scratch --deletion-policy Delete --dry-run
repository "web" declared in tenant acme: … usable as ovh-gra-0.registry.dev.stackngo.fr/acme/web

--dry-run:

apiVersion: registry.stackngo.io/v1alpha1
kind: RegistryRepository
metadata:
name: scratch
spec:
deletionPolicy: Delete

--json output: {"uploads": [{"key": "acme/…/RegistryRepository/web.yml", "kind": "RegistryRepository", "name": "web", …}]}.

Errors:

MessageCause
--keep-last must be between 0 and 100000value out of bounds (likewise --keep-days, 0 to 3650)
--keep-tag is limited to 16 expressionsmore than 16 --keep-tag
--keep-tag "…": error parsing regexp: …invalid expression
--deletion-policy "…": expected Block or Deleteunknown value
--description is limited to 512 charactersdescription too long

With --tenant NAME, the repository is declared in NAME and the message shows its address in that tenant.

sng registry pull​

sng registry pull REPO[:TAG|@DIGEST] [-o FILE]

Pulls an image and loads it into the local docker daemon, or writes it to an archive that docker load can load.

ArgumentDescription
REPO[:TAG|@DIGEST]image of the tenant
FlagTypeDefaultDescription
-o, --outputstringwrites an archive instead of loading the image into the daemon
sng registry pull web:1.2.0
sng registry pull web:1.2.0 --output web.tar
sng registry pull web@sha256:4f1c9a…
pulled ovh-gra-0.registry.dev.stackngo.fr/acme/web@sha256:4f1c9a…
saved ovh-gra-0.registry.dev.stackngo.fr/acme/web@sha256:4f1c9a… to web.tar

--json output: {"reference": "…", "digest": "sha256:…", "output": "web.tar"} (output empty without --output).

Error: not found in the registry: … (unknown tag or digest).

sng registry delete​

sng registry delete REPO:TAG | REPO@DIGEST | REPO [--yes]
  • With a tag or a digest: deletes the image from the registry (registry:delete). A tag is first resolved to a digest: all tags pointing to the same image disappear with it.
  • With REPO alone: removes the RegistryRepository manifest from the desired state. Once the platform applies this, the images are purged if deletionPolicy is Delete; with Block, the repository stays as long as it contains tags.
ArgumentDescription
REPO:TAG, REPO@DIGEST, or REPOimage or repository
FlagTypeDefaultDescription
-y, --yesboolfalseconfirms without a prompt; required outside an interactive terminal
sng registry delete web:1.0.0
sng registry delete web@sha256:4f1c9a…
sng registry delete scratch --yes
deleted ovh-gra-0.registry.dev.stackngo.fr/acme/web@sha256:4f1c9a…
deleted: acme/…/RegistryRepository/scratch.yml (… images are purged if deletionPolicy is Delete)

--json output: {"reference": "…", "digest": "sha256:…"} for an image; the response of the deletion API (key, …) for a repository.

Errors: confirmation requise : relancez avec --yes ou depuis un terminal interactif, opération annulée (answer other than "oui"), invalid repository "…". With --tenant NAME, the deleted image or repository is the one of NAME, and the confirmation says so.

sng registry build​

sng registry build [CONTEXT] [-t REPO[:TAG]] [-f DOCKERFILE] [--platform P,...] [--build-arg K=V]...
[--target STAGE] [--no-push] [--no-scan] [--registry-scan] [--severity S] [--fail-on S]
[--scan-timeout D]
sng registry build --from-image IMAGE [-t REPO[:TAG]]
sng registry build --from-tar FILE -t REPO[:TAG]

Builds CONTEXT (default .) with docker buildx build, pushes the image to <registre>/<tenant>/REPO:TAG with your session (docker is configured as by sng registry login), then scans it for vulnerabilities on your machine with Trivy (the trivy command, which you install yourself): the pushed image is scanned by its digest, with your session.

Default name: without -t, the repository is named after the current directory (lowercase, separators becoming -) and the tag is latest.

Repository created automatically: if the repository is not declared yet, sng registry build declares it itself (default settings: all tags kept, private, deletion blocked while it holds images), waits for it to be ready (3 minutes at most), then pushes. With --no-push, the registry is not touched. Without the right to declare the repository: droits insuffisants; if the repository exists but the push is refused: missing rights (policy registry:push).

Push an existing image, without rebuilding:

  • --from-image IMAGE pushes an image from the local docker daemon. Without -t, the last component of the name and its tag are reused (ghcr.io/acme/tool:3 → tool:3).
  • --from-tar FILE -t REPO[:TAG] pushes an archive (docker save or OCI archive); -t is required.

Both options are incompatible with CONTEXT, -f, --platform, --build-arg, --target and --no-push. They create the repository and print the same messages as a build; the vulnerability scan remains available. --from-image relies on docker save: docker is still required. This replaces the former sng registry push command, which was removed.

  • trivy missing: the image is pushed, a warning is printed (warning: CVE scan skipped: trivy is not installed …) and the command succeeds. With --fail-on, it exits with an error, since nothing was scanned.
  • --registry-scan: waits for the scan made by the registry instead of trivy (up to --scan-timeout). The platform's registry does not scan images yet: this option is meant for later.
  • --no-scan: no scan.
  • --no-push: the image is loaded into the local daemon and scanned by trivy if it is installed.
ArgumentDescription
CONTEXTbuild directory (default .)
FlagTypeDefaultDescription
-t, --tagstring(required)REPO[:TAG] target in the tenant; a digest is refused
-f, --filestringCONTEXT/Dockerfilepath of the Dockerfile
--platformlisttarget platforms, e.g. linux/amd64,linux/arm64
--build-argstring, repeatablebuild variable KEY=VALUE
--targetstringtargeted build stage
--no-pushboolfalseloads the image into the local daemon instead of pushing it (a single --platform)
--no-scanboolfalseno vulnerability scan
--registry-scanboolfalsewaits for the registry scan instead of the local trivy scan
--severitystringHIGHminimum severity listed: UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL
--fail-onstringexits with an error if a vulnerability of this severity or higher is found (or if no scan could take place)
--scan-timeoutduration5mwith --registry-scan: maximum wait for the registry scan
sng registry build # repository = directory name, tag latest
sng registry build -t web:1.2.0 # push, then local scan with trivy
sng registry build ./api -f api/Dockerfile -t api:$(git rev-parse --short HEAD) --fail-on CRITICAL
sng registry build -t web:dev --no-push --fail-on CRITICAL # no push, local scan
sng registry build -t web:1.2.0 --no-scan
sng registry build --from-image ghcr.io/acme/tool:3 # pushes tool:3 without building
sng registry build --from-tar image.tar -t web:1.2.0
pushed ovh-gra-0.registry.dev.stackngo.fr/acme/web:1.2.0@sha256:4f1c9a…

The pushed line is followed by the trivy report (vulnerabilities of severity --severity or higher).

--json output: {"reference": "…", "digest": "sha256:…"}; the local scan then prints nothing, but --fail-on still applies. With --registry-scan, the registry report is added.

Errors:

MessageCause
--from-tar needs -t REPO[:TAG]--from-tar without -t
-t needs a tag, not a digest-t web@sha256:…
docker is required for sng registry build (docker buildx)docker missing from PATH
--no-push loads into the local daemon, which holds one platform: pass a single --platformseveral platforms with --no-push
--build-arg "…": expected KEY=VALUEmalformed argument
invalid severity "…": expected one of UNKNOWN, LOW, MEDIUM, HIGH, CRITICALunknown --severity or --fail-on
warning: CVE scan skipped: trivy is not installed (install it, or use --registry-scan)image pushed, trivy missing (warning, not an error)
image pushed, but --fail-on needs a CVE scan: install trivy, or use --registry-scan--fail-on without trivy: the image is pushed, the command exits with an error
CVE scan skipped: the image is not in the registry and trivy is not installed …--no-push without a local trivy (warning, not an error)

sng registry login​

sng registry login

Configures docker to authenticate with your session: adds credHelpers["ovh-gra-0.registry.dev.stackngo.fr"] = "sng" to ~/.docker/config.json (or $DOCKER_CONFIG/config.json), keeping the rest of the file, and makes docker-credential-sng (a link to sng) findable. No password is stored: the helper returns the current session and renews it if needed. The session is checked against the registry before anything is written.

Docker runs the helper without the sng flags: it reads the default configuration, or the file designated by STNG_CONFIG.

FlagTypeDefaultDescription
(no flags of its own)
sng registry login
docker now authenticates to ovh-gra-0.registry.dev.stackngo.fr with the session of tenant "acme"

If the link is not in PATH, a warning is written to standard error: warning: docker-credential-sng is not in PATH; add <dossier> to PATH so docker finds it. If the link cannot be created: create <chemin> (run `sudo make install`, or link it yourself): ….

--json output: {"registry": "ovh-gra-0.registry.dev.stackngo.fr", "dockerConfig": "/home/me/.docker/config.json", "tenant": "acme"}.

sng registry access-key credentials​

sng registry access-key credentials NAME [--show-password]

Shows the current credentials of a registry access key (RegistryAccessKey), for a CI job or a tool that cannot open a tenant session. The username (accesskey/<tenant>/<name>) is always shown; the password only with --show-password. It changes at each renewal of the key; the previous one stays accepted during its grace period (graceHours, 24 h by default).

Reserved for tenant administrators (action registry:admin).

FlagTypeDefaultDescription
--show-passwordboolfalsealso prints the password (sensitive: keep it out of logs)
sng registry access-key credentials builder
username: accesskey/acme/builder
password: (hidden, add --show-password to print it)

An invalid name is refused before any call: invalid access key name "…".

--json output: {"name": "builder", "username": "accesskey/acme/builder"}, with the password key only if --show-password is given.

sng registry access-key rotate​

sng registry access-key rotate NAME

Requests a new password for a registry access key, without waiting for rotateEveryDays. The previous one stays accepted during the key's grace period (graceHours, 24 h by default). Read the new one with sng registry access-key credentials.

The default pull key is managed by the platform and cannot be renewed here. Reserved for tenant administrators (action registry:rotate).

sng registry access-key rotate builder
rotation requested for builder: the previous password stays valid during the grace period
read the new one with: sng registry access-key credentials builder --show-password

A renewal already in progress returns an error: try again in a moment.

See also​