diff --git a/set_app_domain.py b/set_app_domain.py
new file mode 100755
index 0000000000000000000000000000000000000000..0d87cfb116f5dfedc39938f7ffd1099f42311c47
--- /dev/null
+++ b/set_app_domain.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+'''
+Script to set the domain of an existing MS, CM or Monitor
+'''
+import os
+import re
+import subprocess
+import sys
+
+import utils
+from utils import log
+
+
+class SetAppDomain():
+    USAGE = '''%s [-d] [-h] [app] <domain>
+    -d: Debug mode (can be started with non root users).
+    -h: Show this message.
+    app: The application for which the new domain should be set.
+         Possible values:
+           "ms" (MediaServer), "cm" (Campus Manager), "mon" (Monitor).
+         It is possible to specify which MS instance should be targetted
+         by using this format: ms-<instance name> (for example ms-msuser).
+    domain: The new domain.''' % __file__
+    MS_INSTANCE_USER_PATTERN = r'^[a-z0-9\-]+$'
+    NGINX_SERVER_NAME_PATTERN = r'^\s*server_name\s+([\w\-\_\.\ ]+);$'
+
+    def __init__(self, *args):
+        self.display_header()
+        args = list(args)
+        # Check if help is required
+        if '-h' in args:
+            log('USAGE: ' + self.USAGE)
+            sys.exit(0)
+        # Check current dir
+        root_dir = utils.get_dir(__file__)
+        if root_dir != '':
+            os.chdir(root_dir)
+        self.root_dir = root_dir
+        # Add to python path
+        if root_dir not in sys.path:
+            sys.path.append(root_dir)
+        # Check that this script is run by root
+        self.debug = '-d' in args
+        if self.debug:
+            args.remove('-d')
+        whoami = subprocess.check_output(['whoami']).decode('utf-8').strip()
+        if whoami != 'root' and not self.debug:
+            log('This script should be run as root user.')
+            sys.exit(1)
+        # Parse args
+        if not args:
+            log('Not enough arguments.')
+            log('USAGE: ' + self.USAGE)
+            sys.exit(1)
+        new_domain = args.pop()
+        if args:
+            app = args.pop()
+        # Change domain
+        instance = None
+        if app == 'cm':
+            nginx_conf = '/etc/nginx/sites-available/skyreach.conf'
+        elif app == 'mon':
+            nginx_conf = '/etc/nginx/sites-available/msmonitor.conf'
+        elif app == 'ms' or app.startswith('ms-'):
+            if app.startswith('ms-'):
+                instance = app[3:].strip('. -\t\n')
+                if not re.match(self.MS_INSTANCE_USER_PATTERN, instance):
+                    log('Invalid MS instance requested. Validation reg exp is: %s' % self.MS_INSTANCE_USER_PATTERN)
+                    sys.exit(1)
+            else:
+                instance = 'msuser'
+            nginx_conf = '/etc/nginx/sites-available/mediaserver-%s.conf' % instance
+        else:
+            log('Invalid app name requested.')
+            log('USAGE: ' + self.USAGE)
+            sys.exit(1)
+        self.change_nginx_domain(nginx_conf, new_domain)
+        if instance:
+            self.change_ms_instance_domain(instance, new_domain)
+        sys.exit(0)
+
+    def change_nginx_domain(self, path, new_domain):
+        log('Checking Nginx configuration file "%s".' % path)
+        if not os.path.exists(path):
+            log('The configuration file does not exist.')
+            sys.exit(1)
+        with open(path, 'r') as fo:
+            vhost = fo.read()
+        new_vhost = ''
+        for line in vhost.split('\n'):
+            if re.match(self.NGINX_SERVER_NAME_PATTERN, line):
+                new_vhost += re.sub(self.NGINX_SERVER_NAME_PATTERN, line, new_domain) + '\n'
+            else:
+                new_vhost += line + '\n'
+        new_vhost = new_vhost.strip() + '\n'
+        if new_vhost != vhost:
+            if self.debug:
+                log('New Nginx conf:')
+                log(new_vhost)
+            else:
+                with open(path, 'w') as fo:
+                    fo.write(new_vhost)
+                log('The configuration file "%s" has been update.' % path)
+        else:
+            log('The configuration file "%s" is already up to date.' % path)
+
+    def change_ms_instance_domain(self, instance, new_domain):
+        # TODO: set MS url in site settings
+        # TODO: reset all local resources managers
+        try:
+            utils.run_commands(['sudo su %s -c "ls"' % instance])
+        except Exception as e:
+            log('Unable to set MS domain:\n%s' % e)
+            sys.exit(1)
+        else:
+            log('MS domain changed')
+
+
+if __name__ == '__main__':
+    SetAppDomain(*sys.argv[1:])