Claude Skill: Docker Registry Management for BattleScope
Purpose: Guide all Docker image building, tagging, versioning, and registry management for BattleScope services.
Core Principles
1. Image Naming Convention
Rule: All BattleScope images MUST follow this naming pattern:
<registry>/<organization>/<service>:<version>-<architecture>
Examples:
docker.io/battlescope/ingestion-service:v3.0.0-amd64 docker.io/battlescope/enrichment-service:v3.0.0-arm64 docker.io/battlescope/battle-service:v3.1.2-amd64
Components:
- •Registry:
docker.io(Docker Hub - public registry) - •Organization:
battlescope - •Service: Service name in kebab-case
- •Version: Semantic versioning (v3.x.x for V3 architecture)
- •Architecture:
amd64orarm64(multi-arch support)
2. Versioning Strategy
Semantic Versioning
Format: vMAJOR.MINOR.PATCH
V3 Architecture:
- •Major Version:
v3(V3 architecture) - •Minor Version: Feature additions, non-breaking changes
- •Patch Version: Bug fixes, minor updates
Examples:
v3.0.0 - Initial V3 release v3.0.1 - Bug fix in ingestion service v3.1.0 - Added historical ingestion feature v3.2.0 - Added data retention policy
Image Tags
Required Tags for Each Image:
- •Specific Version:
v3.0.0-amd64 - •Major.Minor:
v3.0-amd64 - •Major:
v3-amd64 - •Latest:
latest-amd64(ONLY for latest stable release)
Multi-Arch Manifest Tags:
- •Specific Version:
v3.0.0(manifest pointing to all archs) - •Major.Minor:
v3.0 - •Major:
v3 - •Latest:
latest
Example Push Sequence:
# Build for amd64 docker build --platform linux/amd64 -t battlescope/ingestion-service:v3.0.0-amd64 . docker tag battlescope/ingestion-service:v3.0.0-amd64 battlescope/ingestion-service:v3.0-amd64 docker tag battlescope/ingestion-service:v3.0.0-amd64 battlescope/ingestion-service:v3-amd64 docker tag battlescope/ingestion-service:v3.0.0-amd64 battlescope/ingestion-service:latest-amd64 # Build for arm64 docker build --platform linux/arm64 -t battlescope/ingestion-service:v3.0.0-arm64 . docker tag battlescope/ingestion-service:v3.0.0-arm64 battlescope/ingestion-service:v3.0-arm64 docker tag battlescope/ingestion-service:v3.0.0-arm64 battlescope/ingestion-service:v3-arm64 docker tag battlescope/ingestion-service:v3.0.0-arm64 battlescope/ingestion-service:latest-arm64 # Push all tags docker push battlescope/ingestion-service:v3.0.0-amd64 docker push battlescope/ingestion-service:v3.0-amd64 docker push battlescope/ingestion-service:v3-amd64 docker push battlescope/ingestion-service:latest-amd64 docker push battlescope/ingestion-service:v3.0.0-arm64 docker push battlescope/ingestion-service:v3.0-arm64 docker push battlescope/ingestion-service:v3-arm64 docker push battlescope/ingestion-service:latest-arm64 # Create and push multi-arch manifest docker manifest create battlescope/ingestion-service:v3.0.0 \ battlescope/ingestion-service:v3.0.0-amd64 \ battlescope/ingestion-service:v3.0.0-arm64 docker manifest push battlescope/ingestion-service:v3.0.0 docker manifest create battlescope/ingestion-service:v3.0 \ battlescope/ingestion-service:v3.0-amd64 \ battlescope/ingestion-service:v3.0-arm64 docker manifest push battlescope/ingestion-service:v3.0 docker manifest create battlescope/ingestion-service:v3 \ battlescope/ingestion-service:v3-amd64 \ battlescope/ingestion-service:v3-arm64 docker manifest push battlescope/ingestion-service:v3 docker manifest create battlescope/ingestion-service:latest \ battlescope/ingestion-service:latest-amd64 \ battlescope/ingestion-service:latest-arm64 docker manifest push battlescope/ingestion-service:latest
3. BattleScope V3 Services
Service Image Names
| Service | Image Name | Description |
|---|---|---|
| Ingestion | battlescope/ingestion-service | Raw killmail acquisition |
| Enrichment | battlescope/enrichment-service | Killmail augmentation |
| Battle | battlescope/battle-service | Battle clustering |
| Search | battlescope/search-service | Full-text search |
| Notification | battlescope/notification-service | Real-time notifications |
| Frontend BFF | battlescope/frontend-bff | Backend-for-Frontend |
| Frontend | battlescope/frontend | Web UI |
Infrastructure Images (if custom)
| Component | Image Name | Description |
|---|---|---|
| Database Migrator | battlescope/db-migrator | Database migrations |
| Init Container | battlescope/init | Initialization tasks |
4. Never Overwrite Production Tags
CRITICAL RULE: NEVER overwrite existing production image tags.
Why:
- •Running pods may pull "updated" image causing inconsistency
- •Rollbacks become impossible
- •Audit trail is lost
- •Violates immutability principle
Correct Approach:
# ❌ WRONG - Overwriting existing tag docker build -t battlescope/ingestion-service:v3.0.0 . docker push battlescope/ingestion-service:v3.0.0 # Overwrites existing v3.0.0! # ✅ CORRECT - Create new version docker build -t battlescope/ingestion-service:v3.0.1 . docker push battlescope/ingestion-service:v3.0.1 # New tag, doesn't overwrite
Exception: latest tag can be updated (but use with caution in production)
5. Image Documentation
Docker Hub Repository Settings
For Each Service Repository:
- •
Description (Short):
codeBattleScope V3 - <Service Name> - <One-line description>
- •
Full Description (README.md):
markdown# BattleScope <Service Name> **Architecture**: V3 Distributed Microservices **Version**: v3.x.x ## Overview <Service description from service specification> ## Supported Tags - `v3.0.0`, `v3.0`, `v3`, `latest` - Multi-arch manifest - `v3.0.0-amd64`, `v3.0-amd64`, `v3-amd64`, `latest-amd64` - AMD64/x86_64 - `v3.0.0-arm64`, `v3.0-arm64`, `v3-arm64`, `latest-arm64` - ARM64 ## Quick Start ```bash docker pull battlescope/<service-name>:v3 docker run -p <port>:<port> battlescope/<service-name>:v3
Environment Variables
Variable Description Default PORTService port 3000KAFKA_BROKERSKafka connection string localhost:9092DATABASE_URLPostgreSQL connection string Required Health Check
bashcurl http://localhost:<port>/health
Documentation
License
MIT
code - •
Enable Auto-Build: If using GitHub integration
- •
Visibility: Public (for all BattleScope images)
6. Build Scripts
Makefile Integration
# Docker build variables DOCKER_REGISTRY ?= docker.io DOCKER_ORG ?= battlescope VERSION ?= v3.0.0 PLATFORMS ?= linux/amd64,linux/arm64 # Service-specific variables SERVICE_NAME := ingestion-service IMAGE_NAME := $(DOCKER_REGISTRY)/$(DOCKER_ORG)/$(SERVICE_NAME) # Build commands .PHONY: docker-build docker-push docker-build-push docker-manifest ## Build Docker image for current platform docker-build: @echo "Building $(IMAGE_NAME):$(VERSION) for current platform..." docker build -t $(IMAGE_NAME):$(VERSION) . ## Build multi-arch Docker images docker-build-multi: @echo "Building $(IMAGE_NAME):$(VERSION) for $(PLATFORMS)..." docker buildx build \ --platform $(PLATFORMS) \ -t $(IMAGE_NAME):$(VERSION) \ -t $(IMAGE_NAME):$(shell echo $(VERSION) | cut -d. -f1-2) \ -t $(IMAGE_NAME):$(shell echo $(VERSION) | cut -d. -f1) \ -t $(IMAGE_NAME):latest \ . ## Push Docker image docker-push: @echo "Pushing $(IMAGE_NAME):$(VERSION)..." docker push $(IMAGE_NAME):$(VERSION) docker push $(IMAGE_NAME):$(shell echo $(VERSION) | cut -d. -f1-2) docker push $(IMAGE_NAME):$(shell echo $(VERSION) | cut -d. -f1) docker push $(IMAGE_NAME):latest ## Build and push (convenience command) docker-build-push: docker-build docker-push ## Build multi-arch and push docker-build-push-multi: @echo "Building and pushing $(IMAGE_NAME):$(VERSION) for $(PLATFORMS)..." docker buildx build \ --platform $(PLATFORMS) \ --push \ -t $(IMAGE_NAME):$(VERSION) \ -t $(IMAGE_NAME):$(shell echo $(VERSION) | cut -d. -f1-2) \ -t $(IMAGE_NAME):$(shell echo $(VERSION) | cut -d. -f1) \ -t $(IMAGE_NAME):latest \ .
7. GitHub Actions CI/CD
Automated Image Building
# .github/workflows/docker-build.yml
name: Build and Push Docker Images
on:
push:
branches:
- main
tags:
- 'v*.*.*'
jobs:
build-and-push:
runs-on: ubuntu-latest
strategy:
matrix:
service:
- ingestion-service
- enrichment-service
- battle-service
- search-service
- notification-service
- frontend-bff
- frontend
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract version from tag
id: version
run: |
if [[ "${{ github.ref }}" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
else
echo "VERSION=v3.0.0-dev-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
fi
- name: Build and push
uses: docker/build-push-action@v5
with:
context: ./services/${{ matrix.service }}
platforms: linux/amd64,linux/arm64
push: true
tags: |
battlescope/${{ matrix.service }}:${{ steps.version.outputs.VERSION }}
battlescope/${{ matrix.service }}:latest
cache-from: type=registry,ref=battlescope/${{ matrix.service }}:buildcache
cache-to: type=registry,ref=battlescope/${{ matrix.service }}:buildcache,mode=max
8. Image Security and Scanning
Best Practices
- •
Base Images:
dockerfile# Use official Node.js LTS with Alpine for smaller size FROM node:20-alpine AS base
- •
Non-Root User:
dockerfile# Create non-root user RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001 USER nodejs
- •
Multi-Stage Builds:
dockerfileFROM node:20-alpine AS builder # Build stage FROM node:20-alpine AS runner # Runtime stage (smaller final image)
- •
Security Scanning:
bash# Scan images before pushing docker scan battlescope/ingestion-service:v3.0.0
9. Registry Cleanup Policy
Retention Rules
Keep:
- •All major versions (v3.x.x, v4.x.x, etc.)
- •Last 10 minor versions of current major
- •Last 5 patch versions of current minor
- •
latesttag
Delete:
- •Dev/test tags older than 30 days
- •Untagged images (dangling)
- •Superseded patch versions (keep last 5 only)
Cleanup Script
#!/bin/bash
# cleanup-old-images.sh
REGISTRY="docker.io"
ORG="battlescope"
SERVICE="$1"
# List all tags
TAGS=$(curl -s "https://hub.docker.com/v2/repositories/${ORG}/${SERVICE}/tags/?page_size=100" | jq -r '.results[].name')
# Delete dev tags older than 30 days
for TAG in $TAGS; do
if [[ "$TAG" =~ -dev- ]]; then
# Check age and delete if > 30 days
echo "Considering $TAG for deletion..."
fi
done
10. Kubernetes Image References
Pod Spec Image Reference
apiVersion: apps/v1
kind: Deployment
metadata:
name: ingestion-service
spec:
template:
spec:
containers:
- name: ingestion-service
# ✅ CORRECT - Use specific version tag
image: battlescope/ingestion-service:v3.0.0
imagePullPolicy: IfNotPresent
# ❌ WRONG - Using 'latest' in production
# image: battlescope/ingestion-service:latest
# imagePullPolicy: Always
Image Pull Policy:
- •
IfNotPresent- Pull only if not cached (recommended for versioned tags) - •
Always- Always pull (use forlatesttag only, not recommended for production) - •
Never- Never pull (use for local development only)
11. Image Registry Credentials
Docker Hub Authentication
Local Development:
docker login docker.io # Enter username and password
Kubernetes Secret:
kubectl create secret docker-registry docker-hub-creds \ --docker-server=docker.io \ --docker-username=<username> \ --docker-password=<password> \ --docker-email=<email> \ --namespace=battlescope
Pod Spec:
spec:
imagePullSecrets:
- name: docker-hub-creds
12. Troubleshooting
Common Issues
Issue: Image not found
Error: Failed to pull image "battlescope/ingestion-service:v3.0.0": rpc error: code = NotFound
Solution:
# Verify image exists docker pull battlescope/ingestion-service:v3.0.0 # Check tag exists on Docker Hub curl https://hub.docker.com/v2/repositories/battlescope/ingestion-service/tags | jq '.results[].name'
Issue: Architecture mismatch
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8)
Solution:
# Pull multi-arch manifest (not architecture-specific tag) docker pull battlescope/ingestion-service:v3.0.0 # Multi-arch manifest # NOT: battlescope/ingestion-service:v3.0.0-amd64
Summary Checklist
Before pushing any image:
- • Image follows naming convention:
battlescope/<service>:v3.x.x - • Version tag is unique (not overwriting existing tag)
- • Multi-arch build (amd64 + arm64)
- • All required tags created (version, major.minor, major, latest)
- • Docker Hub repository has proper description
- • Image scanned for vulnerabilities
- • Kubernetes manifests updated with new version
- • CHANGELOG updated with new version
Remember: Images are immutable. Never overwrite an existing production tag!