From 2a8e544de333115181cf81c27c8a02c2aa0e19cd Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Fri, 26 Jun 2026 23:37:52 +1000 Subject: [PATCH] feat: add Docker Registry V2 endpoint at /v2/ (#57) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The v3 Go rewrite removed the /v2/ Docker Registry compatibility endpoint. Docker clients need: - GET/HEAD /v2/ → 200 (registry ping) - GET/HEAD /v2/{remoteName}/* → proxy to the docker remote Usage: `docker pull artifactapi.example.com/{remoteName}/image:tag` Reviewed-on: https://git.unkin.net/unkin/artifactapi/pulls/57 Co-authored-by: Ben Vincent Co-committed-by: Ben Vincent --- internal/api/v1/proxy.go | 14 ++++++++++++++ internal/server/server.go | 1 + 2 files changed, 15 insertions(+) diff --git a/internal/api/v1/proxy.go b/internal/api/v1/proxy.go index f37719a..9092bfa 100644 --- a/internal/api/v1/proxy.go +++ b/internal/api/v1/proxy.go @@ -37,6 +37,20 @@ func (h *ProxyHandler) Routes() chi.Router { return r } +func (h *ProxyHandler) DockerV2Routes() chi.Router { + r := chi.NewRouter() + r.Get("/", h.handleDockerPing) + r.Head("/", h.handleDockerPing) + r.Get("/{remoteName}/*", h.handleProxy) + r.Head("/{remoteName}/*", h.handleProxy) + return r +} + +func (h *ProxyHandler) handleDockerPing(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Docker-Distribution-Api-Version", "registry/2.0") + w.WriteHeader(http.StatusOK) +} + func (h *ProxyHandler) handleProxy(w http.ResponseWriter, r *http.Request) { remoteName := chi.URLParam(r, "remoteName") path := chi.URLParam(r, "*") diff --git a/internal/server/server.go b/internal/server/server.go index b28e6b9..00ea708 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -96,6 +96,7 @@ func (s *Server) routes() chi.Router { proxyHandler := v1.NewProxyHandler(s.engine, s.virtEngine, s.db, s.store, s.localHandler) r.Mount("/api/v1", proxyHandler.Routes()) + r.Mount("/v2", proxyHandler.DockerV2Routes()) remotesHandler := v2.NewRemotesHandler(s.db) virtualsHandler := v2.NewVirtualsHandler(s.db)