Previously we have written a simple API server that interacts with MongoDB, redis, and influxDB. We also managed to run our deployments on our Kubernetes cluster with the image pulled from docker.
Now let's try to create our own private image repository. The Gitea application we set up before has a container registry that is compliant with the Open Container Initiative. As such, we can push and pull docker images to our Gitea.
Prerequisites: we need to have SSL enabled on our Gitea application, check here to find out more on how to enable it.
Pushing to a private repository
My main PC is using Docker Desktop with WSL2. To push our image successfully, we must enable insecure-registries in the Docker desktop configuration.
Under Settings -> Docker Engine, add the following:
{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"experimental": false,
"insecure-registries": [
"192.168.1.4:3000"
]
}
192.168.1.4:3000 is the URL of our Gitea application. This can be a simple domain name such as gitea.local if the DNS record is added into the DNS server (e.g. on PiHole).
Perform a login to save credentials, and enter the username and password used for Gitea login. Here I have an account name called andre.
docker login 192.168.1.4:3000 --username andre --password *******
Next, we need to tag the docker image before pushing. According to Gitea documentation:

We need to first tag our image according to the above format
docker tag 9b0f43d3c161 192.168.1.4:3000/andre/api-server:1.0.1
docker build -t 192.168.1.4:3000/andre/api-server:1.0.1 .
Now we can push to Gitea as shown below
docker push 192.168.1.4:3000/andre/api-server:1.0.1
curl -ik --user andre https://192.168.1.4:3000/v2/_catalog
curl -ik --user andre https://192.168.1.4:3000/v2/andre/api-server/tags/list
Here is a list of APIs we can use to view the images we have pushed
Pulling from a private repository
we are following their guide here
we first create our auth value which comprises of <username>:<password> which is then baseb4 encoded. We use -n to prevent echo from adding extra newlines.
echo -n "andre:12345678" | base64
Next, we can create our dockerconfig.json to store our credentials secrets. The "192.168.1.4:3000" key is the IP and port where our image repository is located, we provide the credential info such as username, password, email and auth, which we had just encoded earlier into this JSON file.
{
"auths": {
"192.168.1.4:3000": {
"username": "andre",
"password": "12345678",
"email": "andre@mail.com",
"auth": "YW5kcmU6MTIzNDU2Nzg="
}
}
}
Now we can parse this JSON file into base64 again.
base64 dockerconfig.json
using this output value, we can then create a image-pull-secret.yaml file and store this value under data.\.dockerconfigjson. The type of secret here is kubernetes.io/dockerconfigjson, which is used to authenticate with a container registry when pulling a private image.
apiVersion: v1
kind: Secret
metadata:
name: image-pull-secret
data:
.dockerconfigjson: eyJhdXRocyI6eyIxOTIuMTY4LjEuNDozMDAwIjp7InVzZXJuYW1lIjoiYW5kcmUiLCJwYXNzd29yZCI6IjEyMzQ1Njc4IiwiZW1haWwiOiJhbmRyZUBtYWlsLmNvbSIsImF1dGgiOiJZVzVrY21VNk1USXpORFUyTnpnPSJ9fX0=
type: kubernetes.io/dockerconfigjson
Now we just need to include this secret in our api-server.yaml so that it knows to use this to authenticate our Gitea application
We can add imagePullSecrets it under the deployment spec.template.spec.
Change the spec.template.spec.containers.image to the one pointing to your private image repository as well
image: 192.168.1.4:3000/andre/api-server:1.0.1
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server-deployment
annotations:
description: "this is my normal backend server deployment"
version: "1.0"
spec:
replicas: 1
selector:
matchLabels:
app: api-server
template:
metadata:
labels:
app: api-server
spec:
containers:
- name: api-server-container
image: 192.168.1.4:3000/andre/api-server:1.0.1
resources:
limits:
memory: "512Mi"
cpu: "1"
requests:
memory: "256Mi"
cpu: "0.2"
ports:
- containerPort: 8080
envFrom:
- configMapRef:
name: homek8-configmap
- secretRef:
name: homek8-secret
imagePullSecrets:
- name: image-pull-secret
Making deployments to k8s
Now we are ready to deploy to Kubernetes.
First, we need to ensure that we added our Gitea SSL certificate to our Kubernetes nodes. To do that, copy the giteaCA.crt over to our k8 nodes then update the ca-certificate:
sudo cp giteaCA.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
Next, we can create a namespace for deployment:
kubectl create namespace homek8-custom-registry
kubectl config set-context --current --namespace=homek8-custom-registry
Lastly, deploy
kubectl apply -f .
Now we can see the container being successfully pulled and created.