I feel love I’ve written a post on this before, but it doesn’t hurt to keep things upto date.
I set up a Kubernetes instance along with container registry etc. within Azure, but if all you want to do is run things locally and at zero cost (other than you usual cost of running a computer), you might want to set up a local container registry.
I’m doing this on Windows for this post, but I expect it’s pretty much the same on Linux and Mac, but in my case I am also running Docker Desktop.
docker-compose
We’re going to stand up the registry using docker-compose, but if you’d like to just run the registry from the simple docker run command, you can use this
docker run -d -p 5000:5000 --name registry registry:2
However you’ll probably want a volume set-up, along with a web UI, so let’s put all that together into the docker-compose.yml file below
version: '3.8'
services:
registry:
image: registry:2
container_name: container-registry
ports:
- "5000:5000"
environment:
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/lib/registry
REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '["http://localhost:8080"]'
REGISTRY_HTTP_HEADERS_Access-Control-Allow-Methods: '["GET", "HEAD", "DELETE"]'
REGISTRY_HTTP_HEADERS_Access-Control-Allow-Credentials: '["true"]'
volumes:
- registry-data:/var/lib/registry
registry-ui:
image: joxit/docker-registry-ui:latest
container_name: registry-ui
ports:
- "8080:80"
environment:
- REGISTRY_TITLE=Private Docker Registry
- REGISTRY_URL=http://localhost:5000
- DELETE_IMAGES=true
depends_on:
- registry
volumes:
registry-data:
Note: if you’re going to be running your services on port 8080, you might wish to change the UI here to use port 8081, for example.
In the above I name my container container-registry as I already have a registry container running on my machine, the REGISTRY_HTTP_HEADERS_Access were required as I was getting CORS like issues. Finally we run up the joxit/docker-registry-ui which gives us a web UI to our registry.
To run everything just type
docker-compose up
and use ctrl+c to bring this down when in interactive mode or run
docker-compose down
If you want to clear up the volume (i.e. remove it) use
docker-compose down -v
Ofcourse you can also use curl etc. to interact with the registry itself, for example to list the repositories
curl http://localhost:500/v2/_catalog
Tag and push
We’re obviously going to need to push images to the registry and this is done by first, tagging them (as usual) then pushing, so for example
docker tag putridparrot.echo_service:v1 localhost:5000/putridparrot.echo_service:v1
which tags the image I already created for a simple “echo service”.
Next we push the tagged image to the registry using
docker push localhost:5000/putridparrot.echo_service:v1
If you’re running the web UI you should be able to see the repository with your new tagged image.
Pull
Obviously we’ll want to be able to pull an image from the registry either to run locally or to deploy within a Kubernetes cluster etc.
docker pull localhost:5000/putridparrot.echo_service:v1
Deployment
If some coming posts I will be writing an echo service in multiple languages, so let’s assume this echo_services is one of those. We’re going to want to run things locally so we might have a deployments.yaml with the following deployment and service
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo
namespace: dev
labels:
app: echo
spec:
replicas: 1
selector:
matchLabels:
app: echo
template:
metadata:
labels:
app: echo
spec:
containers:
- name: echo
image: localhost:5000/putridparrot.echo_service:v1
ports:
- containerPort: 8080
resources:
requests:
memory: "100Mi"
cpu: "100m"
limits:
memory: "200Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /livez
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /readyz
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: echo-service
namespace: dev
labels:
app: echo
spec:
type: ClusterIP
selector:
app: echo
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
Now we can use port forwarding in place on an ingress service if we’d like, for testing, like this
kubectl port-forward svc/echo-service 8080:8080 -n dev
and now use http://localhost:8080/echo?text=Putridparrot
Other options to get this deployment running with ingress require hosts file changes or we can add a load balancer, for example
apiVersion: v1
kind: Service
metadata:
name: echo-service
spec:
type: LoadBalancer
selector:
app: echo
ports:
- protocol: TCP
port: 8080
targetPort: 8080