Billionmail/BillionMail · error
failed to update docker-compose.yml: %v
Error message
failed to update docker-compose.yml: %v
What it means
applyConfigs is step 1 of ApplyConfigsWithRollback: update the docker-compose topology by generating docker-compose_addnetwork.yml. If updateDockerCompose fails for any reason (dir creation, docker exec, read/modify/write), the error is wrapped with this prefix and triggers rollback of the Postfix configs. It is a wrapper — the root cause is inside updateDockerCompose.
Source
Thrown at core/internal/service/multi_ip_domain/config_manager.go:144
return nil
}
// cleanupBackups Clean up backup files
func (m *ConfigManager) cleanupBackups(ctx context.Context, backups map[string]string) {
for _, backup := range backups {
if gfile.Exists(backup) {
g.Log().Debugf(ctx, "Cleaning up backup file: %s", backup)
_ = os.Remove(backup)
}
}
}
// applyConfigs Apply configurations
func (m *ConfigManager) applyConfigs(ctx context.Context, configs []map[string]interface{}) error {
// 1. Update docker-compose.yml
if err := m.updateDockerCompose(ctx, configs); err != nil {
return fmt.Errorf("failed to update docker-compose.yml: %v", err)
}
// 2. Update Postfix configurations
if err := m.updatePostfixConfigs(ctx, configs); err != nil {
return fmt.Errorf("failed to update Postfix configurations: %v", err)
}
return nil
}
// updateDockerCompose Generate docker-compose_addnetwork.yml
func (m *ConfigManager) updateDockerCompose(ctx context.Context, configs []map[string]interface{}) error {
originalPath := filepath.Join(public.HostWorkDir, "docker-compose.yml")
outputPath := filepath.Join(public.HostWorkDir, "docker-compose_addnetwork.yml")
// 设置临时文件路径
// 容器内路径:/opt/billionmail/core/data (通过 public.AbsPath 获取)
// 宿主机路径:./core-data (相对于 docker-compose.yml 所在目录)View on GitHub (pinned to fc36c76c05)
Solutions
- Unwrap the inner error to find the failing step (temp dir, copy, read, modify, or output copy).
- Verify docker-compose.yml exists at HostWorkDir and the core-data host volume is mounted and writable.
- Confirm the container can run chroot /host_root commands and the Docker API is reachable (docker ps from inside).
- After fixing, re-run ApplyConfigsWithRollback; it already restored Postfix configs via rollback, so retry is safe.
Defensive patterns
Strategy: validation
Validate before calling
// preflight before apply
if _, err := os.Stat(filepath.Join(public.HostWorkDir, "docker-compose.yml")); err != nil {
return fmt.Errorf("docker-compose.yml missing: %v", err)
}
if _, err := os.Stat(filepath.Join(public.HostWorkDir, "core-data")); err != nil {
return fmt.Errorf("core-data volume not mounted: %v", err)
} Try / catch
if err := mgr.ApplyConfigsWithRollback(ctx, configs); err != nil {
if strings.Contains(err.Error(), "failed to update docker-compose.yml") {
// inner cause is in the wrapped text; check docker socket, chroot, mounts
}
} Prevention
- Verify /host_root chroot and Docker API access from the container at startup.
- Keep docker-compose.yml at the expected HostWorkDir path.
- Ensure the core-data bind mount matches AbsPath('../core/data').
- Health-check docker exec capability before config applies.
When it happens
Trigger: Any updateDockerCompose failure: cannot create the temp data dir, chroot cp of docker-compose.yml fails, temp file empty, content modification error, or copy of the output file back to the host fails.
Common situations: Missing /host_root chroot capability or docker API socket inaccessible; docker-compose.yml not at public.HostWorkDir; core-data volume not mounted so the container↔host temp path mapping is broken; malformed compose content.
Related errors
- failed to update Postfix configurations: %v
- Not suppliers found
- Model not found
- failed to query group: %w
- failed to check unsubscribe: %w
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/2a969027348752c7.
Report an issue: GitHub.