Golang Docker容器未在Docker-Compose中重新启动
I want to be able to restart a golang docker file on failure to connect to rabbitmq as outined here: (Docker Compose wait for container X before starting Y see answer by: svenhornberg). Unfortunately my golang container will exit but never restart and I don't know why.
Docker-compose:
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"
Docker file:
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" ]
Here is my golang code:
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)
<...>
And here is my terminal output (golang never restarts after rabbit called):
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...>
I'm very confused on how to get this to work. What am I doing wrong?
EDIT:
The exec.Command
was incorrectly implemented, however os.Exit(1)
, log.Fatal
, and log.Panic
exit the container, but the container does not restart. Still confused.
The Docker documentation says:
A restart policy only takes effect after a container starts successfully. In this case, starting successfully means that the container is up for at least 10 seconds and Docker has started monitoring it. This prevents a container which does not start at all from going into a restart loop.
Since the Go code you show exits basically immediately, it never meets this 10-second-minimum rule.
You can force Go to wait until the process has been alive a minimum of 10 seconds by using time.After somewhat like:
ch := time.After(10 * time.Second)
defer (func() { fmt.Println("waiting"); <-ch; fmt.Println("waited") })()
That is, create a channel that will receive an event after 10 seconds, and then actually receive it (immediately if it's happened, waiting if not) before main
returns. From playing with https://play.golang.org/p/zGY5jFWbXyk, the one trick is that there needs to be some observable effect after receiving from the channel or else it doesn't actually wait.