node-notifier icon indicating copy to clipboard operation
node-notifier copied to clipboard

Notification on host from a docker container?

Open si14 opened this issue 6 years ago • 21 comments

Hi there!

There is a pretty common (as far as I know) pattern of using frontend tools in Docker containers for local development. However, it makes notifications (using e.g. gulp-notify) problematic. One option I can think of is using Growl service on host, but Growl is now a paid app and thus suboptimal. Do you think there are other ways to provide host notifications?

si14 avatar Sep 07 '17 14:09 si14

Hi ! Trying to achieve the exact same thing, did advance on this subject ? thanks

philippefuentes avatar Oct 12 '17 11:10 philippefuentes

Also looking for this :)

alexgorbatchev avatar Oct 24 '17 03:10 alexgorbatchev

Is it possible to do something like IPC communication from docker? Either that, or you could create your own GNTP-server (it's an open protocol) listening on host machine and doing notifications.

mikaelbr avatar Jan 14 '18 10:01 mikaelbr

Would be great :)

christianhaller avatar Jan 30 '18 19:01 christianhaller

I think maybe this is something not in the scope of this project. But thinking about it I think it would be fairly straight forward to use node-nofifier as a client inside an environment and write a HTTP server implementing the GNTP (or a subset) using node-notifier again on the host environment to actually interact with the OS. Did that make any sense?

mikaelbr avatar Jan 30 '18 20:01 mikaelbr

+1 for this: @si14 did you find solution to this?

damianobarbati avatar Apr 26 '18 16:04 damianobarbati

+1

ostenning avatar May 18 '18 14:05 ostenning

On Ubuntu, etc. It seems like libn0tify-bin listens on an address/port already, and that that can be set with env vars on the host. https://github.com/bersace/libnotify-proxy/blob/master/notify-proxy. Here's the relevant segment:

logger.info("Starting notify-proxy")

loop = asyncio.get_event_loop()
addr = os.environ.get('PROXY_ADDR', '127.0.0.1')
port = int(os.environ.get('PROXY_PORT', '1216'))
server = loop.run_until_complete(loop.create_server(
    NotifyProtocol, addr, port,
    reuse_address=True, reuse_port=True,
))

logger.info("Listening on %s:%d", addr, port)

Seems like you could make that accessible to node-notifier inside the container and it would work.

RowdyElectron avatar Aug 28 '18 14:08 RowdyElectron

Example of sending notifications using notify-send-server (Linux Mint 18.3 XFCE host) and notify-send-http (tested inside ubuntu:latest):

On Host:

curl -L https://github.com/fgrehm/notify-send-http/releases/download/v0.2.0/server-linux_amd64 > $HOME/.local/bin/notify-send-server
chmod +x $HOME/.local/bin/notify-send-server

Confirm:

 which notify-send-server

Then start:

PORT=12345 notify-send-server

Start Ubuntu:

docker run -it ubuntu:latest /bin/bash

Now in container:

apt update
apt install curl iputils-ping npm
curl -L https://github.com/fgrehm/notify-send-http/releases/download/v0.2.0/client-linux_amd64 |  tee /usr/bin/notify-send &>/dev/null;
chmod +x  /usr/bin/notify-send
export NOTIFY_SEND_URL="http://<<your host IP>>:12345"

Test:

notify-send "summary" "message"
npm i -g node-notifier-cli

Installed in my container at

/usr/local/lib/node_modules/node-notifier-cli

Run:

nodejs bin.js -t "summary" -m "message" 

--- EDIT --- Hmm Looks like a lot of this has been documented on the README at https://github.com/fgrehm/notify-send-http

RowdyElectron avatar Aug 28 '18 15:08 RowdyElectron

@si14 Can you take a look at this solution and try it with the non-cli version of node-notifier. My JS abilities are very weak :/

RowdyElectron avatar Aug 28 '18 15:08 RowdyElectron

@RowdyElectron I have it working, great work!

mkantautas avatar Aug 30 '18 00:08 mkantautas

Any update on this?

rakishii13 avatar Nov 06 '18 19:11 rakishii13

Bumperino!

marcospgp avatar Feb 28 '19 16:02 marcospgp

What more can I do to make this a workable solution for you @marcospgp @rakishii13 ? I am not too familiar with JS, so I may need help if internals are needed to be changed. @mikaelbr May we continue this issue to see if a solution can be implemented?

RowdyElectron avatar Mar 01 '19 09:03 RowdyElectron

As a band-aid, if you use Gulp both inside and outside of Docker, you can disable gulp-notify using an environment variable that's set in your container.

afeld avatar Apr 21 '19 21:04 afeld

Bumping 🙏

johannessjoberg avatar Oct 25 '19 11:10 johannessjoberg

I looked around for a solution with not much luck so I made a thing that does this, though it does require a little bit of setup: kolombo

jarofghosts avatar Apr 04 '20 22:04 jarofghosts

So, I finally found a solution which works on linux (no luck on osx or windows so far): node-notifier uses libnotify-bin here, which relies on dbus. If you share the dbus socket into the container and node runs as the same user as the host user, you can see desktop notifications.

Source: https://github.com/mviereck/x11docker/wiki/How-to-connect-container-to-DBus-from-host#dbus-user-session-daemon

DBus user session daemon

The DBus user session daemon can have a real or an abstract unix socket. Check the output of echo $DBUS_SESSION_BUS_ADDRESS.

If it contains unix:path, it is a real unix socket within file system. If it contains unix:abstract, it is an abstract unix socket.

DBus with real unix socket in file system

Example: DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus Set this variable as it is given: --env DBUS_SESSION_BUS_ADDRESS="$DBUS_SESSION_BUS_ADDRESS" Share the given socket file: --volume /run/user/1000/bus:/run/user/1000/bus Run image with same user as on host: --user $(id -u):$(id -g) Test: Run notify-send "hello host" in container.

DBus with abstract unix socket

Example: DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-KDKGRIL7QX,guid=221d2f667e843d50fd1dc6a05babf8ae Set this variable as it is given: --env DBUS_SESSION_BUS_ADDRESS="$DBUS_SESSION_BUS_ADDRESS" Allow access with --network=host. This is an unfortunate insecure solution that shares host network stack with container.

Does anyone know if notifications on osx and windows also use socket files? Maybe there is a similar solution?

tbruckmaier avatar Sep 22 '20 09:09 tbruckmaier

I was trying to find a solution for this but unfortunately, it was either too complicated or unsupported. As of September 2021, Growl is deprecated. I found an article that claims to have solved the issue but it requires to use vagrant - https://medium.com/@gilesbutler/forwarding-notifications-from-a-ubuntu-vm-to-osx-host-42e7ba8abc33. I didn't try it myself. Another article is a very advanced custom solution, definitely not a step-by-step guide - https://nitish.ch/notes/notifications-in-mac-from-a-linux-ssh-server/.

alexkuc avatar Sep 12 '21 02:09 alexkuc

I haven't used this library in a long time, but from a high level a solution for this would be to run an alerting client locally and have it listen for alerts from a docker container. Would need to share a port with the container.

marcospgp avatar Sep 13 '21 13:09 marcospgp

I have used simple pipe (mkpipe) as volume and shell script to watch for input, parse with cut -d ";" and then send to notify-send It surely can be used on mac os, maybe wsl.

lamasutra avatar Dec 31 '22 19:12 lamasutra