Skip to main content

Build and push images

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.

Your pipeline builds an image, pushes it to the tenant's registry and updates the App that uses it. The job authenticates with the registry using its OIDC session: no secret to store.

Prerequisites​

A repository declared in the tenant:

sng registry create api

or, as a manifest:

infra/RegistryRepository/api.yml
apiVersion: registry.stackngo.io/v1alpha1
kind: RegistryRepository
metadata:
name: api
spec:
retention:
keepLastCount: 20
keepTagsRegex: ["^v\\d+\\.\\d+\\.\\d+$"]

The repository is called <registry>/acme/api. The registry hostname is indicated by sng registry login; see Push and pull.

The job's OIDC session​

The trust used by the job must have registry:push on the repository. The readwrite policy includes it; otherwise, add a policy:

{
"Version": "1",
"Statement": [
{"Effect": "Allow", "Actions": ["registry:push", "registry:pull"], "Resources": ["repository/api"]},
{"Effect": "Allow", "Actions": ["deploy:read", "deploy:write", "deploy:list"], "Resources": ["*"]}
]
}
sng tenant policy create ci-api -f ci-api.json
sng tenant policy attach ci-api --oidc-trust gitlab-deploy

In the job, sng registry uses the current session:

build-and-push:
extends: .sng
stage: deploy
image: docker:27
services: [docker:27-dind]
script:
- sng registry login # docker login with the job's session
- docker build -t api:$CI_COMMIT_SHORT_SHA .
- sng registry build --from-image api:$CI_COMMIT_SHORT_SHA

Or sng registry build builds, pushes, then scans the image with trivy if the job's image provides it (otherwise a warning is printed and the job goes on). --fail-on makes the job fail on a serious vulnerability, or if trivy is missing:

- sng registry build . -t api:$CI_COMMIT_SHORT_SHA --fail-on CRITICAL

What about registry access keys?​

A registry access key (RegistryAccessKey) is used above all by your App resources to pull your private images (imagePullSecrets). To push from an external CI, prefer the OIDC session above: no secret to store or renew.

A key remains useful when the job cannot open a session:

  • job run by an App of your tenant: declare the key with ci: true, and the App reads its credentials in its environment variables. Without ci: true, an App that names them in env or envFrom is refused;
  • external tool without OIDC: a tenant administrator reads the credentials with sng registry access-key credentials NAME --show-password and copies them into the CI variables; to be redone after each renewal.

Details in Registry access keys.

Update the App​

The pushed image must end up in the manifest. Two approaches:

Moving tag and restart. The App references acme/api:main; the job pushes this tag then forces a restart:

sng app restart api

Simple, but the desired state does not say which version is running.

Immutable tag in the manifest. The job rewrites the image in the file and applies:

sed -i "s#\(image: .*/acme/api:\).*#\1$CI_COMMIT_SHORT_SHA#" infra/App/api.yml
sng apply infra/App/api.yml
git commit -am "deploy api $CI_COMMIT_SHORT_SHA" && git push # if you want the trace in git

More rigorous: sng pull and your repository say exactly what is running, and sng env restore brings you back to a precise version.

Pull the image from the tenant​

An App does not receive registry access automatically, even in the same tenant. Declare a read access key (actions: [pull]): the platform prepares the credential <key>-registry, which you reference in spec.imagePullSecrets (Registry access keys). A public: true repository can be pulled without authentication. For a private external registry, see (Variables and secrets).

See also​