Why a private registry?
- Manage images that cannot be made public
- Bypass Docker Hub rate limits
- Faster builds (internal network)
- Integrated vulnerability scanning and access control
1. Harbor — Self-hosted registry
Bash
# Docker Compose Harbor
curl -LO https://github.com/goharbor/harbor/releases/latest/download/harbor-online-installer.tgz
tar xzf harbor-online-installer.tgz
cd harbor
# harbor.yml settings
cp harbor.yml.tmpl harbor.yml
# hostname, https.certificate, https.private_key
#
sudo ./install.sh --with-trivy # TrivyLogin and image push:
Bash
docker login harbor.example.com
docker tag myapp:latest harbor.example.com/myproject/myapp:latest
docker push harbor.example.com/myproject/myapp:latest
docker pull harbor.example.com/myproject/myapp:latest2. AWS ECR (Elastic Container Registry)
Bash
#
aws ecr create-repository --repository-name myapp --region ap-northeast-2
# URI check
aws ecr describe-repositories --query 'repositories[0].repositoryUri' --output text
# ( 12when )
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com
# + push
REGISTRY=123456789012.dkr.ecr.ap-northeast-2.amazonaws.com
docker tag myapp:latest ${REGISTRY}/myapp:latest
docker push ${REGISTRY}/myapp:latest
# image list
aws ecr list-images --repository-name myapp
#
aws ecr put-lifecycle-policy --repository-name myapp --lifecycle-policy-text '{
"rules": [{
"rulePriority": 1,
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 7
},
"action": {"type": "expire"}
}]
}'3. GitHub Container Registry (GHCR)
Bash
# PAT : GitHub → Settings → Developer settings → Personal access tokens
# : write:packages, read:packages, delete:packages
#
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin
# push
docker tag myapp:latest ghcr.io/USERNAME/myapp:latest
docker push ghcr.io/USERNAME/myapp:latestIn GitHub Actions:
YAML
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/${{ github.repository }}:latestUsing a private registry in Kubernetes
Bash
# imagePullSecret
kubectl create secret docker-registry regcred --docker-server=harbor.example.com --docker-username=admin --docker-password=Harbor12345 --namespace=defaultYAML
# deployment.yaml
spec:
template:
spec:
imagePullSecrets:
- name: regcred
containers:
- name: myapp
image: harbor.example.com/myproject/myapp:latestWith ECR you can skip secrets by using IRSA (IAM Roles for Service Accounts):
Bash
# eksctl IRSA settings
eksctl create iamserviceaccount --name ecr-access --namespace default --cluster my-cluster --attach-policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly --approveEditorial note
AI tools may assist drafting. Check the evidence in each guide for whether commands were run and which environment was used. Confirm the current docs for your version before applying instructions, and email us about errors. email us
Topic-related official docs (auto-linked · not per-claim sources)Kubernetes documentation ↗Docker documentation ↗AWS documentation ↗
Questions & answers
Ask a question about this guide. We'll review and reply.