public
nobgit
read
NobMail
Based on mailcow: dockerized
Languages
Repository composition by tracked source files.
PHP
49%
JavaScript
35%
HTML
9%
CSS
4%
Shell
2%
Python
1%
Lua
0%
Perl
0%
Ruby
0%
SCSS
0%
Create file
Wiki Documentation
Clone
https://nobgit.com/orgs/nobgit/nobmail.git
ssh://[email protected]:2222/orgs/nobgit/nobmail.git
Commit
[Rspamd] Echo dummy for fowardingshosts map; Use higher map reading interval; [Dockerapi] Exit on sigterm; [Watchdog] Wait for dockerapi-mailcow to be online
1e9bc49f
data/Dockerfiles/dockerapi/server.py | 105 ++++++++++++++++-----------
data/Dockerfiles/watchdog/watchdog.sh | 16 ++++
data/conf/rspamd/dynmaps/forwardinghosts.php | 4 +-
data/conf/rspamd/local.d/options.inc | 2 +-
docker-compose.yml | 6 +-
5 files changed, 88 insertions(+), 45 deletions(-)
Diff
diff --git a/data/Dockerfiles/dockerapi/server.py b/data/Dockerfiles/dockerapi/server.py
index a021ab54..aabcaf31 100644
--- a/data/Dockerfiles/dockerapi/server.py
+++ b/data/Dockerfiles/dockerapi/server.py
@@ -1,62 +1,85 @@
from flask import Flask
from flask_restful import Resource, Api
from flask import jsonify
+from threading import Thread
import docker
+import signal
+import time
docker_client = docker.DockerClient(base_url='unix://var/run/docker.sock')
app = Flask(__name__)
api = Api(app)
class containers_get(Resource):
- def get(self):
- containers = {}
- for container in docker_client.containers.list(all=True):
- containers.update({container.attrs['Id']: container.attrs})
- return containers
+ def get(self):
+ containers = {}
+ for container in docker_client.containers.list(all=True):
+ containers.update({container.attrs['Id']: container.attrs})
+ return containers
class container_get(Resource):
- def get(self, container_id):
- if container_id and container_id.isalnum():
- for container in docker_client.containers.list(all=True, filters={"id": container_id}):
- return container.attrs
- else:
- return jsonify(message='No or invalid id defined')
+ def get(self, container_id):
+ if container_id and container_id.isalnum():
+ for container in docker_client.containers.list(all=True, filters={"id": container_id}):
+ return container.attrs
+ else:
+ return jsonify(message='No or invalid id defined')
class container_post(Resource):
- def post(self, container_id, post_action):
- if container_id and container_id.isalnum() and post_action:
- if post_action == 'stop':
- try:
- for container in docker_client.containers.list(all=True, filters={"id": container_id}):
- container.stop()
- except:
- return 'Error'
- else:
- return 'OK'
- elif post_action == 'start':
- try:
- for container in docker_client.containers.list(all=True, filters={"id": container_id}):
- container.start()
- except:
- return 'Error'
- else:
- return 'OK'
- elif post_action == 'restart':
- try:
- for container in docker_client.containers.list(all=True, filters={"id": container_id}):
- container.restart()
- except:
- return 'Error'
- else:
- return 'OK'
- else:
- return jsonify(message='Invalid action')
+ def post(self, container_id, post_action):
+ if container_id and container_id.isalnum() and post_action:
+ if post_action == 'stop':
+ try:
+ for container in docker_client.containers.list(all=True, filters={"id": container_id}):
+ container.stop()
+ except:
+ return 'Error'
+ else:
+ return 'OK'
+ elif post_action == 'start':
+ try:
+ for container in docker_client.containers.list(all=True, filters={"id": container_id}):
+ container.start()
+ except:
+ return 'Error'
+ else:
+ return 'OK'
+ elif post_action == 'restart':
+ try:
+ for container in docker_client.containers.list(all=True, filters={"id": container_id}):
+ container.restart()
+ except:
+ return 'Error'
else:
- return jsonify(message='Invalid container id or missing action')
+ return 'OK'
+ else:
+ return jsonify(message='Invalid action')
+ else:
+ return jsonify(message='Invalid container id or missing action')
+
+class GracefulKiller:
+ kill_now = False
+ def __init__(self):
+ signal.signal(signal.SIGINT, self.exit_gracefully)
+ signal.signal(signal.SIGTERM, self.exit_gracefully)
+
+ def exit_gracefully(self,signum, frame):
+ self.kill_now = True
+
+def startFlaskAPI():
+ app.run(debug=False, host='0.0.0.0', port='8080', threaded=True)
api.add_resource(containers_get, '/containers/json')
api.add_resource(container_get, '/containers/<string:container_id>/json')
api.add_resource(container_post, '/containers/<string:container_id>/<string:post_action>')
if __name__ == '__main__':
- app.run(debug=False, host='0.0.0.0', port='8080')
+ api_thread = Thread(target=startFlaskAPI)
+ api_thread.daemon = True
+ api_thread.start()
+ killer = GracefulKiller()
+ while True:
+ time.sleep(1)
+ if killer.kill_now:
+ break
+ print "Stopping dockerapi-mailcow"
diff --git a/data/Dockerfiles/watchdog/watchdog.sh b/data/Dockerfiles/watchdog/watchdog.sh
index 470025de..d7351936 100755
--- a/data/Dockerfiles/watchdog/watchdog.sh
+++ b/data/Dockerfiles/watchdog/watchdog.sh
@@ -360,6 +360,22 @@ while true; do
done
) &
+# Monitor dockerapi
+(
+while true; do
+ while nc -z dockerapi 8080; do
+ sleep 3
+ done
+ echo "Cannot find dockerapi-mailcow, waiting to recover..."
+ kill -STOP ${BACKGROUND_TASKS[*]}
+ until nc -z dockerapi 8080; do
+ sleep 3
+ done
+ kill -CONT ${BACKGROUND_TASKS[*]}
+ kill -USR1 ${BACKGROUND_TASKS[*]}
+done
+) &
+
# Restart container when threshold limit reached
while true; do
CONTAINER_ID=
diff --git a/data/conf/rspamd/dynmaps/forwardinghosts.php b/data/conf/rspamd/dynmaps/forwardinghosts.php
index 522a21f9..10285b71 100644
--- a/data/conf/rspamd/dynmaps/forwardinghosts.php
+++ b/data/conf/rspamd/dynmaps/forwardinghosts.php
@@ -44,11 +44,13 @@ if (isset($_GET['host'])) {
}
} else {
try {
+ echo '240.240.240.240' . PHP_EOL;
foreach ($redis->hGetAll('WHITELISTED_FWD_HOST') as $host => $source) {
- echo $host . "\n";
+ echo $host . PHP_EOL;
}
}
catch (RedisException $e) {
+ echo '240.240.240.240' . PHP_EOL;
exit;
}
}
diff --git a/data/conf/rspamd/local.d/options.inc b/data/conf/rspamd/local.d/options.inc
index bb940b3f..09117984 100644
--- a/data/conf/rspamd/local.d/options.inc
+++ b/data/conf/rspamd/local.d/options.inc
@@ -1,7 +1,7 @@
dns {
enable_dnssec = true;
}
-map_watch_interval = 15s;
+map_watch_interval = 60s;
dns {
timeout = 4s;
retransmits = 5;
diff --git a/docker-compose.yml b/docker-compose.yml
index 56f8459c..ae908b1f 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -215,12 +215,14 @@ services:
depends_on:
- sogo-mailcow
- php-fpm-mailcow
+ - redis-mailcow
image: nginx:mainline-alpine
command: /bin/sh -c "envsubst < /etc/nginx/conf.d/templates/listen_plain.template > /etc/nginx/conf.d/listen_plain.active &&
envsubst < /etc/nginx/conf.d/templates/listen_ssl.template > /etc/nginx/conf.d/listen_ssl.active &&
envsubst < /etc/nginx/conf.d/templates/server_name.template > /etc/nginx/conf.d/server_name.active &&
nginx -qt &&
until ping phpfpm -c1 > /dev/null; do sleep 1; done &&
+ until ping redis -c1 > /dev/null; do sleep 1; done &&
exec nginx -g 'daemon off;'"
environment:
- HTTPS_PORT=${HTTPS_PORT:-443}
@@ -291,7 +293,7 @@ services:
- /lib/modules:/lib/modules:ro
watchdog-mailcow:
- image: mailcow/watchdog:1.8
+ image: mailcow/watchdog:1.9
build: ./data/Dockerfiles/watchdog
volumes:
- vmail-vol-1:/vmail:ro
@@ -310,7 +312,7 @@ services:
- watchdog
dockerapi-mailcow:
- image: mailcow/dockerapi:1.0
+ image: mailcow/dockerapi:1.1
stop_grace_period: 3s
build: ./data/Dockerfiles/dockerapi
volumes: