---
title: Deploying a Docker image
description: Run a prebuilt image from Docker Hub, GitHub Container Registry or any other registry, including private images.
section: Services
order: 2
---

Dekka can run an image you have already built, without building anything itself. This suits images published by your own CI and off-the-shelf software such as `nginx` or `metabase/metabase`.

## Deploy a public image

1. On the canvas, choose **Add**, then **Docker image**.
2. Enter the **Image** with a tag or digest, such as `nginx:1.27` or `ghcr.io/acme/api:1.4.2`.
3. Give the service a name, choose how it **Runs as**, and for a web service enter the port the image listens on.
4. Choose **Deploy**.

An image without a registry host, such as `nginx:1.27`, comes from Docker Hub. Every image needs a tag or a `@sha256:` digest, because Dekka won't guess at `latest`.

## Deploy a private image

A private image needs a [registry credential](/docs/registry-credentials) for its registry, stored in your organisation's settings. Name the credential in the service's image source:

```bash tab="cURL"
curl https://api.dekka.cloud/v1/projects/$PROJECT_ID/resources \
  -H "Authorization: Bearer $DEKKA_API_KEY" \
  --json '{
    "kind": "application",
    "name": "api",
    "spec": {
      "source": {
        "provider": "image",
        "image": "ghcr.io/acme/api:1.4.2",
        "registry_credential_id": "'$CREDENTIAL_ID'"
      },
      "runtime": { "port": 8080 }
    }
  }'
```

The credential's registry has to match the image's. A credential for `ghcr.io` can't pull from `docker.io`, and Dekka refuses the pair with 422 `registry_credential_mismatch`. If the registry turns the credential down at deploy time, the deployment fails with `image_pull_unauthorized`.

> [!NOTE]
> The dashboard doesn't have a way to choose a registry credential for a service yet, so set `registry_credential_id` with the API when you create the service or with `PATCH /v1/resources/{id}`.

## Deploy a new version

Change the image tag in the service's **Settings**, choose **Stage changes**, then **Deploy changes**. Choosing **Deploy** without changing the tag pulls the same reference again, which picks up a new image only if the tag has moved.

An image service doesn't deploy on push, has no build settings, and doesn't use build minutes. Everything under **Deploy**, **Resources** and **Networking** in its settings works as it does for a service built from GitHub, which [Build and deploy settings](/docs/build-configuration) describes.
