feat: add private Docker registry authentication for base images
All checks were successful
Check / check (pull_request) Successful in 3m34s
All checks were successful
Check / check (pull_request) Successful in 3m34s
Add per-app registry credentials that are passed to Docker during image builds, allowing apps to use base images from private registries. - New registry_credentials table (migration 007) - RegistryCredential model with full CRUD operations - Docker client passes AuthConfigs to ImageBuild when credentials exist - Deploy service fetches app registry credentials before builds - Web UI section for managing registry credentials (add/edit/delete) - Comprehensive unit tests for model and auth config builder - README updated to list the feature
This commit is contained in:
@@ -20,6 +20,7 @@ import (
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/go-connections/nat"
|
||||
@@ -105,12 +106,20 @@ func (c *Client) IsConnected() bool {
|
||||
return c.docker != nil
|
||||
}
|
||||
|
||||
// RegistryAuth contains authentication credentials for a Docker registry.
|
||||
type RegistryAuth struct {
|
||||
Registry string
|
||||
Username string
|
||||
Password string //nolint:gosec // credential field required for registry auth
|
||||
}
|
||||
|
||||
// BuildImageOptions contains options for building an image.
|
||||
type BuildImageOptions struct {
|
||||
ContextDir string
|
||||
DockerfilePath string
|
||||
Tags []string
|
||||
LogWriter io.Writer // Optional writer for build output
|
||||
LogWriter io.Writer // Optional writer for build output
|
||||
RegistryAuths []RegistryAuth // Optional registry credentials for pulling private base images
|
||||
}
|
||||
|
||||
// BuildImage builds a Docker image from a context directory.
|
||||
@@ -161,6 +170,21 @@ type PortMapping struct {
|
||||
Protocol string // "tcp" or "udp"
|
||||
}
|
||||
|
||||
// buildAuthConfigs converts RegistryAuth slices into Docker's AuthConfigs map.
|
||||
func buildAuthConfigs(auths []RegistryAuth) map[string]registry.AuthConfig {
|
||||
configs := make(map[string]registry.AuthConfig, len(auths))
|
||||
|
||||
for _, auth := range auths {
|
||||
configs[auth.Registry] = registry.AuthConfig{
|
||||
Username: auth.Username,
|
||||
Password: auth.Password,
|
||||
ServerAddress: auth.Registry,
|
||||
}
|
||||
}
|
||||
|
||||
return configs
|
||||
}
|
||||
|
||||
// buildPortConfig converts port mappings to Docker port configuration.
|
||||
func buildPortConfig(ports []PortMapping) (nat.PortSet, nat.PortMap) {
|
||||
exposedPorts := make(nat.PortSet)
|
||||
@@ -513,12 +537,18 @@ func (c *Client) performBuild(
|
||||
}()
|
||||
|
||||
// Build image
|
||||
resp, err := c.docker.ImageBuild(ctx, tarArchive, dockertypes.ImageBuildOptions{
|
||||
buildOpts := dockertypes.ImageBuildOptions{
|
||||
Dockerfile: opts.DockerfilePath,
|
||||
Tags: opts.Tags,
|
||||
Remove: true,
|
||||
NoCache: false,
|
||||
})
|
||||
}
|
||||
|
||||
if len(opts.RegistryAuths) > 0 {
|
||||
buildOpts.AuthConfigs = buildAuthConfigs(opts.RegistryAuths)
|
||||
}
|
||||
|
||||
resp, err := c.docker.ImageBuild(ctx, tarArchive, buildOpts)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to build image: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user