diff --git a/Dockerfile b/Dockerfile index 475d58c..08b35c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,11 +20,12 @@ FROM alpine:3.17 WORKDIR /app -# Install runtime dependencies including docker cli +# Install runtime dependencies including docker and docker compose plugin RUN apk add --no-cache \ ca-certificates \ curl \ - docker-cli + docker-cli \ + docker-cli-compose # Copy the binary from the builder stage COPY --from=builder /app/app /app/app diff --git a/README.md b/README.md index 7051964..0db9614 100644 --- a/README.md +++ b/README.md @@ -26,15 +26,17 @@ The service can be deployed using Docker Compose. Below is an example configurat ```yaml services: sidecar: - image: ghcr.io/aurora-is-near/blockscout-vc:latest + command: + - sh + - -c + - /app/app sidecar --config /app/config/local.yaml container_name: sidecar - pull_policy: always - command: ["sh", "-c", "/app/app --config /app/config/local.yaml"] - volumes: - - ./config:/app/config - - /var/run/docker.sock:/var/run/docker.sock - - ./docker-compose.yaml:/app/config/docker-compose.yaml:ro + image: ghcr.io/aurora-is-near/blockscout-vc:latest restart: unless-stopped + volumes: + - ./config:/app/config + - /var/run/docker.sock:/var/run/docker.sock + - ./docker-compose.yaml:/app/config/docker-compose.yaml ``` ### Important Notes diff --git a/internal/docker/docker.go b/internal/docker/docker.go index 83ad9f8..dbe4a06 100644 --- a/internal/docker/docker.go +++ b/internal/docker/docker.go @@ -27,18 +27,37 @@ func (d *Docker) RecreateContainers(containerNames []string) error { pathToDockerCompose := viper.GetString("pathToDockerCompose") uniqueContainers := d.UniqueContainerNames(containerNames) - args := []string{"compose", "-f", pathToDockerCompose, "up", "-d", "--force-recreate"} - args = append(args, uniqueContainers...) + // Define the sequence of commands to execute + commands := []struct { + args []string + desc string + errMessage string + }{ + { + args: []string{"rm", "-f"}, + desc: "Stopping and removing containers", + errMessage: "Error stopping and removing containers", + }, + { + args: []string{"compose", "-f", pathToDockerCompose, "up", "-d", "--force-recreate"}, + desc: "Recreating containers", + errMessage: "Error recreating containers", + }, + } - cmd := exec.Command("docker", args...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr + // Execute each command in sequence + for _, cmd := range commands { + args := append(cmd.args, uniqueContainers...) - fmt.Printf("Running docker-compose up -d --force-recreate %v\n", containerNames) + execCmd := exec.Command("docker", args...) + execCmd.Stdout = os.Stdout + execCmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - fmt.Printf("Error: %v\n", err) - return err + fmt.Printf("%s: %s\n", cmd.desc, execCmd.String()) + if err := execCmd.Run(); err != nil { + fmt.Printf("%s: %v\n", cmd.errMessage, err) + return err + } } fmt.Println("Docker containers recreated successfully!") diff --git a/internal/worker/worker.go b/internal/worker/worker.go index a205179..05dd8b1 100644 --- a/internal/worker/worker.go +++ b/internal/worker/worker.go @@ -68,15 +68,22 @@ func (w *Worker) process(ctx context.Context) { case <-ctx.Done(): return case job := <-w.jobs: - err := w.docker.RecreateContainers(job.ContainerNames) - if err != nil { - log.Printf("failed to recreate containers: %v", err) - continue - } + jobKey := w.makeKey(job.ContainerNames) + // Using an immediately invoked function to ensure defer runs after each job + // Without this, defer would only run when the process function returns + func() { + defer func() { + w.jobSetMux.Lock() + delete(w.jobSet, jobKey) + w.jobSetMux.Unlock() + }() - w.jobSetMux.Lock() - delete(w.jobSet, w.makeKey(job.ContainerNames)) - w.jobSetMux.Unlock() + err := w.docker.RecreateContainers(job.ContainerNames) + if err != nil { + log.Printf("failed to recreate containers: %v", err) + return + } + }() } } }