WriteDockerComposeYAML writes a .ddev-docker-compose-base.yaml and related to the .ddev directory. It then uses `docker-compose convert` to get a canonical version of the full compose file. It then makes a couple of fixups to the canonical version (networks and approot bind points) by marshaling the
()
| 21 | // It then makes a couple of fixups to the canonical version (networks and approot bind points) by |
| 22 | // marshaling the canonical version to YAML and then unmarshaling it back into a canonical version. |
| 23 | func (app *DdevApp) WriteDockerComposeYAML() error { |
| 24 | var err error |
| 25 | |
| 26 | // Create a host working_dir for the web service beforehand. |
| 27 | // Otherwise, Docker will create it as root user (when Mutagen is disabled). |
| 28 | // This problem (particularly for Docker volumes) is described in |
| 29 | // https://github.com/moby/moby/issues/2259 |
| 30 | hostWorkingDir := app.GetHostWorkingDir("web", "") |
| 31 | if hostWorkingDir != "" { |
| 32 | _ = os.MkdirAll(hostWorkingDir, 0755) |
| 33 | } |
| 34 | |
| 35 | rendered, err := app.RenderComposeYAML() |
| 36 | if err != nil { |
| 37 | return err |
| 38 | } |
| 39 | |
| 40 | baseYAMLPath := app.DockerComposeYAMLPath() |
| 41 | baseContentBytes := []byte(rendered) |
| 42 | |
| 43 | // If the file already exists and has the same content, don't overwrite it. |
| 44 | skipBaseWrite := false |
| 45 | if existingContent, err := os.ReadFile(baseYAMLPath); err == nil { |
| 46 | if bytes.Equal(baseContentBytes, existingContent) { |
| 47 | skipBaseWrite = true |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | if !skipBaseWrite { |
| 52 | f, err := os.Create(baseYAMLPath) |
| 53 | if err != nil { |
| 54 | return err |
| 55 | } |
| 56 | defer util.CheckClose(f) |
| 57 | |
| 58 | _, err = f.Write(baseContentBytes) |
| 59 | if err != nil { |
| 60 | return err |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | files, err := app.ComposeFiles() |
| 65 | if err != nil { |
| 66 | return err |
| 67 | } |
| 68 | envFiles, err := app.EnvFiles() |
| 69 | if err != nil { |
| 70 | return err |
| 71 | } |
| 72 | var action []string |
| 73 | for _, envFile := range envFiles { |
| 74 | action = append(action, "--env-file", envFile) |
| 75 | } |
| 76 | fullContents, _, err := dockerutil.ComposeCmd(&dockerutil.ComposeCmdOpts{ |
| 77 | ComposeFiles: files, |
| 78 | Profiles: []string{`*`}, |
| 79 | Action: append(action, "config"), |
| 80 | }) |