{"id":13936374,"url":"https://github.com/vfxGer/docker_eventer","last_synced_at":"2025-07-19T21:32:31.091Z","repository":{"id":45353869,"uuid":"110172769","full_name":"vfxGer/docker_eventer","owner":"vfxGer","description":"A Docker container to notify about Docker events written in Python","archived":false,"fork":false,"pushed_at":"2019-01-10T15:37:51.000Z","size":20,"stargazers_count":14,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-27T04:30:57.308Z","etag":null,"topics":["container","docker","docker-compose","events","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vfxGer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-09T22:20:41.000Z","updated_at":"2023-02-20T16:03:42.000Z","dependencies_parsed_at":"2022-09-19T01:30:34.543Z","dependency_job_id":null,"html_url":"https://github.com/vfxGer/docker_eventer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vfxGer/docker_eventer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vfxGer%2Fdocker_eventer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vfxGer%2Fdocker_eventer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vfxGer%2Fdocker_eventer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vfxGer%2Fdocker_eventer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vfxGer","download_url":"https://codeload.github.com/vfxGer/docker_eventer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vfxGer%2Fdocker_eventer/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266019657,"owners_count":23864916,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["container","docker","docker-compose","events","python"],"created_at":"2024-08-07T23:02:36.661Z","updated_at":"2025-07-19T21:32:26.084Z","avatar_url":"https://github.com/vfxGer.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# Docker Event\n\n## The Problem\n\nI had a problem recently. I had a couple Docker containers on one machine \nfor a personal project which was a django web app called \n[issueinfinity.com](https://www.issueinfinity.com). \nOne of the containers, that was doing some image manipulation, kept \ncrashing and I did not know until I logged into the machine and looked at it\n using `docker ps`. So I wanted an e-mail notification if any of my \n containers stopped or if anything happened to them. \n \n## The Command\nI discovered a command `docker events`. This is a very handy command to see what has \n happened to your docker containers.\n \nTo see what has happened to your containers in the last hour you can run:\n\n    docker events --format {{json .}} --since \"1h\" --until \"0s\"\n    \nThe `--since 1h` simply means get everything since an hour ago.\n\nThe `--until 0s` means until 0 seconds ago, without the `--until` the command\n will just continually stream docker events.\n \nThe `--format \"{{json .}}\"` argument outputs the events as \n[JSON lines](http://jsonlines.org) which basically means a JSON document for\n every event.\n\nAs well as the above you can add filters to the events like\n\n    docker events --filter 'container=test' --filter 'event=stop'\n\nThis will output any stop event on the test container. For more about the \nfilters and more details on the other the arguments see the \n[official docker docs](https://docs.docker.com/engine/reference/commandline/events)\n\n## The Python Script\nSo now we have enough to create a Python script:\n```python\nimport sys\nimport subprocess\nimport time\nimport json\nfrom collections import Counter\nfrom pprint import pprint, pformat\n\nfrom notifier import notify\n\n\ndef run():\n    proc = subprocess.Popen('docker events --format \"{{json .}}\" --since \"1h\" --until \"0s\"',\n                            stdout=subprocess.PIPE,\n                            stderr=subprocess.STDOUT, shell=True)\n\n    retcode = proc.poll()\n    wait_time = 0.1\n    while retcode is None:\n        time.sleep(wait_time)\n        retcode = proc.poll()\n    res = proc.stdout.read()\n    res = res.decode(\"utf-8\")\n    event_data = []\n    for line in res.split(\"\\n\"):\n        line = line.strip()\n        if line:\n            event_data.append(json.loads(line))\n            pprint(event_data[-1])\n            print(\"-\"*5)\n    if event_data:\n        message = \"\"\n        message += \"\\n%d events\\n\" % len(event_data)\n        message += pformat(Counter(row['Action'] for row in event_data))\n        message += \"\\n\"\n        message += pformat(event_data)\n        subject = \"[DOCKER_EVENTS] %d docker events\\n\" % len(event_data)\n        notify(message, subject)\n        print(\"e-mail sent\")\n\n\ndef main(_):\n    while True:\n        run()\n        print(\"Now sleeping for an hour\")\n        time.sleep(60*60)\n\n\n\nif __name__==\"__main__\":\n    main(sys.argv[1:])\n```\n\nHere I am simply running the docker event in a subprocess. \nI am the putting the stderr of the process into stdout and putting \nstdout into a temporary file. The temporary file avoids issues with \nbuffer overflows. Then the script sends an e-mail(not shown) if there is \nany events \nand parses the json to create a summary of the work.\n\nAlthough this works the subprocess adds overhead so to simplify the \nsolution we can just use the docker python api.\n\n## Using the Docker Python API\nSimply run `pip install docker`\nto install the python docker api.\n\nNow the script becomes simpler:\n\n```python\nimport sys\nimport time\nfrom collections import Counter\nfrom pprint import pprint, pformat\nimport datetime\n\nfrom notifier import notify\nimport docker\n\n\ndef run():\n    client = docker.from_env()\n    until = datetime.datetime.utcnow()\n    since = until - datetime.timedelta(hours=1)\n    event_data = []\n    for event in client.events(since=since, until=until, decode=True):\n        event_data.append(event)\n        pprint(event_data[-1])\n        print(\"-\" * 5)\n    if event_data:\n        message = \"\"\n        message += \"\\n%d events\\n\" % len(event_data)\n        message += pformat(Counter(row['Action'] for row in event_data))\n        message += \"\\n\"\n        message += pformat(event_data)\n        subject = \"%d docker events\\n\" % len(event_data)\n        notify(message, subject)\n        print(\"e-mail sent\")\n\n\ndef main(_):\n    while True:\n        run()\n        print(\"Now sleeping for an hour\")\n        time.sleep(60*60)\n\n\nif __name__==\"__main__\":\n    main(sys.argv[1:])\n```\n\nThe docker client is created from the environment with `docker.from_env`, \nwhich means it works like the command line would. \nThe client.events function works very similar to the command line version. \nThe `decode=True` means the output are python dictionaries.\n## I Put Docker in your Docker\nNow I could put this python script into supervisord and run on the docker \nmachine but if we are using docker why not use docker. \nTo get this working in a docker container we need to install the docker \nclient inside the container. The simplest way to do this is to run  \n`apt-get install docker.io` in the Dockerfile. \n\nThen to make it work we need to mount the docker socket into the container \nwith `/var/run/docker.sock:/var/run/docker.sock`.\n\nYou can see this in the docker-compose.yml file.\n\nAnd voila a docker event notifier. \n\n## Update, now streaming\nA comment on [reddit](https://www.reddit.com/r/Python/comments/7bx7qe/an_explanation_and_code_of_a_python_script_to/dpm39e5/) said:\n\u003e Though preferably it would be rather when an event happens than just polling for it.\n\nAnd I agree but I still did not want to be bombarded with e-mails so here's what I came up with\n```python\n#!/usr/bin/env python3\nimport time\nfrom collections import Counter\nfrom pprint import pformat\nimport datetime\n\nimport docker\n\nimport notifier\n\nMAX_NOTIFY_TIME = 60\n\n\ndef notify(events):\n    message = \"\"\n    message += \"\\n%d events\\n\" % len(events)\n    message += pformat(Counter(row['Action'] for row in events))\n    message += \"\\n\"\n    message += pformat(events)\n    subject = \"[DOCKER_EVNETS] %d docker events\\n\" % len(events)\n    print(\"Sending e-mail %s\", subject)\n    notifier.notify(message, subject)\n\n\ndef run():\n    client = docker.from_env()\n    while True:\n        for event in client.events(decode=True):\n            notify([event])\n            break\n        since = datetime.datetime.now()\n        # Do not want to bombard the e-mailer with messages so sleeping\n        print(\"Sleeping for %d seconds\" % MAX_NOTIFY_TIME)\n        time.sleep(MAX_NOTIFY_TIME)\n        print(\"Woke\")\n        until = datetime.datetime.now()\n        notify([event for event in client.events(since=since, until=until, decode=True)])\n\n\ndef main():\n    run()\n\n\nif __name__==\"__main__\":\n    main()\n\n```\nIt is a simple solution, it gets the first event, e-mails about it and then sleeps. After the program stops sleeping it gets all the events that happened while it was sleeping and sends them and repeats.\n\n## Still to do:\n- [ ] make it more configurable\n- [x] make it send notification on the first event and not just once an hour\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FvfxGer%2Fdocker_eventer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FvfxGer%2Fdocker_eventer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FvfxGer%2Fdocker_eventer/lists"}