diff --git a/local/compose.go b/local/compose.go
index f32f16e79..232a8f4b6 100644
--- a/local/compose.go
+++ b/local/compose.go
@@ -79,8 +79,8 @@ func (s *local) Up(ctx context.Context, project *types.Project, detach bool) err
 		}
 	}
 
-	err := inDependencyOrder(ctx, project, func(service types.ServiceConfig) error {
-		return s.ensureService(ctx, project, service)
+	err := inDependencyOrder(ctx, project, func(c context.Context, service types.ServiceConfig) error {
+		return s.ensureService(c, project, service)
 	})
 	return err
 }
@@ -415,10 +415,10 @@ func getContainerCreateOptions(p *types.Project, s types.ServiceConfig, number i
 		MacAddress:      s.MacAddress,
 		Labels:          labels,
 		StopSignal:      s.StopSignal,
-		//		Env:             s.Environment, FIXME conversion
-		//		Healthcheck:     s.HealthCheck, FIXME conversion
+		Env:             toMobyEnv(s.Environment),
+		Healthcheck:     toMobyHealthCheck(s.HealthCheck),
 		// Volumes:         // FIXME unclear to me the overlap with HostConfig.Mounts
-		// StopTimeout: 	 s.StopGracePeriod FIXME conversion
+		StopTimeout: toSeconds(s.StopGracePeriod),
 	}
 
 	mountOptions := buildContainerMountOptions(p, s, inherit)
diff --git a/local/convergence.go b/local/convergence.go
index 86984a40b..72689d77c 100644
--- a/local/convergence.go
+++ b/local/convergence.go
@@ -22,6 +22,7 @@ import (
 	"context"
 	"fmt"
 	"strconv"
+	"time"
 
 	"github.com/compose-spec/compose-go/types"
 	moby "github.com/docker/docker/api/types"
@@ -33,7 +34,17 @@ import (
 	"github.com/docker/compose-cli/progress"
 )
 
+const (
+	extLifecycle  = "x-lifecycle"
+	forceRecreate = "force_recreate"
+)
+
 func (s *local) ensureService(ctx context.Context, project *types.Project, service types.ServiceConfig) error {
+	err := s.waitDependencies(ctx, project, service)
+	if err != nil {
+		return err
+	}
+
 	actual, err := s.containerService.apiClient.ContainerList(ctx, moby.ContainerListOptions{
 		Filters: filters.NewArgs(
 			filters.Arg("label", fmt.Sprintf("%s=%s", projectLabel, project.Name)),
@@ -80,10 +91,11 @@ func (s *local) ensureService(ctx context.Context, project *types.Project, servi
 	if err != nil {
 		return err
 	}
+
 	for _, container := range actual {
 		container := container
 		diverged := container.Labels[configHashLabel] != expected
-		if diverged {
+		if diverged || service.Extensions[extLifecycle] == forceRecreate {
 			eg.Go(func() error {
 				return s.recreateContainer(ctx, project, service, container)
 			})
@@ -102,6 +114,30 @@ func (s *local) ensureService(ctx context.Context, project *types.Project, servi
 	return eg.Wait()
 }
 
+func (s *local) waitDependencies(ctx context.Context, project *types.Project, service types.ServiceConfig) error {
+	eg, ctx := errgroup.WithContext(ctx)
+	for dep, config := range service.DependsOn {
+		switch config.Condition {
+		case "service_healthy":
+			eg.Go(func() error {
+				ticker := time.NewTicker(500 * time.Millisecond)
+				defer ticker.Stop()
+				for {
+					<-ticker.C
+					healthy, err := s.isServiceHealthy(ctx, project, dep)
+					if err != nil {
+						return err
+					}
+					if healthy {
+						return nil
+					}
+				}
+			})
+		}
+	}
+	return eg.Wait()
+}
+
 func nextContainerNumber(containers []moby.Container) (int, error) {
 	max := 0
 	for _, c := range containers {
@@ -184,9 +220,23 @@ func (s *local) recreateContainer(ctx context.Context, project *types.Project, s
 		StatusText: "Recreated",
 		Done:       true,
 	})
+	setDependentLifecycle(project, service.Name, forceRecreate)
 	return nil
 }
 
+// setDependentLifecycle define the Lifecycle strategy for all services to depend on specified service
+func setDependentLifecycle(project *types.Project, service string, strategy string) {
+	for i, s := range project.Services {
+		if contains(s.GetDependencies(), service) {
+			if s.Extensions == nil {
+				s.Extensions = map[string]interface{}{}
+			}
+			s.Extensions[extLifecycle] = strategy
+			project.Services[i] = s
+		}
+	}
+}
+
 func (s *local) restartContainer(ctx context.Context, service types.ServiceConfig, container moby.Container) error {
 	w := progress.ContextWriter(ctx)
 	w.Event(progress.Event{
@@ -240,3 +290,33 @@ func (s *local) connectContainerToNetwork(ctx context.Context, id string, servic
 	}
 	return nil
 }
+
+func (s *local) isServiceHealthy(ctx context.Context, project *types.Project, service string) (bool, error) {
+	containers, err := s.containerService.apiClient.ContainerList(ctx, moby.ContainerListOptions{
+		Filters: filters.NewArgs(
+			filters.Arg("label", fmt.Sprintf("%s=%s", projectLabel, project.Name)),
+			filters.Arg("label", fmt.Sprintf("%s=%s", serviceLabel, service)),
+		),
+	})
+	if err != nil {
+		return false, err
+	}
+
+	for _, c := range containers {
+		container, err := s.containerService.apiClient.ContainerInspect(ctx, c.ID)
+		if err != nil {
+			return false, err
+		}
+		if container.State == nil || container.State.Health == nil {
+			return false, fmt.Errorf("container for service %q has no healthcheck configured", service)
+		}
+		switch container.State.Health.Status {
+		case "starting":
+			return false, nil
+		case "unhealthy":
+			return false, nil
+		}
+	}
+	return true, nil
+
+}
diff --git a/local/convert.go b/local/convert.go
index 05931a366..f0b834a7b 100644
--- a/local/convert.go
+++ b/local/convert.go
@@ -23,7 +23,9 @@ import (
 	"sort"
 	"strconv"
 	"strings"
+	"time"
 
+	compose "github.com/compose-spec/compose-go/types"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/go-connections/nat"
@@ -93,6 +95,57 @@ func toPorts(ports []types.Port) []containers.Port {
 	return result
 }
 
+func toMobyEnv(environment compose.MappingWithEquals) []string {
+	var env []string
+	for k, v := range environment {
+		if v == nil {
+			env = append(env, k)
+		} else {
+			env = append(env, fmt.Sprintf("%s=%s", k, *v))
+		}
+	}
+	return env
+}
+
+func toMobyHealthCheck(check *compose.HealthCheckConfig) *container.HealthConfig {
+	if check == nil {
+		return nil
+	}
+	var (
+		interval time.Duration
+		timeout  time.Duration
+		period   time.Duration
+		retries  int
+	)
+	if check.Interval != nil {
+		interval = time.Duration(*check.Interval)
+	}
+	if check.Timeout != nil {
+		timeout = time.Duration(*check.Timeout)
+	}
+	if check.StartPeriod != nil {
+		period = time.Duration(*check.StartPeriod)
+	}
+	if check.Retries != nil {
+		retries = int(*check.Retries)
+	}
+	return &container.HealthConfig{
+		Test:        check.Test,
+		Interval:    interval,
+		Timeout:     timeout,
+		StartPeriod: period,
+		Retries:     retries,
+	}
+}
+
+func toSeconds(d *compose.Duration) *int {
+	if d == nil {
+		return nil
+	}
+	s := int(time.Duration(*d).Seconds())
+	return &s
+}
+
 func fromPorts(ports []containers.Port) (map[nat.Port]struct{}, map[nat.Port][]nat.PortBinding, error) {
 	var (
 		exposedPorts = make(map[nat.Port]struct{}, len(ports))
diff --git a/local/dependencies.go b/local/dependencies.go
index 50d7a4c47..e5ac9a77d 100644
--- a/local/dependencies.go
+++ b/local/dependencies.go
@@ -25,37 +25,89 @@ import (
 	"golang.org/x/sync/errgroup"
 )
 
-func inDependencyOrder(ctx context.Context, project *types.Project, fn func(types.ServiceConfig) error) error {
-	eg, _ := errgroup.WithContext(ctx)
-	var (
-		scheduled []string
-		ready     []string
-	)
+func inDependencyOrder(ctx context.Context, project *types.Project, fn func(context.Context, types.ServiceConfig) error) error {
+	graph := buildDependencyGraph(project.Services)
+
+	eg, ctx := errgroup.WithContext(ctx)
 	results := make(chan string)
-	for len(ready) < len(project.Services) {
-		for _, service := range project.Services {
-			if contains(scheduled, service.Name) {
-				continue
-			}
-			if containsAll(ready, service.GetDependencies()) {
-				service := service
-				scheduled = append(scheduled, service.Name)
-				eg.Go(func() error {
-					err := fn(service)
-					if err != nil {
-						close(results)
-						return err
-					}
-					results <- service.Name
-					return nil
-				})
-			}
+	errors := make(chan error)
+	for len(graph) > 0 {
+		for _, n := range graph.independents() {
+			service := n.service
+			eg.Go(func() error {
+				err := fn(ctx, service)
+				if err != nil {
+					errors <- err
+					return err
+				}
+				results <- service.Name
+				return nil
+			})
 		}
-		result, ok := <-results
-		if !ok {
-			break
+		select {
+		case result := <-results:
+			graph.resolved(result)
+		case err := <-errors:
+			return err
 		}
-		ready = append(ready, result)
 	}
 	return eg.Wait()
 }
+
+type dependencyGraph map[string]node
+
+type node struct {
+	service      types.ServiceConfig
+	dependencies []string
+	dependent    []string
+}
+
+func (graph dependencyGraph) independents() []node {
+	var nodes []node
+	for _, node := range graph {
+		if len(node.dependencies) == 0 {
+			nodes = append(nodes, node)
+		}
+	}
+	return nodes
+}
+
+func (graph dependencyGraph) resolved(result string) {
+	for _, parent := range graph[result].dependent {
+		node := graph[parent]
+		node.dependencies = remove(node.dependencies, result)
+		graph[parent] = node
+	}
+	delete(graph, result)
+}
+
+func buildDependencyGraph(services types.Services) dependencyGraph {
+	graph := dependencyGraph{}
+	for _, s := range services {
+		graph[s.Name] = node{
+			service: s,
+		}
+	}
+
+	for _, s := range services {
+		node := graph[s.Name]
+		for _, name := range s.GetDependencies() {
+			dependency := graph[name]
+			node.dependencies = append(node.dependencies, name)
+			dependency.dependent = append(dependency.dependent, s.Name)
+			graph[name] = dependency
+		}
+		graph[s.Name] = node
+	}
+	return graph
+}
+
+func remove(slice []string, item string) []string {
+	var s []string
+	for _, i := range slice {
+		if i != item {
+			s = append(s, i)
+		}
+	}
+	return s
+}
diff --git a/local/dependencies_test.go b/local/dependencies_test.go
index b0b6cfe37..3dc62f693 100644
--- a/local/dependencies_test.go
+++ b/local/dependencies_test.go
@@ -49,7 +49,7 @@ func TestInDependencyOrder(t *testing.T) {
 		},
 	}
 	//nolint:errcheck, unparam
-	go inDependencyOrder(context.TODO(), &project, func(config types.ServiceConfig) error {
+	go inDependencyOrder(context.TODO(), &project, func(ctx context.Context, config types.ServiceConfig) error {
 		order <- config.Name
 		return nil
 	})
diff --git a/local/util.go b/local/util.go
index adc1b2e2c..c49af75dd 100644
--- a/local/util.go
+++ b/local/util.go
@@ -40,12 +40,3 @@ func contains(slice []string, item string) bool {
 	}
 	return false
 }
-
-func containsAll(slice []string, items []string) bool {
-	for _, i := range items {
-		if !contains(slice, i) {
-			return false
-		}
-	}
-	return true
-}