I'm trying to access a docker registry (public or private) using Go. A simple program which can access any registry and verify if an image is present.
I looked at docker client available in Go https://pkg.go.dev/github.com/docker/[email protected] incompatible/client
But the problem is, this client needs a docker daemon running in order to work. Is there any way to query a docker registry (ex: hub.docker.com) without any dependency on underlying docker engine?
My idea is to run this program on a docker container and there wont be any docker engine running inside a container. And I don't want to run docker inside docker or any sort of hack. I just want to connect to a registry and query an image. And please don't quote other questions in stack overflow. No one has answered this.
This is what I have done so far
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"github.com/docker/docker/api/types/filters"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
)
func main() {
cli, err := client.NewClientWithOpts(client.WithHost("https://hub.docker.com"), client.WithAPIVersionNegotiation())
if err != nil {
fmt.Println(err.Error())
return
}
err = imagemanifest(cli)
if err != nil {
fmt.Println(err)
}
err = imageSearch(cli)
}
func imagemanifest(dockerClient *client.Client) error {
var authConfig = types.AuthConfig{
Username: "amokkara",
Password: "M@vr1ck2009",
ServerAddress: "https://index.docker.io/v2/",
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second*1200)
defer cancel()
authConfigBytes, _ := json.Marshal(authConfig)
authConfigEncoded := base64.URLEncoding.EncodeToString(authConfigBytes)
ctx, cancel = context.WithTimeout(context.Background(), time.Second*1200)
defer cancel()
searchres , err := dockerClient.DistributionInspect(ctx,"amokkara/amokkara:3",authConfigEncoded)
if err != nil {
return err
}
fmt.Println(searchres.Descriptor.Digest.String())
return nil
}
If I initialize client like this
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
This works because its using underlying docker daemon (in my case docker desktop) to query the registry. But if create client using
client.NewClientWithOpts(client.WithHost("https://hub.docker.com"), client.WithAPIVersionNegotiation())
it fails giving 404 error. Does this client require a docker daemon to work. If so, is there any other way i can query a registry? Please help me with this.
CodePudding user response:
Skopeo is the leader software on dealing with registries without daemon.
It's also written with Go.
You can inspire from inspect.go
Note that, you don't need to use github.com/docker/docker/*
modules, but it will be github.com/containers/*
, and namely https://github.com/containers/image