caronc / apprise-api

A lightweight REST framework that wraps the Apprise Notification Library
https://hub.docker.com/r/caronc/apprise
MIT License
673 stars 61 forks source link

Stateful Configuration File Usage #195

Closed instantdreams closed 5 months ago

instantdreams commented 5 months ago

:question: Using a Configuration File

I am sure I'm missing something obvious here, checking to validate my steps as I've been looking at this for far too long.

Configuration

I first create an example configuration file with generic details:

version: 1

urls:
  - tgram://{token_id}/{chat_id}/:
    - tag: general
  - tgram://{token_id}/{chat_id}:{topic_id}/:
    - tag: topic

I then set up the environment to use the correct values and right permissions:

cd /srv/apprise
mkdir attach config plugin
cp apprise.example.yaml config/apprise.yaml
nano config/apprise.yaml
sudo chown www-data:www-data --recursive attach config plugin
sudo chmod g+rwx --recursive attach config plugin

As part of this process I add the correct telegram tokens, chat ids, and topics.

I then stand up the container:

docker compose pull
docker compose up --detach
sleep 8
docker compose logs

Here is my compose.yaml file configuration:

name: apprise
services:
  apprise:
    container_name: apprise
    environment:
      - TZ=America/Edmonton
      - APPRISE_STATEFUL_MODE=simple
      - APPRISE_CONFIG_LOCK=no
      - APPRISE_DEFAULT_THEME=dark
    hostname: apprise
    image: caronc/apprise:latest
    ports:
      - mode: ingress
        protocol: tcp
        published: "8000"
        target: 8000
    restart: unless-stopped
    user: www-data:www-data
    volumes:
      - bind:
          create_host_path: true
        source: /srv/apprise/attach
        target: /attach
        type: bind
      - bind:
          create_host_path: true
        source: /srv/apprise/config
        target: /config
        type: bind
      - bind:
          create_host_path: true
        source: /srv/apprise/plugin
        target: /plugin
        type: bind
      - bind:
          create_host_path: true
        read_only: true
        source: /etc/timezone
        target: /etc/timezone
        type: bind
      - bind:
          create_host_path: true
        read_only: true
        source: /etc/localtime
        target: /etc/localtime
        type: bind

Status

The following commands all work:

$ docker exec apprise apprise --help
Usage: apprise [OPTIONS] SERVER_URL [SERVER_URL2 [SERVER_URL3]]
...

$ docker exec apprise apprise --config /config/apprise.yaml --body "Hello there" --title "General Kenobi" --tag general

$ docker exec apprise apprise --config /config/apprise.yaml --body "Hello there" --title "General Kenobi" --tag topic

The Assumption

When I access my server at http://[server-ip]:8000/ I would expect to see the configuration visible under the Configuration Manager so I can review and test the settings from the web ui.

The Question

Do I to use the add function? If so, are there any curl examples that I could use?

caronc commented 5 months ago

Hmm, as a test, what happens if you rename the file to apprise.yml?

instantdreams commented 5 months ago

Here are the steps taken:

$ cd /srv/apprise/
$ ls -lha config/
total 16K
drwxrwxr-x 3 www-data www-data 4.0K Jun 10 14:33 .
drwxr-xr-x 5 idsvc    idsvc    4.0K Jun 10 14:36 ..
-rwxrwxr-x 1 www-data www-data 1.1K Jun 10 14:33 apprise.yaml
drwxrwxr-x 2 www-data www-data 4.0K Jun 10 13:54 .tmp_healthcheck

$ docker compose down
[+] Running 1/1
 ✔ Container apprise  Removed                                                                                                                          2.0s

$ sudo mv config/apprise.yaml config/apprise.yml
$ ls -lha config/
total 16K
drwxrwxr-x 3 www-data www-data 4.0K Jun 10 15:43 .
drwxr-xr-x 5 idsvc    idsvc    4.0K Jun 10 14:36 ..
-rwxrwxr-x 1 www-data www-data 1.1K Jun 10 14:33 apprise.yml
drwxrwxr-x 2 www-data www-data 4.0K Jun 10 13:54 .tmp_healthcheck

$ docker compose pull;docker compose down;sleep 2;docker compose up --detach;sleep 16;docker compose logs
[+] Pulling 1/1
 ✔ apprise Pulled                                                                                                                                      0.7s
Warning: No resource found to remove for project "apprise".
[+] Running 1/1
 ✔ Container apprise  Started                                                                                                                          0.5s
apprise  | 2024-06-10 15:44:13,710 INFO Set uid to user 33 succeeded
apprise  | 2024-06-10 15:44:13,714 INFO supervisord started with pid 1
apprise  | 2024-06-10 15:44:14,718 INFO spawned: 'gunicorn' with pid 7
apprise  | 2024-06-10 15:44:14,722 INFO spawned: 'nginx' with pid 8
apprise  | [2024-06-10 15:44:15 -0600] [7] [INFO] Starting gunicorn 22.0.0
apprise  | [2024-06-10 15:44:15 -0600] [7] [INFO] Listening at: http://0.0.0.0:8080 (7)
apprise  | [2024-06-10 15:44:15 -0600] [7] [INFO] Using worker: gevent
apprise  | [2024-06-10 15:44:15 -0600] [11] [INFO] Booting worker with pid: 11
apprise  | [2024-06-10 15:44:15 -0600] [12] [INFO] Booting worker with pid: 12
apprise  | [2024-06-10 15:44:15 -0600] [13] [INFO] Booting worker with pid: 13
apprise  | [2024-06-10 15:44:15 -0600] [14] [INFO] Booting worker with pid: 14
apprise  | 2024-06-10 15:44:15,785 INFO success: gunicorn entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
apprise  | 2024-06-10 15:44:15,786 INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
apprise  | [2024-06-10 15:44:15 -0600] [15] [INFO] Booting worker with pid: 15

Accessing http://[server-ip]:8000/ allows me to create new entries using the web ui but does not show the content of apprise.yml.

instantdreams commented 5 months ago

Should this be automatically loaded?

caronc commented 5 months ago

Sorry for the delay, yes, it should be automatically loaded. I'm wondering if the website doesn't know where to look.

See here and set the environment variable APPRISE_CONFIG_DIR to /config since that is where you're placing your config files.

instantdreams commented 5 months ago

I've added the APPRISE_CONFIG_DIR environment value to no effect.

Here is the compose config:

name: apprise
services:
  apprise:
    container_name: apprise
    environment:
      - TZ=America/Edmonton
      - APPRISE_STATEFUL_MODE=simple
      - APPRISE_CONFIG_LOCK=no
      - APPRISE_DEFAULT_THEME=dark
      - APPRISE_CONFIG_DIR=/config
    hostname: apprise
    image: caronc/apprise:latest
    ports:
      - mode: ingress
        protocol: tcp
        published: "8000"
        target: 8000
    restart: unless-stopped
    user: www-data:www-data
    volumes:
      - bind:
          create_host_path: true
        source: /srv/apprise/attach
        target: /attach
        type: bind
      - bind:
          create_host_path: true
        source: /srv/apprise/config
        target: /config
        type: bind
      - bind:
          create_host_path: true
        source: /srv/apprise/plugin
        target: /plugin
        type: bind
      - bind:
          create_host_path: true
        read_only: true
        source: /etc/timezone
        target: /etc/timezone
        type: bind
      - bind:
          create_host_path: true
        read_only: true
        source: /etc/localtime
        target: /etc/localtime
        type: bind

Here are the logs:

apprise  | 2024-06-13 08:45:16,184 INFO Set uid to user 33 succeeded
apprise  | 2024-06-13 08:45:16,188 INFO supervisord started with pid 1
apprise  | 2024-06-13 08:45:17,193 INFO spawned: 'gunicorn' with pid 7
apprise  | 2024-06-13 08:45:17,198 INFO spawned: 'nginx' with pid 8
apprise  | 2024-06-13 08:45:18,200 INFO success: gunicorn entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
apprise  | 2024-06-13 08:45:18,200 INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
apprise  | [2024-06-13 08:45:18 -0600] [7] [INFO] Starting gunicorn 22.0.0
apprise  | [2024-06-13 08:45:18 -0600] [7] [INFO] Listening at: http://0.0.0.0:8080 (7)
apprise  | [2024-06-13 08:45:18 -0600] [7] [INFO] Using worker: gevent
apprise  | [2024-06-13 08:45:18 -0600] [11] [INFO] Booting worker with pid: 11
apprise  | [2024-06-13 08:45:18 -0600] [12] [INFO] Booting worker with pid: 12
apprise  | [2024-06-13 08:45:18 -0600] [13] [INFO] Booting worker with pid: 13
apprise  | [2024-06-13 08:45:18 -0600] [14] [INFO] Booting worker with pid: 14
apprise  | [2024-06-13 08:45:18 -0600] [15] [INFO] Booting worker with pid: 15

Here is what I see when I access the web ui: image

When I select Configuration Manager I see this: image

I'm wondering how the id of key is set when apprise-api imports the configuration file.

I have tried to add the values from the configuration key using the API:

$ curl --request POST --form 'config=/config/apprise.yml' --form 'format=yaml' http://192.168.1.93:8000/add/notify-telegram
No valid URL(s) defined

$ curl --request POST --data '{"config": "apprise.yml", "format":"yaml"}' --header "Content-Type: application/json" http://192.168.1.93:8000/add/notify-telegram
{"error": "No valid URL(s) defined"}

I'm not sure why it is asking for a URL when I specified the config parameter.

I tried the add method without a key:

$ curl --request POST --form "config=/config/apprise.yml" --form "format=yaml" http://192.168.1.93:8000/add

<!doctype html>
<html lang="en">
<head>
  <title>Not Found</title>
</head>
<body>
  <h1>Not Found</h1><p>The requested resource was not found on this server.</p>
</body>
</html>

Are there any other debugging options I could turn on?

instantdreams commented 5 months ago

I added the following to my compose.yaml file:

      - LOG_LEVEL=DEBUG
      - DEBUG=yes

The following commands were run:

$ curl --request POST --form "config=/config/apprise.yml" --form "format=yaml" http://192.168.1.93:8000/add/notify-telegram
No valid URL(s) defined

$ curl --request POST --data '{"config": "apprise.yml", "format":"yaml"}' --header "Content-Type: application/json" http://192.168.1.93:8000/add/notify-telegram
{"error": "No valid URL(s) defined"}

$ curl --request POST http://192.168.1.93:8000/details

$ docker exec apprise apprise --config /config/apprise.yml --title "Apprise Test" --body "Body of message" --tag topic

The log files have additional information:

apprise  | 2024-06-13 09:45:07,860 INFO Set uid to user 33 succeeded
apprise  | 2024-06-13 09:45:07,862 INFO supervisord started with pid 1
apprise  | 2024-06-13 09:45:08,865 INFO spawned: 'gunicorn' with pid 7
apprise  | 2024-06-13 09:45:08,869 INFO spawned: 'nginx' with pid 8
apprise  | [2024-06-13 09:45:09 -0600] [7] [INFO] Starting gunicorn 22.0.0
apprise  | [2024-06-13 09:45:09 -0600] [7] [INFO] Listening at: http://0.0.0.0:8080 (7)
apprise  | [2024-06-13 09:45:09 -0600] [7] [INFO] Using worker: gevent
apprise  | [2024-06-13 09:45:09 -0600] [11] [INFO] Booting worker with pid: 11
apprise  | [2024-06-13 09:45:09 -0600] [12] [INFO] Booting worker with pid: 12
apprise  | [2024-06-13 09:45:09 -0600] [13] [INFO] Booting worker with pid: 13
apprise  | 2024-06-13 09:45:09,877 INFO success: gunicorn entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
apprise  | 2024-06-13 09:45:09,877 INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
apprise  | [2024-06-13 09:45:09 -0600] [14] [INFO] Booting worker with pid: 14
apprise  | [2024-06-13 09:45:10 -0600] [15] [INFO] Booting worker with pid: 15
apprise  | 2024-06-13 10:45:20,470 [DEBUG] apprise: Language set to en
apprise  | 2024-06-13 10:45:20,733 [DEBUG] apprise: Attachment Plugin 2(s) and 3 Schema(s) loaded in 0.0008s
apprise  | 2024-06-13 10:45:20,742 [DEBUG] apprise: Language set to en
apprise  | 2024-06-13 10:45:20,742 [DEBUG] apprise: Loading raw configuration: /config/apprise.yml
apprise  | 2024-06-13 10:45:20,743 [DEBUG] apprise: Configuration Plugin 3(s) and 4 Schema(s) loaded in 0.0015s
apprise  | 2024-06-13 10:45:20,744 [ERROR] apprise: Invalid Apprise YAML based configuration specified.
apprise  | 2024-06-13 10:45:20,744 [WARNING] apprise: Failed to load Apprise configuration from memory://
apprise  | 2024-06-13 10:45:20,744 [WARNING] django: ADD - 127.0.0.1 - No valid URL(s) defined using KEY: notify-telegram
apprise  | 2024-06-13 10:45:20,745 [WARNING] django.request: Bad Request: /add/notify-telegram
apprise  | 192.168.1.93 - - [13/Jun/2024:09:45:20 -0600] "POST /add/notify-telegram HTTP/1.1" 400 23 "-" "curl/7.88.1"
apprise  | 2024/06/13 09:45:20 [info] 10#10: *1 client 192.168.1.93 closed keepalive connection
apprise  | 2024-06-13 10:45:41,835 [DEBUG] apprise: Language set to en
apprise  | 2024-06-13 10:45:42,046 [DEBUG] apprise: Attachment Plugin 2(s) and 3 Schema(s) loaded in 0.0007s
apprise  | 2024-06-13 10:45:42,050 [DEBUG] apprise: Language set to en
apprise  | 2024-06-13 10:45:42,050 [DEBUG] apprise: Loading raw configuration: apprise.yml
apprise  | 2024-06-13 10:45:42,052 [DEBUG] apprise: Configuration Plugin 3(s) and 4 Schema(s) loaded in 0.0017s
apprise  | 2024-06-13 10:45:42,052 [ERROR] apprise: Invalid Apprise YAML based configuration specified.
apprise  | 2024-06-13 10:45:42,053 [WARNING] apprise: Failed to load Apprise configuration from memory://
apprise  | 2024-06-13 10:45:42,053 [WARNING] django: ADD - 127.0.0.1 - No valid URL(s) defined using KEY: notify-telegram
apprise  | 2024-06-13 10:45:42,055 [WARNING] django.request: Bad Request: /add/notify-telegram
apprise  | 192.168.1.93 - - [13/Jun/2024:09:45:42 -0600] "POST /add/notify-telegram HTTP/1.1" 400 36 "-" "curl/7.88.1"
apprise  | 2024/06/13 09:45:42 [info] 9#9: *3 client 192.168.1.93 closed keepalive connection
apprise  | 2024-06-13 10:45:48,141 [DEBUG] apprise: Language set to en
apprise  | 2024-06-13 10:45:48,365 [DEBUG] apprise: Attachment Plugin 2(s) and 3 Schema(s) loaded in 0.0008s
apprise  | 2024-06-13 10:45:48,368 [WARNING] django.request: Method Not Allowed (POST): /details
apprise  | 2024-06-13 10:45:48,368 [WARNING] django.request: Method Not Allowed: /details
apprise  | 192.168.1.93 - - [13/Jun/2024:09:45:48 -0600] "POST /details HTTP/1.1" 405 0 "-" "curl/7.88.1"
apprise  | 2024/06/13 09:45:48 [info] 10#10: *5 client 192.168.1.93 closed keepalive connection

The test message was received by my telegram topic. There seems to be a disconnection between what the apprise command line is expecting and what the apprise-api is trying to load?

caronc commented 5 months ago

I can't reproduce your issue, the API uses the same Apprise library under the hood.

Would you be able to send over your configuration to me at lead2gold@gmail.com. or at the very least, reveal your add call being made by curl?

Could you try just using the website alone just to test that it is saving everything correctly?

caronc commented 5 months ago

I sent an email about the docker setup. For the add calls, you need to pass the configuration itself, not the name of the file:


# The below may work 
 curl --request POST --form "config=$(</config.file)" http://192.168.1.93:8000/add/notify-telegram
instantdreams commented 5 months ago

This issue was initially fixed by running the following commands:

cd /srv/apprise/
mkdir attach/ config/ plugin/
sudo chown --recursive www-data:www-data attach/ config/ plugin/
sudo chmod --recursive 777 attach/ config/ plugin/
docker compose up --detach

However, on reviewing this, once I check the logs I see nothing loaded:

apprise  | 2024-06-21 09:16:27,475 INFO Set uid to user 33 succeeded
apprise  | 2024-06-21 09:16:27,477 INFO supervisord started with pid 1
apprise  | 2024-06-21 09:16:28,481 INFO spawned: 'gunicorn' with pid 8
apprise  | 2024-06-21 09:16:28,485 INFO spawned: 'nginx' with pid 9
apprise  | [2024-06-21 09:16:29 -0600] [8] [INFO] Starting gunicorn 22.0.0
apprise  | [2024-06-21 09:16:29 -0600] [8] [INFO] Listening at: http://0.0.0.0:8080 (8)
apprise  | [2024-06-21 09:16:29 -0600] [8] [INFO] Using worker: gevent
apprise  | [2024-06-21 09:16:29 -0600] [12] [INFO] Booting worker with pid: 12
apprise  | [2024-06-21 09:16:29 -0600] [13] [INFO] Booting worker with pid: 13
apprise  | [2024-06-21 09:16:29 -0600] [14] [INFO] Booting worker with pid: 14
apprise  | [2024-06-21 09:16:29 -0600] [15] [INFO] Booting worker with pid: 15
apprise  | 2024-06-21 09:16:29,527 INFO success: gunicorn entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
apprise  | 2024-06-21 09:16:29,527 INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

It isn't until I access http://192.168.1.93:8000/cfg/apprise/ that the configuration is loaded:

apprise  | 2024-06-21 10:48:47,527 [DEBUG] apprise: Language set to en
apprise  | 2024-06-21 10:48:47,726 [DEBUG] apprise: Attachment Plugin 2(s) and 3 Schema(s) loaded in 0.0008s
apprise  | 192.168.1.110 - - [21/Jun/2024:09:48:47 -0600] "GET /cfg/apprise HTTP/1.1" 200 8563 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0"
apprise  | 2024-06-21 10:48:47,853 [DEBUG] apprise: Language set to en
apprise  | 2024-06-21 10:48:47,853 [DEBUG] apprise: Loading raw configuration: version: 1
apprise  |
apprise  | [...]
apprise  |
apprise  | 2024-06-21 10:48:47,856 [DEBUG] apprise: Configuration Plugin 3(s) and 4 Schema(s) loaded in 0.0027s
apprise  | 2024-06-21 10:48:48,069 [DEBUG] apprise: Notification Plugin 104(s) and 148 Schema(s) loaded in 0.2081s

I would have expected the configuration to automatically load - is there a command I need to pass in the compose file to get it to load the file on start up, e.g.:

    command: --config.file=/config/apprise.yml

Thank you!

caronc commented 5 months ago

Glad you got it resolved; closing off the ticket.

instantdreams commented 5 months ago

Latest release results in the following:

apprise  | You must be root to run this script.
apprise  | Caution: This should only be ran in a dockerized instance!

Looking into it. Will remove user: www-data:www-data first.

instantdreams commented 5 months ago

Removed the user: declaration in the compose file. Restarted the container. Everything works.