Notifiarr / notifiarr

Client for Notifiarr.com
https://notifiarr.com
MIT License
508 stars 30 forks source link

Enhancement request: Add docker healthcheck #793

Closed animeai closed 1 month ago

animeai commented 1 month ago

Currently the way this is set up as a docker container there is no way to run any kind of healthcheck.

Having a healthcheck built into the docker container allows for unhealthy containers (i.e. those that fail the healthcheck) to be either automatically restarted or flagged for investigation. I understand that the decision to use a scratch container with no shell (or other unnecessary binaries) is a good choice for security, and adding a shell, python, curl, or similar defeats the purpose.

Since this is a project written in go, would it be possible to add a simple healthcheck binary? It would only need to poll http://localhost:5454 when run and return either an exit code of 1 it if cannot connect, or exit code of 0 if it can. The healthcheck can then be incorporated into the Dockerfile at build or added manually to the docker-compose file or docker run command so the container can be marked as healthy or unhealthy,.

davidnewhall commented 1 month ago

Hello, and thanks for your report. Answers inlined below.

Currently the way this is set up as a docker container there is no way to run any kind of healthcheck.

If the container stops working the website will send a notice to your client discord channel. That's the "built-in" health check. Outside of that, what is considered unhealthy?

There is no shell as it is a scratch container.

We also have these non-scratch containers:

ghcr.io/notifiarr/notifiarr:alpine
ghcr.io/notifiarr/notifiarr:cuda

There is no curl.

A curl-like command is built into Notifiarr. It may not be perfect, but we can tune it. I'm not sure how to use it to poll the notifiarr client itself though. My attempts to use 127.0.0.1 did not work.

/notifiarr --curl http://url.here

ie.

root@rzr:~# docker run -it notifiarr /notifiarr --curl http://localhost:5454
[ERROR] 2024/07/29 17:18:44 making http request: Get "http://localhost:5454": dial tcp 127.0.0.1:5454: connect: connection refused

As far as I can tell there are no languages

That's the nature of a scratch container.

Since this is a project written in go, would it be possible to add a simple healthcheck binary?

It has one. :) However, the app works fine without the local web server listening. It can also hang and stop working with the web server listening. Checking port 5454 is probably not any more useful than checking if the container has a PID.


I'm curious if this is a real problem you need to solve, or if this is a nice-to-have?

davidnewhall commented 1 month ago

I was using docker run instead of docker exec. This worked (as well as 127.0.0.1):

root@rzr:~# docker exec -it Notifiarr /notifiarr --curl http://172.23.0.4:5454
401 Unauthorized
Date: Mon, 29 Jul 2024 17:29:25 GMT
Content-Type: text/html

The thing I'd caution you on here is that when you go into the WebUI and click save, it reloads the app. During that reload the web server is disabled. It may be disabled for up to 70 seconds. If the health check fires in this time, it'll restart the container.

animeai commented 1 month ago

Absolutely a "nice to have". Mostly so I can automate a restart of the container if it becomes unhealthy (i.e. broken) and I can't log into the server immediately. Chances are it will never need this but I like belt and braces!

I played around with various iterations of "/notifiarr --curl http://localhost:5454 || exit 1" with the scratch image but couldn't get it to work and mark the container as healthy. Then I noticed you mentioned an alpine container which includes wget. Wget would be my 3rd choice after curl, then bash, but it will work.

healthcheck:
  test: timeout 10s wget --quiet --tries=1 --spider http://localhost:5454
  interval: 60s
  timeout: 10s
  start_period: 120s
  retries: 5

Adding this as a healthcheck with the alpine image worked great! Thanks so much for your help - I wouldn't have found the alpine version without you as it doesn't seem to be referenced in the docs here, or be available on docker hub.

davidnewhall commented 1 month ago

||and exit are bash commands. The health check doesn't run bash, so that isn't needed and will likely cause an immediate failure. To avoid relying on DNS, the most accurate check would be /notifiarr --curl http://127.0.0.1:5454/

Glad you got it figured out!