Ravindra BagaleCourses & study guides मराठी

Chapter 73: DevOps Projects Part 3: Docker Websites, APIs, Compose, Registry and ECR

73.9 Project 25: Run a private Docker registry

Friends, teams need a place to store images that is not a public hub. Today we run registry:2 on port 5000 with a volume, tag and push an nginx image, pull it back, and call the v2 catalog API.

What you will build in this project

  1. registry:2 on :5000.
  2. Push and pull localhost:5000/shop-nginx.
  3. Catalog and tags API.
  4. Volume keeps blobs across restart.

1. Start from a real company story

At Freshworks in Chennai, developers pushed images to a shared laptop folder with scp. Digests never matched and one bad copy hit staging.

A rollback failed for 40 minutes. Rough cost: about ₹6 lakh in SLA credits.

Meera stood up a private registry with a volume and digest pins in Compose.

Today we run that registry lab on localhost:5000.

registry:2:5000 + volumedocker taglocalhost:5000/...docker pushlayers + digestpull + curl catalogproven
Picture 1: build → tag → push → pull from private registry

Ravindra Bagale's Tip

Many students run a registry with no volume and wonder where tags went after restart. Mount /var/lib/registry. Keep that habit.

2. Start and prepare

Step 1: Run registry container

Why: Need a place to store images. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: docker run registry:2. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 1: run

Type this:

docker rm -f local-registry >/dev/null 2>&1; docker volume create registry-data >/dev/null; docker run -d --name local-registry -p 5000:5000 -v registry-data:/var/lib/registry registry:2 && echo started

You will see:

started

What it means: Registry up.

Example 2: ps

Type this:

docker ps --filter name=local-registry --format '{{.Names}} {{.Ports}}'

You will see:

local-registry 0.0.0.0:5000->5000/tcp

What it means: Mapped.

Example 3: v2

Type this:

curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:5000/v2/

You will see:

200

What it means: API.

Step 2: Tag local image

Why: Tag includes registry host. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: docker tag. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 4: need image

Type this:

docker images nginx:1.27-alpine -q | head -1 || docker pull nginx:1.27-alpine

You will see:

sha...

What it means: Base image.

Example 5: tag

Type this:

docker tag nginx:1.27-alpine localhost:5000/shop-nginx:1.0 && docker images localhost:5000/shop-nginx --format '{{.Repository}}:{{.Tag}}'

You will see:

localhost:5000/shop-nginx:1.0

What it means: Tagged.

Example 6: why host

Type this:

echo 'The first path segment before / is the registry host:port'

You will see:

The first path segment before / is the registry host:port

What it means: Rule.

Step 3: Push to localhost

Why: Push uploads layers. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: docker push. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 7: push

Type this:

docker push localhost:5000/shop-nginx:1.0

You will see:

Pushed ... digest: sha256:...

What it means: Pushed.

Example 8: ok

Type this:

echo push_ok

You will see:

push_ok

What it means: OK.

Example 9: note

Type this:

echo 'If push fails with HTTP, check insecure-registries only for lab hosts'

You will see:

If push fails with HTTP, check insecure-registries only for lab hosts

What it means: Lab tip.

3. Build the main pieces

Step 4: Pull from registry

Why: Pull proves registry. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: docker pull. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 10: rmi local tag optional

Type this:

docker rmi localhost:5000/shop-nginx:1.0 >/dev/null 2>&1; echo cleared_local_tag

You will see:

cleared_local_tag

What it means: Force pull.

Example 11: pull

Type this:

docker pull localhost:5000/shop-nginx:1.0

You will see:

Pulled ...

What it means: Pulled.

Example 12: images

Type this:

docker images localhost:5000/shop-nginx:1.0 --format '{{.Repository}}:{{.Tag}}'

You will see:

localhost:5000/shop-nginx:1.0

What it means: Listed.

Step 5: List catalog

Why: Catalog lists repos. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: curl _catalog. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 13: catalog

Type this:

curl -s http://127.0.0.1:5000/v2/_catalog

You will see:

{"repositories":["shop-nginx"]}

What it means: Catalog.

Example 14: tags

Type this:

curl -s http://127.0.0.1:5000/v2/shop-nginx/tags/list

You will see:

{"name":"shop-nginx","tags":["1.0"]}

What it means: Tags.

Example 15: code

Type this:

curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:5000/v2/_catalog

You will see:

200

What it means: OK.

Step 6: Verify digest

Why: Digest pins content. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: inspect RepoDigests. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 16: digest

Type this:

docker image inspect localhost:5000/shop-nginx:1.0 --format '{{index .RepoDigests 0}}'

You will see:

localhost:5000/shop-nginx@sha256:...

What it means: Digest.

Example 17: pin tip

Type this:

echo 'Prefer digest pins in production compose and k8s'

You will see:

Prefer digest pins in production compose and k8s

What it means: Habit.

Example 18: id

Type this:

docker images localhost:5000/shop-nginx:1.0 --format '{{.ID}}'

You will see:

sha256:...

What it means: ID.

4. Automate and verify

Step 7: Restart registry volume

Why: Volume keeps blobs. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: volume mount. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 19: restart

Type this:

docker restart local-registry && sleep 2 && curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:5000/v2/

You will see:

200

What it means: Still up.

Example 20: catalog2

Type this:

curl -s http://127.0.0.1:5000/v2/_catalog

You will see:

{"repositories":["shop-nginx"]}

What it means: Data kept.

Example 21: vol

Type this:

docker volume inspect registry-data --format '{{.Name}}'

You will see:

registry-data

What it means: Volume.

Step 8: Push again

Why: Second push is faster. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: push again. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 22: retag

Type this:

docker tag localhost:5000/shop-nginx:1.0 localhost:5000/shop-nginx:1.1 && docker push localhost:5000/shop-nginx:1.1

You will see:

Pushed

What it means: Second tag.

Example 23: tags2

Type this:

curl -s http://127.0.0.1:5000/v2/shop-nginx/tags/list

You will see:

...1.0...1.1...

What it means: Two tags.

Example 24: layers

Type this:

echo 'Second push reuses layers; output shows Mounted from'

You will see:

Second push reuses layers; output shows Mounted from

What it means: Cache.

Step 9: Pull on clean name

Why: Retag pull. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: rmi then pull. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 25: rmi

Type this:

docker rmi localhost:5000/shop-nginx:1.1 >/dev/null 2>&1; docker pull localhost:5000/shop-nginx:1.1

You will see:

Pulled

What it means: Clean pull.

Example 26: run

Type this:

docker rm -f reg-test >/dev/null 2>&1; docker run -d --name reg-test -p 8089:80 localhost:5000/shop-nginx:1.1 && curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8089/

You will see:

200

What it means: Runs.

Example 27: stop

Type this:

docker rm -f reg-test >/dev/null; echo cleaned

You will see:

cleaned

What it means: Clean.

5. Harden and accept

Step 10: curl v2 API

Why: HTTP API check. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: /v2/. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 28: v2

Type this:

curl -s http://127.0.0.1:5000/v2/

You will see:

{}

What it means: Empty JSON OK.

Example 29: headers

Type this:

curl -sI http://127.0.0.1:5000/v2/ | head -3

You will see:

HTTP/1.1 200 OK

What it means: Headers.

Example 30: catalog

Type this:

curl -s http://127.0.0.1:5000/v2/_catalog

You will see:

{"repositories":["shop-nginx"]}

What it means: Still.

Step 11: Auth note

Why: Real registries need TLS+auth. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: htpasswd note. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 31: auth

Type this:

echo 'Production: put TLS and htpasswd or SSO in front of the registry'

You will see:

Production: put TLS and htpasswd or SSO in front of the registry

What it means: Real life.

Example 32: insecure

Type this:

echo 'Do not leave insecure-registries on company laptops'

You will see:

Do not leave insecure-registries on company laptops

What it means: Safety.

Example 33: cleanup tip

Type this:

echo 'Lab: docker rm -f local-registry; keep volume if you want blobs'

You will see:

Lab: docker rm -f local-registry; keep volume if you want blobs

What it means: Cleanup.

Step 12: Acceptance checklist

Why: Meera signs off when push and pull work. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the stack is healthy today.

What: All green. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn Compose and registries.

Example 34: push ok

Type this:

curl -s http://127.0.0.1:5000/v2/shop-nginx/tags/list | grep 1.0

You will see:

1.0

What it means: Tag.

Example 35: pull ok

Type this:

docker images localhost:5000/shop-nginx --format '{{.Tag}}' | head

You will see:

1.0

What it means: Local.

Example 36: Sign-off

Type this:

echo 'Meera: PASS'

You will see:

Meera: PASS

What it means: Done.

Check yourself

Q1. Who fixed Freshworks image chaos?

Meera

Q2. Registry image?

registry:2

Q3. Host port?

5000

Q4. Catalog path?

/v2/_catalog

Q5. Volume path in container?

/var/lib/registry

Q6. Why digest pins?

Immutable content

Friends, you pushed and pulled through a private registry. Did you understand? Let us try it once more. Add a second tag and pin a service by digest in a tiny compose file.

Lab: try at home

  1. Run registry:2 with a volume.
  2. Tag nginx to localhost:5000.
  3. Push and pull.
  4. curl the catalog.
  5. Restart and confirm tags remain.

Recap

  • Tag must include registry host.
  • Volume keeps blobs.
  • Digests pin immutable content.
  • Lab HTTP is not production TLS.
  • Catalog API lists repositories.