Skip to content

Lifecycle hook doesn't execute when callilng service.Up in the API #12513

@chris-gputrader

Description

@chris-gputrader

I've been pounding my head against this and am not sure if I'm not doing something incorrect or if its the codebase but lifecycle hooks don't seem to get executed when calling the API directly. I have the following example code to test this.

package main

import (
	"context"
	"flag"
	"log"
	"os"
	"time"

	"github.com/compose-spec/compose-go/v2/loader"
	"github.com/compose-spec/compose-go/v2/types"
	"github.com/docker/cli/cli/command"
	"github.com/docker/cli/cli/flags"
	"github.com/docker/compose/v2/pkg/api"
	"github.com/docker/compose/v2/pkg/compose"
)

func main() {
	// Add command line flag for config file
	configFile := flag.String("config", "compose.yaml", "Path to compose config file (yaml or json)")
	flag.Parse()

	// Read the configuration file
	bytes, err := os.ReadFile(*configFile)
	if err != nil {
		log.Fatalf("Failed to read config file: %v", err)
	}

	// Setup Docker client config
	dockerCli, err := command.NewDockerCli()
	if err != nil {
		log.Fatalf("Failed to create docker cli: %v", err)
	}

	opts := flags.NewClientOptions()
	if err := dockerCli.Initialize(opts); err != nil {
		log.Fatalf("Failed to initialize docker cli: %v", err)
	}

	// Create compose service
	service := compose.NewComposeService(dockerCli)

	// Load the project from config
	project, err := loader.Load(types.ConfigDetails{
		ConfigFiles: []types.ConfigFile{
			{
				Content: bytes,
			},
		},
		Environment: types.NewMapping(os.Environ()),
	})
	if err != nil {
		log.Fatalf("Failed to load project: %v", err)
	}

	// Setup options
	options := api.UpOptions{
		Create: api.CreateOptions{
			RemoveOrphans: true,
		},
		Start: api.StartOptions{
			Wait: true,
		},
	}

	// Create context with timeout
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
	defer cancel()

	// Pull the images
	if err := service.Pull(ctx, project, api.PullOptions{}); err != nil {
		log.Fatalf("Failed to pull images: %v", err)
	}

	//log the project object
	log.Printf("Project: %v\n", project)

	// Start the project
	if err := service.Up(ctx, project, options); err != nil {
		log.Fatalf("Failed to start project: %v", err)
	}

	log.Println("Services started successfully!")
}

Here is a simple compose.yml to test with:

services:
  alpine:
    image: alpine
    command: sleep 1000000
    post_start:
      - command: /bin/sh -c "echo somecontent > /root/file.txt"      
        privileged: true

The container gets created but the post_start hook never runs.

Any ideas or am I just calling this wrong?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions