Golang Docker 容器未在 Docker-Compose 中重新启动

Pet*_*and 1 restart go rabbitmq docker docker-compose

我希望能够在无法连接到 rabbitmq 时重新启动 golang docker 文件,如下所述:(Docker Compose 在启动 Y 之前等待容器 X,请参阅:svenhornberg 的回答)。不幸的是,我的 golang 容器将退出但永远不会重新启动,我不知道为什么。

Docker-撰写:

version: '3.3'
services:
  mongo:
    image: 'mongo:3.4.1'
    container_name: 'datastore'
    ports:
      - '27017:27017'
  rabbitmq:
    restart: always
    tty: true
    image: rabbitmq:3.7-management-alpine
    hostname: "rabbit"
    ports:
      - "15672:15672" 
      - "5672:5672"
    labels:
      NAME: "rabbitmq"
    volumes:
      - ./rabbitmq-isolated.conf:/etc/rabbitmq/rabbitmq.config
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:15672"]
      interval: 3s
      timeout: 5s
      retries: 20
  api:
    restart: always
    tty: true
    container_name: 'api'
    build: '.'
    working_dir: /go/src/github.com/patientplatypus/project
    ports:
      - '8000:8000'
    volumes:
      - './:/go/src/github.com/patientplatypus/project'
      - './uploads:/uploads'
      - './scripts:/scripts'
      - './templates:/templates'
    depends_on:
      - "mongo"
      - "rabbitmq"
Run Code Online (Sandbox Code Playgroud)

码头工人文件:

FROM golang:latest

WORKDIR /go/src/github.com/patientplatypus/project
COPY . .

RUN go get github.com/imroc/req
<...more go gets...>
RUN go get github.com/joho/godotenv

EXPOSE 8000

ENTRYPOINT  [ "fresh" ]
Run Code Online (Sandbox Code Playgroud)

这是我的 golang 代码:

package main

import (
    "fmt"
    "log"
    "os"
    "os/exec"
    "net/http"
)

func main() {

    fmt.Println("Golang server started")
    godotenv.Load()
    fmt.Println("now doing healthcheck on rabbit")
    exec.Command("docker-compose restart api")
    os.Exit(1)
  <...>
Run Code Online (Sandbox Code Playgroud)

这是我的终端输出(golang 在rabbit 调用后永远不会重新启动):

api         | 23:23:00 app         | Golang server started
api         | 23:23:00 app         | now doing healthcheck on rabbit
rabbitmq_1  | 
rabbitmq_1  |   ##  ##
rabbitmq_1  |   ##  ##      RabbitMQ 3.7.11. Copyright (C) 2007-2019 Pivotal Software, Inc.
rabbitmq_1  |   ##########  Licensed under the MPL.  See http://www.rabbitmq.com/
rabbitmq_1  |   ######  ##
rabbitmq_1  |   ##########  Logs: <stdout>
<...more rabbit logging...>
Run Code Online (Sandbox Code Playgroud)

我对如何让它发挥作用感到非常困惑。我究竟做错了什么?

编辑:

exec.Command被错误地执行,但是os.Exit(1)log.Fatallog.Panic退出容器,但容器不会重新启动。还是一头雾水。

Dav*_*aze 5

Docker 文档说:

重启策略只有在容器启动成功后才会生效。在这种情况下,成功启动意味着容器至少启动了 10 秒,并且 Docker 已经开始监控它。这可以防止根本没有启动的容器进入重启循环。

由于您显示的 Go 代码基本上立即退出,因此它永远不会满足这个最少 10 秒的规则。

您可以使用time.After强制 Go 等待进程至少存活 10 秒,类似于:

ch := time.After(10 * time.Second)
defer (func() { fmt.Println("waiting"); <-ch; fmt.Println("waited") })()
Run Code Online (Sandbox Code Playgroud)

也就是说,创建一个将在 10 秒后接收事件的通道,然后在main返回之前实际接收它(如果发生则立即接收,否则等待)。从玩https://play.golang.org/p/zGY5jFWbXyk 开始,一个技巧是从频道接收后需要有一些可观察的效果,否则它实际上不会等待。