fix: ensure compose projects are spawned from the /tmp directory

A recent update to compose executes a stat call in the current working directory, which may have incorrect permissions for execution once the user is changed to the dokku user. This change forces all compose commands to execute in the /tmp directory by using a helper function to execute compose up/down.

Closes #7705
This commit is contained in:
Jose Diaz-Gonzalez
2025-05-24 23:31:34 -04:00
parent 41ac56e54b
commit 6ce10b5be6
8 changed files with 108 additions and 39 deletions

View File

@@ -11,6 +11,63 @@ import (
"time"
)
// ComposeUpInput is the input for the ComposeUp function
type ComposeUpInput struct {
ProjectName string
ComposeFile string
}
// ComposeUp executes a docker compose up command
func ComposeUp(input ComposeUpInput) error {
result, err := CallExecCommand(ExecCommandInput{
Command: DockerBin(),
Args: []string{
"compose",
"--file", input.ComposeFile,
"--project-name", input.ProjectName,
"up",
"--detach",
"--quiet-pull",
},
StreamStdio: true,
WorkingDirectory: "/tmp",
})
if err != nil || result.ExitCode != 0 {
return fmt.Errorf("Unable to start compose project: %s", result.Stderr)
}
return nil
}
// ComposeDownInput is the input for the ComposeDown function
type ComposeDownInput struct {
ProjectName string
ComposeFile string
}
// ComposeDown executes a docker compose down command
func ComposeDown(input ComposeDownInput) error {
result, err := CallExecCommand(ExecCommandInput{
Command: DockerBin(),
Args: []string{
"compose",
"--file", input.ComposeFile,
"--project-name", input.ProjectName,
"down",
"--remove-orphans",
},
StreamStdio: true,
WorkingDirectory: "/tmp",
})
if err != nil || result.ExitCode != 0 {
return fmt.Errorf("Unable to stop %s: %s", input.ProjectName, result.Stderr)
}
return nil
}
// ContainerIsRunning checks to see if a container is running
func ContainerIsRunning(containerID string) bool {
b, err := DockerInspect(containerID, "'{{.State.Running}}'")

View File

@@ -50,6 +50,9 @@ type ExecCommandInput struct {
// Sudo runs the command with sudo -n -u root
Sudo bool
// WorkingDirectory is the working directory to run the command in
WorkingDirectory string
}
// ExecCommandResponse is the response for the ExecCommand function
@@ -134,6 +137,10 @@ func CallExecCommandWithContext(ctx context.Context, input ExecCommandInput) (Ex
DisableStdioBuffer: input.DisableStdioBuffer,
}
if input.WorkingDirectory != "" {
cmd.Cwd = input.WorkingDirectory
}
if os.Getenv("DOKKU_TRACE") == "1" {
argsSt := ""
if len(cmd.Args) > 0 {

View File

@@ -20,6 +20,20 @@ func main() {
var err error
switch cmd {
case "compose-up":
projectName := flag.Arg(1)
composeFile := flag.Arg(2)
err = common.ComposeUp(common.ComposeUpInput{
ProjectName: projectName,
ComposeFile: composeFile,
})
case "compose-down":
projectName := flag.Arg(1)
composeFile := flag.Arg(2)
err = common.ComposeDown(common.ComposeDownInput{
ProjectName: projectName,
ComposeFile: composeFile,
})
case "copy-from-image":
appName := flag.Arg(1)
image := flag.Arg(2)