Deploy ihasmail's newest release, recorded by its dated tag

The ihasmail default was a pin that went stale within days, and ihasmail
keeps ten releases' images, so an old default would in time stop pulling.
With no --ihasmail-image the tool now pulls :latest before asking, reads the
version the image carries, confirms the dated tag is the same image, and
writes that tag into compose.yaml (or the digest, if there is no such tag).
Stalwart and Caddy stay pinned. A weekly end-to-end run against the newest
release, three hours after ihasmail publishes, is what keeps it safe.
This commit is contained in:
2026-09-15 12:00:20 -07:00
parent c151df45d0
commit 408fc20d7b
10 changed files with 276 additions and 18 deletions
+10 -2
View File
@@ -101,7 +101,7 @@ Flags:
fs.StringVar(&o.Dir, "dir", "", "deployment directory to write, new or empty (default ./PROJECT)")
fs.StringVar(&o.Project, "project", "", "compose project name (default ihasmail-DOMAIN, dots as dashes)")
fs.StringVar(&o.StalwartImage, "stalwart-image", config.DefaultStalwartImage, "Stalwart image")
fs.StringVar(&o.IhasmailImage, "ihasmail-image", config.DefaultIhasmailImage, "ihasmail image")
fs.StringVar(&o.IhasmailImage, "ihasmail-image", config.NewestIhasmail, "ihasmail image; the default is the newest release, written into compose.yaml as its dated tag")
fs.StringVar(&o.CaddyImage, "caddy-image", config.DefaultCaddyImage, "Caddy image")
fs.StringVar(&o.WebmailBind, "webmail-bind", "127.0.0.1:8080", "host address for ihasmail's own port")
fs.StringVar(&o.StalwartBind, "stalwart-bind", "127.0.0.1:8081", "host address for Stalwart's plain-HTTP port (admin UI)")
@@ -132,6 +132,10 @@ Flags:
for _, w := range warnings {
log.Warn("%s", w)
}
// Before the question, so the answer is about the exact ihasmail release.
if plan, err = deploy.ResolveIhasmail(ctx, plan, log); err != nil {
return err
}
if !yes {
if err := confirm("deploy this?"); err != nil {
return err
@@ -162,7 +166,11 @@ func describe(p config.Plan, log deploy.Log) {
log.Info("ACME Let's Encrypt, contact %s", p.Email)
}
}
log.Info("images %s, %s", p.StalwartImage, p.IhasmailImage)
if p.FollowsNewestIhasmail() {
log.Info("images %s, ihasmail's newest release", p.StalwartImage)
} else {
log.Info("images %s, %s", p.StalwartImage, p.IhasmailImage)
}
if !p.Local {
log.Info(" %s", p.CaddyImage)
}