added Dockerfile
This commit is contained in:
9
Dockerfile
Normal file
9
Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM python:3.7
|
||||||
|
WORKDIR /app
|
||||||
|
COPY receiver.py .
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN python -m pip install -r requirements.txt
|
||||||
|
CMD ["python", "/app/receiver.py"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
16
README.md
Normal file
16
README.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Mail Receiver for Healthcheck
|
||||||
|
|
||||||
|
This is a simple docker container which acts as SMTP backend and forwards pings from mail to healthchecks.
|
||||||
|
|
||||||
|
I made this up, because the docker container I use for healthchecks does not include smtp, and I did not want do maintain this container on my own.
|
||||||
|
|
||||||
|
## Usage:
|
||||||
|
|
||||||
|
Basically run the docker container with the following environment variables set:
|
||||||
|
|
||||||
|
- `PING_URL`: The base url for the ping to healthchecks in the format `https://yourinstance.com/ping/` please do not remove the trailing slash.
|
||||||
|
- `PING_ID`: The ID to track the health of this script/container itself.
|
||||||
|
- `PING_TIMEOUT`: The time between pings for the script should be done.
|
||||||
|
- `MAIL_DOMAIN`: The domain name to accept messages for.
|
||||||
|
|
||||||
|
|
||||||
18
receiver.py
18
receiver.py
@@ -3,12 +3,19 @@ import re
|
|||||||
import requests
|
import requests
|
||||||
from aiosmtpd.controller import Controller
|
from aiosmtpd.controller import Controller
|
||||||
import os
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class CustomHandler:
|
class CustomHandler:
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.domain = os.getenv('MAIL_DOMAIN', 'localhost')
|
self.domain = os.getenv('MAIL_DOMAIN', 'localhost')
|
||||||
self.ping_url = os.getenv('PING_URL', 'https://healthcheck.io/ping/')
|
self.ping_url = os.getenv('PING_URL', 'https://healthcheck.io/ping/')
|
||||||
|
_logger.debug('Mail domain: %s', self.domain)
|
||||||
|
_logger.debug('Mail ping url: %s', self.ping_url)
|
||||||
|
|
||||||
async def handle_DATA(self, server, session, envelope):
|
async def handle_DATA(self, server, session, envelope):
|
||||||
peer = session.peer
|
peer = session.peer
|
||||||
@@ -16,23 +23,28 @@ class CustomHandler:
|
|||||||
rcpt_tos = envelope.rcpt_tos
|
rcpt_tos = envelope.rcpt_tos
|
||||||
data = envelope.content # type: bytes
|
data = envelope.content # type: bytes
|
||||||
for rcpt in rcpt_tos:
|
for rcpt in rcpt_tos:
|
||||||
print(rcpt)
|
_logger.debug('Cecking to address: %s', rcpt)
|
||||||
match = re.match(f'([a-zA-Z-_0-9]+)@{self.domain}', rcpt)
|
match = re.match(f'([a-zA-Z-_0-9]+)@{self.domain}', rcpt)
|
||||||
if match is not None:
|
if match is not None:
|
||||||
|
_logger.debug('match found: %s', rcpt)
|
||||||
found = match
|
found = match
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
_logger.debug('no match found')
|
||||||
return '500 Could not process your message'
|
return '500 Could not process your message'
|
||||||
headers= { 'User-Agent': 'EmailPing from ' + mail_from }
|
headers= { 'User-Agent': 'EmailPing from ' + mail_from }
|
||||||
requests.get(f'{self.ping_url}{match.group(1)}', headers=headers)
|
url = f'{self.ping_url}{match.group(1)}'
|
||||||
|
_logger.info('Calling Ping url: %s for address: %s', url, mail_from)
|
||||||
|
requests.get(url, headers=headers)
|
||||||
return '250 OK'
|
return '250 OK'
|
||||||
|
|
||||||
async def health_check():
|
async def health_check():
|
||||||
ping_url = os.getenv('PING_URL', 'https://healthcheck.io/ping/')
|
ping_url = os.getenv('PING_URL', 'https://healthcheck.io/ping/')
|
||||||
ping_id = os.getenv('PING_ID', '101fcaa8-32c5-4281-936f-330412b7afa4')
|
ping_id = os.getenv('PING_ID', '101fcaa8-32c5-4281-936f-330412b7afa4')
|
||||||
ping_timeout = os.getenv('PING_TIMEOUT', '60')
|
ping_timeout = os.getenv('PING_TIMEOUT', '60')
|
||||||
|
_logger.info('Reporting own health to: %s', f'{ping_url}{ping_id}')
|
||||||
while True:
|
while True:
|
||||||
requests.get(f'{self.ping_url}{ping_id}')
|
requests.get(f'{ping_url}{ping_id}')
|
||||||
await asyncio.sleep(ping_timeout)
|
await asyncio.sleep(ping_timeout)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
Reference in New Issue
Block a user