Set up and manage container registries with security scanning and access control.
You are a container registry expert. Help me set up a secure registry.
## Registry Needs
Platform: ${{PLATFORM}}
Access control: ${{ACCESS}}
Security: ${{SECURITY}}
Storage: ${{STORAGE}}
## Please Configure:
1. **AWS ECR Setup**
```hcl
# Terraform ECR
resource "aws_ecr_repository" "app" {
name = "myapp"
image_tag_mutability = "IMMUTABLE"
image_scanning_configuration {
scan_on_push = true
}
encryption_configuration {
encryption_type = "KMS"
kms_key = aws_kms_key.ecr.arn
}
}
resource "aws_ecr_lifecycle_policy" "app" {
repository = aws_ecr_repository.app.name
policy = jsonencode({
rules = [
{
rulePriority = 1
description = "Keep last 30 images"
selection = {
tagStatus = "tagged"
tagPrefixList = ["v"]
countType = "imageCountMoreThan"
countNumber = 30
}
action = {
type = "expire"
}
},
{
rulePriority = 2
description = "Delete untagged images after 7 days"
selection = {
tagStatus = "untagged"
countType = "sinceImagePushed"
countUnit = "days"
countNumber = 7
}
action = {
type = "expire"
}
}
]
})
}
```
2. **ECR IAM Policy**
```hcl
resource "aws_iam_policy" "ecr_push" {
name = "ecr-push-policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage"
]
Resource = aws_ecr_repository.app.arn
}
]
})
}
```
3. **GitHub Container Registry**
```yaml
# GitHub Actions workflow
name: Build and Push
on:
push:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@v5
id: meta
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=sha
type=semver,pattern={{version}}
- uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
```
4. **Harbor Setup**
```yaml
# Harbor Helm values
expose:
type: ingress
tls:
enabled: true
certSource: secret
secret:
secretName: harbor-tls
ingress:
hosts:
core: harbor.example.com
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
persistence:
enabled: true
persistentVolumeClaim:
registry:
size: 100Gi
database:
size: 10Gi
harborAdminPassword: "secure-password"
trivy:
enabled: true
notary:
enabled: true
```
5. **Image Scanning**
```bash
# Trivy scanning
trivy image myregistry/myimage:latest
# Grype scanning
grype myregistry/myimage:latest
# CI integration
- name: Scan image
uses: aquasecurity/trivy-action@master
with:
image-ref: '${{ env.IMAGE_NAME }}'
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
```
6. **Registry Mirroring**
```yaml
# containerd config for mirroring
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://mirror.gcr.io", "https://registry-1.docker.io"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."myregistry.io"]
endpoint = ["https://myregistry.io"]
```
7. **Authentication**
```bash
# Docker login
docker login myregistry.io -u username -p password
# Service account for Kubernetes
kubectl create secret docker-registry regcred \
--docker-server=myregistry.io \
--docker-username=username \
--docker-password=password \
--docker-email=email@example.com
# Use in deployment
spec:
imagePullSecrets:
- name: regcred
```
8. **Cleanup Automation**
```bash
#!/bin/bash
# Cleanup old images
# AWS ECR
aws ecr describe-images --repository-name myapp \
--query 'imageDetails[?imagePushedAt<=`2024-01-01`].imageDigest' \
--output text | xargs -I {} aws ecr batch-delete-image \
--repository-name myapp --image-ids imageDigest={}
# GHCR
gh api -X DELETE /user/packages/container/myapp/versions/123
```Or press ⌘C to copy
Replace these placeholders with your own content before using the prompt.
[{PLATFORM][{ACCESS][{SECURITY][{STORAGE]{
name = "myapp"
image_tag_mutability = "IMMUTABLE"
image_scanning_configuration {
scan_on_push = true
}{
encryption_type = "KMS"
kms_key = aws_kms_key.ecr.arn
}{
repository = aws_ecr_repository.app.name
policy = jsonencode({
rules = [
{
rulePriority = 1
description = "Keep last 30 images"
selection = {
tagStatus = "tagged"
tagPrefixList = ["v"]
countType = "imageCountMoreThan"
countNumber = 30
}{
type = "expire"
}{
rulePriority = 2
description = "Delete untagged images after 7 days"
selection = {
tagStatus = "untagged"
countType = "sinceImagePushed"
countUnit = "days"
countNumber = 7
}{
name = "ecr-push-policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage"
]
Resource = aws_ecr_repository.app.arn
}{{ github.repository }{{ env.REGISTRY }{{ github.actor }{{ secrets.GITHUB_TOKEN }{{ env.IMAGE_NAME }{{version}{{ steps.meta.outputs.tags }