> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Demo Make Docker Build Docker Push

> Building, tagging, pushing a Docker image to a registry and verifying its manifest for Kubernetes deployments.

A Kubernetes cluster cannot run a locally-built binary — it needs an image reference that the cluster can pull from a registry. In this lesson you'll:

* set a concrete image tag that points to a registry,
* build a controller image via the project's Makefile,
* push that image to a registry, and
* confirm the registry contains a manifest for the tag.

## 1) Set the image reference

Set the `IMG` environment variable to a registry path and a version tag. In this recording we use a local registry at `127.0.0.1:5000` and tag `v0.1.0`:

```bash theme={null}
export IMG=127.0.0.1:5000/course/webapp-operator:v0.1.0
```

## 2) Build the image

Use the Makefile target that forwards `IMG` into Docker. The Makefile injects the tag into the Docker build so the resulting image is named as above.

```bash theme={null}
make docker-build IMG=$IMG
```

The project uses a multi-stage Dockerfile. The build usually compiles a `manager` binary in the builder stage, then copies that into a minimal runtime image in a later stage. Example (truncated) build output:

```console theme={null}
=> CACHED [builder 6/7] COPY . .
=> CACHED [builder 7/7] RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager cmd/main.go
=> CACHED [stage-1 2/3] COPY --from=builder /workspace/manager .
exporting to image
=> exporting layers
=> exporting manifest sha256:8a81b15d6d50b0094af375f659be04fdcb422a84ccd50d7e5b5968dcf220ab6a
=> exporting config sha256:31b190ab9c56c6b65483f180bbce9c28a5f51b8eafc8ee78608f35f47675f90e
=> exporting attestation manifest sha256:5adf21588e94c411886136fcad009a7cfa809ab043dd059a09e22b
=> naming to 127.0.0.1:5000/course/webapp-operator:v0.1.0
=> unpacking to 127.0.0.1:5000/course/webapp-operator:v0.1.0
```

Summary:

* Builder stage compiles the `manager` binary.
* Runtime stage packages that binary into the final controller image.

## 3) Push the image to the registry

Push the tag you just built so the registry stores the layers and writes an image manifest:

```bash theme={null}
make docker-push IMG=$IMG
```

Push output will show each layer uploaded and a final digest for the pushed tag. Example:

```console theme={null}
2780920e5dbf: Pushed
9b2e9c4f5243: Pushed
c172f21814df: Pushed
47de5dd0b812: Pushed
d6b1b89eccac: Pushed
52630fc75a18: Pushed
3214c34f5c0c: Pushed
b839dfae016f: Pushed
99ba982a9142: Pushed
ebdc5f54cdc: Pushed
v0.1.0: digest: sha256:db81233d7799521a10305a9e722847a1920e2ceec4f67fdd43bae2c23ba50086 size: 856
```

The registry manifest written for `v0.1.0` is what Kubernetes later uses when resolving the image reference during deployment.

## 4) Verify the registry tag and manifest

To confirm the tag and its digest are visible in the registry (i.e., not just in your local Docker cache), inspect the image with Docker Buildx imagetools:

```bash theme={null}
docker buildx imagetools inspect $IMG
```

Example output shows the tag's digest and the platform manifests it references:

```console theme={null}
Digest: sha256:db81233d7799521a10305a9e722847a1920e2ceec4f67fdd43bae2c23ba50086

Manifests:
  Name: 127.0.0.1:5000/course/webapp-operator:v0.1.0@sha256:8a81b15d6d50b0094af375f659be04fdcb422a84ccd50d7e5b5968dcf220ab6a
  MediaType: application/vnd.oci.image.manifest.v1+json
  Platform:
    linux/amd64

  Name: 127.0.0.1:5000/course/webapp-operator:v0.1.0@sha256:5adf21588e94c411886136fcad009a7cfa809ab043dd059a09e22b
  MediaType: application/vnd.oci.image.manifest.v1+json
  Platform: unknown/unknown
```

<Callout icon="lightbulb" color="#1CB2FE">
  Tags (like `v0.1.0`) are mutable references, while the digest (`sha256:...`) is the immutable content identifier. Using the digest (for example `image: 127.0.0.1:5000/course/webapp-operator@sha256:<digest>`) in manifests or deployment specs guarantees the exact image bytes that will be pulled.
</Callout>

<Callout icon="warning" color="#FF6B6B">
  If you're using a local registry (e.g., `127.0.0.1:5000`) make sure the registry service is running and your Docker daemon is configured to allow pushing to that host (insecure registry settings may be required). Pushing to remote registries may also require authentication.
</Callout>

## Quick reference — common commands

| Step          | Command                                                   | Purpose                                                    |
| ------------- | --------------------------------------------------------- | ---------------------------------------------------------- |
| Set image tag | `export IMG=127.0.0.1:5000/course/webapp-operator:v0.1.0` | Point `IMG` at the registry and tag to use                 |
| Build         | `make docker-build IMG=$IMG`                              | Build the multi-stage Docker image with the provided tag   |
| Push          | `make docker-push IMG=$IMG`                               | Upload layers and create a registry manifest for the tag   |
| Inspect       | `docker buildx imagetools inspect $IMG`                   | Verify tag, digest, and platform manifests in the registry |

## Deploying with the pushed image

Now that the controller image is available from the registry, pass the same `IMG` value into your deployment step (for example):

```bash theme={null}
make deploy IMG=$IMG
```

Or pin by digest in Kubernetes manifests:

```yaml theme={null}
# example snippet
containers:
  - name: manager
    image: 127.0.0.1:5000/course/webapp-operator@sha256:db81233d7799521a10305a9e722847a1920e2ceec4f67fdd43bae2c23ba50086
```

Using the digest above ensures the cluster pulls the exact content you pushed.

## Links and references

* [Docker Buildx imagetools](https://docs.docker.com/buildx/working-with-buildx/#imagetools)
* [Kubernetes Documentation — Images](https://kubernetes.io/docs/concepts/containers/images/)
* [Docker Registry (distribution) GitHub](https://github.com/distribution/distribution)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/kubernetes-operators/module/5a9bfe56-bc26-4325-b659-06027d4e815f/lesson/fa37ed3b-f8dd-4a7b-8859-c344c18d5ed1" />
</CardGroup>
