diff --git a/pkg/deployment/container.go b/pkg/deployment/container.go index 376f1ef..678e741 100644 --- a/pkg/deployment/container.go +++ b/pkg/deployment/container.go @@ -127,19 +127,19 @@ func (d *Deployment) performHealthChecks(container string, healthCheck *config.H return fmt.Errorf("container failed to become healthy\n\x1b[93mOutput from the container:\x1b[0m\n%s", grayOutput) } -func (d *Deployment) startContainer(service *config.Service) error { - _, err := d.runCommand(context.Background(), "docker", "start", service.Name) +func (d *Deployment) startContainer(container string) error { + _, err := d.runCommand(context.Background(), "docker", "start", container) if err != nil { - return fmt.Errorf("failed to start container for %s: %v", service.Name, err) + return fmt.Errorf("failed to start container for %s: %v", container, err) } return nil } func (d *Deployment) createContainer(project string, service *config.Service, suffix string) error { - svcName := service.Name + container := containerName(project, service.Name, suffix) - args := []string{"run", "-d", "--name", svcName + suffix, "--network", project, "--network-alias", svcName + suffix, "--restart", "unless-stopped"} + args := []string{"run", "-d", "--name", container, "--network", project, "--network-alias", service.Name + suffix, "--restart", "unless-stopped"} for _, value := range service.Env { args = append(args, "-e", value) @@ -219,3 +219,7 @@ func (d *Deployment) containerShouldBeUpdated(project string, service *config.Se return containerInfo.Config.Labels["ftl.config-hash"] != hash, nil } + +func containerName(project, service, suffix string) string { + return fmt.Sprintf("%s-%s%s", project, service, suffix) +} diff --git a/pkg/deployment/deployment_test.go b/pkg/deployment/deployment_test.go index 3c9e64d..0e095de 100644 --- a/pkg/deployment/deployment_test.go +++ b/pkg/deployment/deployment_test.go @@ -215,10 +215,11 @@ func (suite *DeploymentTestSuite) TestDeploy() { fmt.Printf("Total requests: %d\n", requestStats.totalRequests) fmt.Printf("Failed requests: %d\n", requestStats.failedRequests) - serviceName := "web" suite.Require().Equal(int32(0), requestStats.failedRequests, "Expected zero failed requests during zero-downtime deployment") - containerInfo := suite.inspectContainer(serviceName) + serviceName := "web" + containerName := containerName(project, serviceName, "") + containerInfo := suite.inspectContainer(containerName) suite.Run("Updated Container State and Config", func() { state := containerInfo["State"].(map[string]interface{}) diff --git a/pkg/deployment/service.go b/pkg/deployment/service.go index 25240ed..32cb909 100644 --- a/pkg/deployment/service.go +++ b/pkg/deployment/service.go @@ -77,7 +77,8 @@ func (d *Deployment) deployService(project string, service *config.Service) erro } if containerStatus == ContainerStatusStopped { - if err := d.startContainer(service); err != nil { + container := containerName(project, service.Name, "") + if err := d.startContainer(container); err != nil { return fmt.Errorf("failed to start container %s: %w", service.Name, err) } return nil @@ -91,17 +92,17 @@ func (d *Deployment) installService(project string, service *config.Service) err return fmt.Errorf("failed to start container for %s: %v", service.Image, err) } - svcName := service.Name + container := containerName(project, service.Name, "") - if err := d.performHealthChecks(svcName, service.HealthCheck); err != nil { - return fmt.Errorf("install failed for %s: container is unhealthy: %w", svcName, err) + if err := d.performHealthChecks(container, service.HealthCheck); err != nil { + return fmt.Errorf("install failed for %s: container is unhealthy: %w", container, err) } return nil } func (d *Deployment) updateService(project string, service *config.Service) error { - svcName := service.Name + container := containerName(project, service.Name, "") if service.Recreate { if err := d.recreateService(project, service); err != nil { @@ -111,23 +112,23 @@ func (d *Deployment) updateService(project string, service *config.Service) erro } if err := d.createContainer(project, service, newContainerSuffix); err != nil { - return fmt.Errorf("failed to start new container for %s: %v", svcName, err) + return fmt.Errorf("failed to start new container for %s: %v", container, err) } - if err := d.performHealthChecks(svcName+newContainerSuffix, service.HealthCheck); err != nil { - if _, err := d.runCommand(context.Background(), "docker", "rm", "-f", svcName+newContainerSuffix); err != nil { - return fmt.Errorf("update failed for %s: new container is unhealthy and cleanup failed: %v", svcName, err) + if err := d.performHealthChecks(container+newContainerSuffix, service.HealthCheck); err != nil { + if _, err := d.runCommand(context.Background(), "docker", "rm", "-f", container+newContainerSuffix); err != nil { + return fmt.Errorf("update failed for %s: new container is unhealthy and cleanup failed: %v", container, err) } - return fmt.Errorf("update failed for %s: new container is unhealthy: %w", svcName, err) + return fmt.Errorf("update failed for %s: new container is unhealthy: %w", container, err) } - oldContID, err := d.switchTraffic(project, svcName) + oldContID, err := d.switchTraffic(project, service.Name) if err != nil { - return fmt.Errorf("failed to switch traffic for %s: %v", svcName, err) + return fmt.Errorf("failed to switch traffic for %s: %v", container, err) } - if err := d.cleanup(oldContID, svcName); err != nil { - return fmt.Errorf("failed to cleanup for %s: %v", svcName, err) + if err := d.cleanup(project, oldContID, service.Name); err != nil { + return fmt.Errorf("failed to cleanup for %s: %v", container, err) } return nil @@ -162,7 +163,7 @@ func (d *Deployment) recreateService(project string, service *config.Service) er } func (d *Deployment) switchTraffic(project, service string) (string, error) { - newContainer := service + newContainerSuffix + newContainer := containerName(project, service, newContainerSuffix) oldContainer, err := d.getContainerID(project, service) if err != nil { return "", fmt.Errorf("failed to get old container ID: %v", err) @@ -194,11 +195,13 @@ func (d *Deployment) switchTraffic(project, service string) (string, error) { return oldContainer, nil } -func (d *Deployment) cleanup(oldContID, service string) error { +func (d *Deployment) cleanup(project, oldContID, service string) error { + oldContainer := containerName(project, service, newContainerSuffix) + newContainer := containerName(project, service, "") cmds := [][]string{ {"docker", "stop", oldContID}, {"docker", "rm", oldContID}, - {"docker", "rename", service + newContainerSuffix, service}, + {"docker", "rename", oldContainer, newContainer}, } for _, cmd := range cmds {