v0.101.0: stacks with locally built images fail to deploy
### Description
Since v0.101.0, any stack that contains a locally built image fails to deploy. doco-cd tries to pull the image from a registry instead of building it, and the whole deployment aborts:
```
failed to deploy stack windmill: failed to deploy stack: failed to pull images:
Error response from daemon: pull access denied for windmill-infra-worker,
repository does not exist or may require 'docker login'
```
v0.100.0 and everything back to v0.95.0 works fine with the same config.
The cause looks like `internal/docker/compose.go`. Up to v0.100.0 the pull was guarded:
```go
if deployConfig.ForceImagePull {
for i, s := range project.Services {
s.PullPolicy = types.PullPolicyAlways
project.Services[i] = s
}
err = service.Pull(ctx, project, api.PullOptions{Quiet: true})
if err != nil {
return fmt.Errorf("failed to pull images: %w", err)
}
}
```
In v0.101.0 the same call runs unconditionally (around line 361):
```go
setDeploymentPhase(setPhase, "pulling images")
err = service.Pull(ctx, project, api.PullOptions{Quiet: true})
if err != nil {
return fmt.Errorf("failed to pull images: %w", err)
}
```
So with the default `force_image_pull: false` every service now gets pulled, including ones that only exist locally because they have a `build:` section.
`api.PullOptions` has an `IgnoreBuildable` field that skips services with a build section, which might be a smaller fix than putting the guard back.
Worth noting the failure is quiet in practice: running containers are untouched, only new deployments break. I only caught it because I watched the log during the upgrade.
### Steps to reproduce the issue
1. Stack with a service that has both `image:` and `build:`, using a tag that does not exist in any registry
2. Deploy it with doco-cd v0.100.0, image gets built, deployment succeeds
3. Upgrade doco-cd to v0.101.0 and trigger a deployment of the same stack
4. Deployment fails with `pull access denied`
No `force_image_pull` set anywhere, so it stays at the default `false`.
### Operating System
Debian GNU/Linux 13 (trixie), Docker 29.6.0
### Docker Compose File
Reduced to the relevant part:
```yaml
services:
infra-worker:
image: my-infra-worker:local
build:
context: ./infra-worker
restart: unless-stopped
```
### Deployment Config
```yaml
name: windmill
working_dir: windmill
reference: master
webhook_filter: '^refs/heads/master$'
auto_discovery:
enabled: true
depth: 1
delete: false
```
### Logs
v0.101.0:
```json
{"level":"info","msg":"deploying stack","deploy":{"recreate":{"forced_services":[],"mode":"diverged"},"reference":"master","stack":"windmill","stage":"deploy","target":"windmill"}}
{"level":"info","msg":"deployment in progress","deploy":{"phase":"pulling images","reference":"master","stack":"windmill","stage":"deploy","target":"windmill"}}
{"level":"error","msg":"deployment failed","deploy":{"error":"failed to deploy stack windmill: failed to deploy stack: failed to pull images: Error response from daemon: pull access denied for windmill-infra-worker, repository does not exist or may require 'docker login'","reference":"master","stack":"windmill","target":"windmill"}}
```
Same stack, same config, after downgrading to v0.100.0:
```json
{"level":"info","msg":"deploying stack","deploy":{"stack":"windmill","stage":"deploy","target":"windmill"}}
{"level":"info","msg":"job completed successfully","elapsed_time":"35.266s","target":"windmill"}
```
0 条评论