We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Deprecate the env-var way of running under docker
We've decided to stop supporting the configuration of synapse via environment variables.

The main reason for this is that you're bound to end up needing to do more things than it's possible to do with the environment variables, and the incomplete support leads to problems like #5430.

An alternative might have been to make it genuinely possible to configure everything via environment variables in some consistent fashion, but that sounds hard and more work than we're able to do.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `docker/start.py`
Content:
```
1 #!/usr/local/bin/python
2 
3 import codecs
4 import glob
5 import os
6 import subprocess
7 import sys
8 
9 import jinja2
10 
11 
12 # Utility functions
13 def log(txt):
14     print(txt, file=sys.stderr)
15 
16 
17 def error(txt):
18     log(txt)
19     sys.exit(2)
20 
21 
22 def convert(src, dst, environ):
23     """Generate a file from a template
24 
25     Args:
26         src (str): path to input file
27         dst (str): path to file to write
28         environ (dict): environment dictionary, for replacement mappings.
29     """
30     with open(src) as infile:
31         template = infile.read()
32     rendered = jinja2.Template(template).render(**environ)
33     with open(dst, "w") as outfile:
34         outfile.write(rendered)
35 
36 
37 def generate_config_from_template(environ, ownership):
38     """Generate a homeserver.yaml from environment variables
39 
40     Args:
41         environ (dict): environment dictionary
42         ownership (str): "<user>:<group>" string which will be used to set
43             ownership of the generated configs
44 
45     Returns:
46         path to generated config file
47     """
48     for v in ("SYNAPSE_SERVER_NAME", "SYNAPSE_REPORT_STATS"):
49         if v not in environ:
50             error(
51                 "Environment variable '%s' is mandatory when generating a config "
52                 "file on-the-fly." % (v,)
53             )
54 
55     # populate some params from data files (if they exist, else create new ones)
56     environ = environ.copy()
57     secrets = {
58         "registration": "SYNAPSE_REGISTRATION_SHARED_SECRET",
59         "macaroon": "SYNAPSE_MACAROON_SECRET_KEY",
60     }
61 
62     for name, secret in secrets.items():
63         if secret not in environ:
64             filename = "/data/%s.%s.key" % (environ["SYNAPSE_SERVER_NAME"], name)
65 
66             # if the file already exists, load in the existing value; otherwise,
67             # generate a new secret and write it to a file
68 
69             if os.path.exists(filename):
70                 log("Reading %s from %s" % (secret, filename))
71                 with open(filename) as handle:
72                     value = handle.read()
73             else:
74                 log("Generating a random secret for {}".format(secret))
75                 value = codecs.encode(os.urandom(32), "hex").decode()
76                 with open(filename, "w") as handle:
77                     handle.write(value)
78             environ[secret] = value
79 
80     environ["SYNAPSE_APPSERVICES"] = glob.glob("/data/appservices/*.yaml")
81     if not os.path.exists("/compiled"):
82         os.mkdir("/compiled")
83 
84     config_path = "/compiled/homeserver.yaml"
85 
86     # Convert SYNAPSE_NO_TLS to boolean if exists
87     if "SYNAPSE_NO_TLS" in environ:
88         tlsanswerstring = str.lower(environ["SYNAPSE_NO_TLS"])
89         if tlsanswerstring in ("true", "on", "1", "yes"):
90             environ["SYNAPSE_NO_TLS"] = True
91         else:
92             if tlsanswerstring in ("false", "off", "0", "no"):
93                 environ["SYNAPSE_NO_TLS"] = False
94             else:
95                 error(
96                     'Environment variable "SYNAPSE_NO_TLS" found but value "'
97                     + tlsanswerstring
98                     + '" unrecognized; exiting.'
99                 )
100 
101     convert("/conf/homeserver.yaml", config_path, environ)
102     convert("/conf/log.config", "/compiled/log.config", environ)
103     subprocess.check_output(["chown", "-R", ownership, "/data"])
104 
105     # Hopefully we already have a signing key, but generate one if not.
106     subprocess.check_output(
107         [
108             "su-exec",
109             ownership,
110             "python",
111             "-m",
112             "synapse.app.homeserver",
113             "--config-path",
114             config_path,
115             # tell synapse to put generated keys in /data rather than /compiled
116             "--keys-directory",
117             "/data",
118             "--generate-keys",
119         ]
120     )
121 
122     return config_path
123 
124 
125 def run_generate_config(environ, ownership):
126     """Run synapse with a --generate-config param to generate a template config file
127 
128     Args:
129         environ (dict): env var dict
130         ownership (str): "userid:groupid" arg for chmod
131 
132     Never returns.
133     """
134     for v in ("SYNAPSE_SERVER_NAME", "SYNAPSE_REPORT_STATS", "SYNAPSE_CONFIG_PATH"):
135         if v not in environ:
136             error("Environment variable '%s' is mandatory in `generate` mode." % (v,))
137 
138     server_name = environ["SYNAPSE_SERVER_NAME"]
139     config_dir = environ.get("SYNAPSE_CONFIG_DIR", "/data")
140     data_dir = environ.get("SYNAPSE_DATA_DIR", "/data")
141 
142     # create a suitable log config from our template
143     log_config_file = "%s/%s.log.config" % (config_dir, server_name)
144     if not os.path.exists(log_config_file):
145         log("Creating log config %s" % (log_config_file,))
146         convert("/conf/log.config", log_config_file, environ)
147 
148     # make sure that synapse has perms to write to the data dir.
149     subprocess.check_output(["chown", ownership, data_dir])
150 
151     args = [
152         "python",
153         "-m",
154         "synapse.app.homeserver",
155         "--server-name",
156         server_name,
157         "--report-stats",
158         environ["SYNAPSE_REPORT_STATS"],
159         "--config-path",
160         environ["SYNAPSE_CONFIG_PATH"],
161         "--config-directory",
162         config_dir,
163         "--data-directory",
164         data_dir,
165         "--generate-config",
166     ]
167     # log("running %s" % (args, ))
168     os.execv("/usr/local/bin/python", args)
169 
170 
171 def main(args, environ):
172     mode = args[1] if len(args) > 1 else None
173     ownership = "{}:{}".format(environ.get("UID", 991), environ.get("GID", 991))
174 
175     # In generate mode, generate a configuration and missing keys, then exit
176     if mode == "generate":
177         return run_generate_config(environ, ownership)
178 
179     # In normal mode, generate missing keys if any, then run synapse
180     if "SYNAPSE_CONFIG_PATH" in environ:
181         config_path = environ["SYNAPSE_CONFIG_PATH"]
182     else:
183         config_path = generate_config_from_template(environ, ownership)
184 
185     args = [
186         "su-exec",
187         ownership,
188         "python",
189         "-m",
190         "synapse.app.homeserver",
191         "--config-path",
192         config_path,
193     ]
194     os.execv("/sbin/su-exec", args)
195 
196 
197 if __name__ == "__main__":
198     main(sys.argv, os.environ)
199
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/docker/start.py b/docker/start.py
--- a/docker/start.py
+++ b/docker/start.py
@@ -131,12 +131,13 @@
 
     Never returns.
     """
-    for v in ("SYNAPSE_SERVER_NAME", "SYNAPSE_REPORT_STATS", "SYNAPSE_CONFIG_PATH"):
+    for v in ("SYNAPSE_SERVER_NAME", "SYNAPSE_REPORT_STATS"):
         if v not in environ:
             error("Environment variable '%s' is mandatory in `generate` mode." % (v,))
 
     server_name = environ["SYNAPSE_SERVER_NAME"]
     config_dir = environ.get("SYNAPSE_CONFIG_DIR", "/data")
+    config_path = environ.get("SYNAPSE_CONFIG_PATH", config_dir + "/homeserver.yaml")
     data_dir = environ.get("SYNAPSE_DATA_DIR", "/data")
 
     # create a suitable log config from our template
@@ -157,7 +158,7 @@
         "--report-stats",
         environ["SYNAPSE_REPORT_STATS"],
         "--config-path",
-        environ["SYNAPSE_CONFIG_PATH"],
+        config_path,
         "--config-directory",
         config_dir,
         "--data-directory",
@@ -176,11 +177,30 @@
     if mode == "generate":
         return run_generate_config(environ, ownership)
 
-    # In normal mode, generate missing keys if any, then run synapse
-    if "SYNAPSE_CONFIG_PATH" in environ:
-        config_path = environ["SYNAPSE_CONFIG_PATH"]
-    else:
+    if "SYNAPSE_SERVER_NAME" in environ:
+        # backwards-compatibility generate-a-config-on-the-fly mode
+        if "SYNAPSE_CONFIG_PATH" in environ:
+            error(
+                "SYNAPSE_SERVER_NAME and SYNAPSE_CONFIG_PATH are mutually exclusive "
+                "except in `generate` mode."
+            )
+
         config_path = generate_config_from_template(environ, ownership)
+    else:
+        config_dir = environ.get("SYNAPSE_CONFIG_DIR", "/data")
+        config_path = environ.get(
+            "SYNAPSE_CONFIG_PATH", config_dir + "/homeserver.yaml"
+        )
+        if not os.path.exists(config_path):
+            error(
+                "Config file '%s' does not exist. You should either create a new "
+                "config file by running with the `generate` argument (and then edit "
+                "the resulting file before restarting) or specify the path to an "
+                "existing config file with the SYNAPSE_CONFIG_PATH variable."
+                % (config_path,)
+            )
+
+    log("Starting synapse with config file " + config_path)
 
     args = [
         "su-exec",

{"golden_diff": "diff --git a/docker/start.py b/docker/start.py\n--- a/docker/start.py\n+++ b/docker/start.py\n@@ -131,12 +131,13 @@\n \n     Never returns.\n     \"\"\"\n-    for v in (\"SYNAPSE_SERVER_NAME\", \"SYNAPSE_REPORT_STATS\", \"SYNAPSE_CONFIG_PATH\"):\n+    for v in (\"SYNAPSE_SERVER_NAME\", \"SYNAPSE_REPORT_STATS\"):\n         if v not in environ:\n             error(\"Environment variable '%s' is mandatory in `generate` mode.\" % (v,))\n \n     server_name = environ[\"SYNAPSE_SERVER_NAME\"]\n     config_dir = environ.get(\"SYNAPSE_CONFIG_DIR\", \"/data\")\n+    config_path = environ.get(\"SYNAPSE_CONFIG_PATH\", config_dir + \"/homeserver.yaml\")\n     data_dir = environ.get(\"SYNAPSE_DATA_DIR\", \"/data\")\n \n     # create a suitable log config from our template\n@@ -157,7 +158,7 @@\n         \"--report-stats\",\n         environ[\"SYNAPSE_REPORT_STATS\"],\n         \"--config-path\",\n-        environ[\"SYNAPSE_CONFIG_PATH\"],\n+        config_path,\n         \"--config-directory\",\n         config_dir,\n         \"--data-directory\",\n@@ -176,11 +177,30 @@\n     if mode == \"generate\":\n         return run_generate_config(environ, ownership)\n \n-    # In normal mode, generate missing keys if any, then run synapse\n-    if \"SYNAPSE_CONFIG_PATH\" in environ:\n-        config_path = environ[\"SYNAPSE_CONFIG_PATH\"]\n-    else:\n+    if \"SYNAPSE_SERVER_NAME\" in environ:\n+        # backwards-compatibility generate-a-config-on-the-fly mode\n+        if \"SYNAPSE_CONFIG_PATH\" in environ:\n+            error(\n+                \"SYNAPSE_SERVER_NAME and SYNAPSE_CONFIG_PATH are mutually exclusive \"\n+                \"except in `generate` mode.\"\n+            )\n+\n         config_path = generate_config_from_template(environ, ownership)\n+    else:\n+        config_dir = environ.get(\"SYNAPSE_CONFIG_DIR\", \"/data\")\n+        config_path = environ.get(\n+            \"SYNAPSE_CONFIG_PATH\", config_dir + \"/homeserver.yaml\"\n+        )\n+        if not os.path.exists(config_path):\n+            error(\n+                \"Config file '%s' does not exist. You should either create a new \"\n+                \"config file by running with the `generate` argument (and then edit \"\n+                \"the resulting file before restarting) or specify the path to an \"\n+                \"existing config file with the SYNAPSE_CONFIG_PATH variable.\"\n+                % (config_path,)\n+            )\n+\n+    log(\"Starting synapse with config file \" + config_path)\n \n     args = [\n         \"su-exec\",\n", "issue": "Deprecate the env-var way of running under docker\nWe've decided to stop supporting the configuration of synapse via environment variables.\r\n\r\nThe main reason for this is that you're bound to end up needing to do more things than it's possible to do with the environment variables, and the incomplete support leads to problems like #5430.\r\n\r\nAn alternative might have been to make it genuinely possible to configure everything via environment variables in some consistent fashion, but that sounds hard and more work than we're able to do.\n", "before_files": [{"content": "#!/usr/local/bin/python\n\nimport codecs\nimport glob\nimport os\nimport subprocess\nimport sys\n\nimport jinja2\n\n\n# Utility functions\ndef log(txt):\n    print(txt, file=sys.stderr)\n\n\ndef error(txt):\n    log(txt)\n    sys.exit(2)\n\n\ndef convert(src, dst, environ):\n    \"\"\"Generate a file from a template\n\n    Args:\n        src (str): path to input file\n        dst (str): path to file to write\n        environ (dict): environment dictionary, for replacement mappings.\n    \"\"\"\n    with open(src) as infile:\n        template = infile.read()\n    rendered = jinja2.Template(template).render(**environ)\n    with open(dst, \"w\") as outfile:\n        outfile.write(rendered)\n\n\ndef generate_config_from_template(environ, ownership):\n    \"\"\"Generate a homeserver.yaml from environment variables\n\n    Args:\n        environ (dict): environment dictionary\n        ownership (str): \"<user>:<group>\" string which will be used to set\n            ownership of the generated configs\n\n    Returns:\n        path to generated config file\n    \"\"\"\n    for v in (\"SYNAPSE_SERVER_NAME\", \"SYNAPSE_REPORT_STATS\"):\n        if v not in environ:\n            error(\n                \"Environment variable '%s' is mandatory when generating a config \"\n                \"file on-the-fly.\" % (v,)\n            )\n\n    # populate some params from data files (if they exist, else create new ones)\n    environ = environ.copy()\n    secrets = {\n        \"registration\": \"SYNAPSE_REGISTRATION_SHARED_SECRET\",\n        \"macaroon\": \"SYNAPSE_MACAROON_SECRET_KEY\",\n    }\n\n    for name, secret in secrets.items():\n        if secret not in environ:\n            filename = \"/data/%s.%s.key\" % (environ[\"SYNAPSE_SERVER_NAME\"], name)\n\n            # if the file already exists, load in the existing value; otherwise,\n            # generate a new secret and write it to a file\n\n            if os.path.exists(filename):\n                log(\"Reading %s from %s\" % (secret, filename))\n                with open(filename) as handle:\n                    value = handle.read()\n            else:\n                log(\"Generating a random secret for {}\".format(secret))\n                value = codecs.encode(os.urandom(32), \"hex\").decode()\n                with open(filename, \"w\") as handle:\n                    handle.write(value)\n            environ[secret] = value\n\n    environ[\"SYNAPSE_APPSERVICES\"] = glob.glob(\"/data/appservices/*.yaml\")\n    if not os.path.exists(\"/compiled\"):\n        os.mkdir(\"/compiled\")\n\n    config_path = \"/compiled/homeserver.yaml\"\n\n    # Convert SYNAPSE_NO_TLS to boolean if exists\n    if \"SYNAPSE_NO_TLS\" in environ:\n        tlsanswerstring = str.lower(environ[\"SYNAPSE_NO_TLS\"])\n        if tlsanswerstring in (\"true\", \"on\", \"1\", \"yes\"):\n            environ[\"SYNAPSE_NO_TLS\"] = True\n        else:\n            if tlsanswerstring in (\"false\", \"off\", \"0\", \"no\"):\n                environ[\"SYNAPSE_NO_TLS\"] = False\n            else:\n                error(\n                    'Environment variable \"SYNAPSE_NO_TLS\" found but value \"'\n                    + tlsanswerstring\n                    + '\" unrecognized; exiting.'\n                )\n\n    convert(\"/conf/homeserver.yaml\", config_path, environ)\n    convert(\"/conf/log.config\", \"/compiled/log.config\", environ)\n    subprocess.check_output([\"chown\", \"-R\", ownership, \"/data\"])\n\n    # Hopefully we already have a signing key, but generate one if not.\n    subprocess.check_output(\n        [\n            \"su-exec\",\n            ownership,\n            \"python\",\n            \"-m\",\n            \"synapse.app.homeserver\",\n            \"--config-path\",\n            config_path,\n            # tell synapse to put generated keys in /data rather than /compiled\n            \"--keys-directory\",\n            \"/data\",\n            \"--generate-keys\",\n        ]\n    )\n\n    return config_path\n\n\ndef run_generate_config(environ, ownership):\n    \"\"\"Run synapse with a --generate-config param to generate a template config file\n\n    Args:\n        environ (dict): env var dict\n        ownership (str): \"userid:groupid\" arg for chmod\n\n    Never returns.\n    \"\"\"\n    for v in (\"SYNAPSE_SERVER_NAME\", \"SYNAPSE_REPORT_STATS\", \"SYNAPSE_CONFIG_PATH\"):\n        if v not in environ:\n            error(\"Environment variable '%s' is mandatory in `generate` mode.\" % (v,))\n\n    server_name = environ[\"SYNAPSE_SERVER_NAME\"]\n    config_dir = environ.get(\"SYNAPSE_CONFIG_DIR\", \"/data\")\n    data_dir = environ.get(\"SYNAPSE_DATA_DIR\", \"/data\")\n\n    # create a suitable log config from our template\n    log_config_file = \"%s/%s.log.config\" % (config_dir, server_name)\n    if not os.path.exists(log_config_file):\n        log(\"Creating log config %s\" % (log_config_file,))\n        convert(\"/conf/log.config\", log_config_file, environ)\n\n    # make sure that synapse has perms to write to the data dir.\n    subprocess.check_output([\"chown\", ownership, data_dir])\n\n    args = [\n        \"python\",\n        \"-m\",\n        \"synapse.app.homeserver\",\n        \"--server-name\",\n        server_name,\n        \"--report-stats\",\n        environ[\"SYNAPSE_REPORT_STATS\"],\n        \"--config-path\",\n        environ[\"SYNAPSE_CONFIG_PATH\"],\n        \"--config-directory\",\n        config_dir,\n        \"--data-directory\",\n        data_dir,\n        \"--generate-config\",\n    ]\n    # log(\"running %s\" % (args, ))\n    os.execv(\"/usr/local/bin/python\", args)\n\n\ndef main(args, environ):\n    mode = args[1] if len(args) > 1 else None\n    ownership = \"{}:{}\".format(environ.get(\"UID\", 991), environ.get(\"GID\", 991))\n\n    # In generate mode, generate a configuration and missing keys, then exit\n    if mode == \"generate\":\n        return run_generate_config(environ, ownership)\n\n    # In normal mode, generate missing keys if any, then run synapse\n    if \"SYNAPSE_CONFIG_PATH\" in environ:\n        config_path = environ[\"SYNAPSE_CONFIG_PATH\"]\n    else:\n        config_path = generate_config_from_template(environ, ownership)\n\n    args = [\n        \"su-exec\",\n        ownership,\n        \"python\",\n        \"-m\",\n        \"synapse.app.homeserver\",\n        \"--config-path\",\n        config_path,\n    ]\n    os.execv(\"/sbin/su-exec\", args)\n\n\nif __name__ == \"__main__\":\n    main(sys.argv, os.environ)\n", "path": "docker/start.py"}], "after_files": [{"content": "#!/usr/local/bin/python\n\nimport codecs\nimport glob\nimport os\nimport subprocess\nimport sys\n\nimport jinja2\n\n\n# Utility functions\ndef log(txt):\n    print(txt, file=sys.stderr)\n\n\ndef error(txt):\n    log(txt)\n    sys.exit(2)\n\n\ndef convert(src, dst, environ):\n    \"\"\"Generate a file from a template\n\n    Args:\n        src (str): path to input file\n        dst (str): path to file to write\n        environ (dict): environment dictionary, for replacement mappings.\n    \"\"\"\n    with open(src) as infile:\n        template = infile.read()\n    rendered = jinja2.Template(template).render(**environ)\n    with open(dst, \"w\") as outfile:\n        outfile.write(rendered)\n\n\ndef generate_config_from_template(environ, ownership):\n    \"\"\"Generate a homeserver.yaml from environment variables\n\n    Args:\n        environ (dict): environment dictionary\n        ownership (str): \"<user>:<group>\" string which will be used to set\n            ownership of the generated configs\n\n    Returns:\n        path to generated config file\n    \"\"\"\n    for v in (\"SYNAPSE_SERVER_NAME\", \"SYNAPSE_REPORT_STATS\"):\n        if v not in environ:\n            error(\n                \"Environment variable '%s' is mandatory when generating a config \"\n                \"file on-the-fly.\" % (v,)\n            )\n\n    # populate some params from data files (if they exist, else create new ones)\n    environ = environ.copy()\n    secrets = {\n        \"registration\": \"SYNAPSE_REGISTRATION_SHARED_SECRET\",\n        \"macaroon\": \"SYNAPSE_MACAROON_SECRET_KEY\",\n    }\n\n    for name, secret in secrets.items():\n        if secret not in environ:\n            filename = \"/data/%s.%s.key\" % (environ[\"SYNAPSE_SERVER_NAME\"], name)\n\n            # if the file already exists, load in the existing value; otherwise,\n            # generate a new secret and write it to a file\n\n            if os.path.exists(filename):\n                log(\"Reading %s from %s\" % (secret, filename))\n                with open(filename) as handle:\n                    value = handle.read()\n            else:\n                log(\"Generating a random secret for {}\".format(secret))\n                value = codecs.encode(os.urandom(32), \"hex\").decode()\n                with open(filename, \"w\") as handle:\n                    handle.write(value)\n            environ[secret] = value\n\n    environ[\"SYNAPSE_APPSERVICES\"] = glob.glob(\"/data/appservices/*.yaml\")\n    if not os.path.exists(\"/compiled\"):\n        os.mkdir(\"/compiled\")\n\n    config_path = \"/compiled/homeserver.yaml\"\n\n    # Convert SYNAPSE_NO_TLS to boolean if exists\n    if \"SYNAPSE_NO_TLS\" in environ:\n        tlsanswerstring = str.lower(environ[\"SYNAPSE_NO_TLS\"])\n        if tlsanswerstring in (\"true\", \"on\", \"1\", \"yes\"):\n            environ[\"SYNAPSE_NO_TLS\"] = True\n        else:\n            if tlsanswerstring in (\"false\", \"off\", \"0\", \"no\"):\n                environ[\"SYNAPSE_NO_TLS\"] = False\n            else:\n                error(\n                    'Environment variable \"SYNAPSE_NO_TLS\" found but value \"'\n                    + tlsanswerstring\n                    + '\" unrecognized; exiting.'\n                )\n\n    convert(\"/conf/homeserver.yaml\", config_path, environ)\n    convert(\"/conf/log.config\", \"/compiled/log.config\", environ)\n    subprocess.check_output([\"chown\", \"-R\", ownership, \"/data\"])\n\n    # Hopefully we already have a signing key, but generate one if not.\n    subprocess.check_output(\n        [\n            \"su-exec\",\n            ownership,\n            \"python\",\n            \"-m\",\n            \"synapse.app.homeserver\",\n            \"--config-path\",\n            config_path,\n            # tell synapse to put generated keys in /data rather than /compiled\n            \"--keys-directory\",\n            \"/data\",\n            \"--generate-keys\",\n        ]\n    )\n\n    return config_path\n\n\ndef run_generate_config(environ, ownership):\n    \"\"\"Run synapse with a --generate-config param to generate a template config file\n\n    Args:\n        environ (dict): env var dict\n        ownership (str): \"userid:groupid\" arg for chmod\n\n    Never returns.\n    \"\"\"\n    for v in (\"SYNAPSE_SERVER_NAME\", \"SYNAPSE_REPORT_STATS\"):\n        if v not in environ:\n            error(\"Environment variable '%s' is mandatory in `generate` mode.\" % (v,))\n\n    server_name = environ[\"SYNAPSE_SERVER_NAME\"]\n    config_dir = environ.get(\"SYNAPSE_CONFIG_DIR\", \"/data\")\n    config_path = environ.get(\"SYNAPSE_CONFIG_PATH\", config_dir + \"/homeserver.yaml\")\n    data_dir = environ.get(\"SYNAPSE_DATA_DIR\", \"/data\")\n\n    # create a suitable log config from our template\n    log_config_file = \"%s/%s.log.config\" % (config_dir, server_name)\n    if not os.path.exists(log_config_file):\n        log(\"Creating log config %s\" % (log_config_file,))\n        convert(\"/conf/log.config\", log_config_file, environ)\n\n    # make sure that synapse has perms to write to the data dir.\n    subprocess.check_output([\"chown\", ownership, data_dir])\n\n    args = [\n        \"python\",\n        \"-m\",\n        \"synapse.app.homeserver\",\n        \"--server-name\",\n        server_name,\n        \"--report-stats\",\n        environ[\"SYNAPSE_REPORT_STATS\"],\n        \"--config-path\",\n        config_path,\n        \"--config-directory\",\n        config_dir,\n        \"--data-directory\",\n        data_dir,\n        \"--generate-config\",\n    ]\n    # log(\"running %s\" % (args, ))\n    os.execv(\"/usr/local/bin/python\", args)\n\n\ndef main(args, environ):\n    mode = args[1] if len(args) > 1 else None\n    ownership = \"{}:{}\".format(environ.get(\"UID\", 991), environ.get(\"GID\", 991))\n\n    # In generate mode, generate a configuration and missing keys, then exit\n    if mode == \"generate\":\n        return run_generate_config(environ, ownership)\n\n    if \"SYNAPSE_SERVER_NAME\" in environ:\n        # backwards-compatibility generate-a-config-on-the-fly mode\n        if \"SYNAPSE_CONFIG_PATH\" in environ:\n            error(\n                \"SYNAPSE_SERVER_NAME and SYNAPSE_CONFIG_PATH are mutually exclusive \"\n                \"except in `generate` mode.\"\n            )\n\n        config_path = generate_config_from_template(environ, ownership)\n    else:\n        config_dir = environ.get(\"SYNAPSE_CONFIG_DIR\", \"/data\")\n        config_path = environ.get(\n            \"SYNAPSE_CONFIG_PATH\", config_dir + \"/homeserver.yaml\"\n        )\n        if not os.path.exists(config_path):\n            error(\n                \"Config file '%s' does not exist. You should either create a new \"\n                \"config file by running with the `generate` argument (and then edit \"\n                \"the resulting file before restarting) or specify the path to an \"\n                \"existing config file with the SYNAPSE_CONFIG_PATH variable.\"\n                % (config_path,)\n            )\n\n    log(\"Starting synapse with config file \" + config_path)\n\n    args = [\n        \"su-exec\",\n        ownership,\n        \"python\",\n        \"-m\",\n        \"synapse.app.homeserver\",\n        \"--config-path\",\n        config_path,\n    ]\n    os.execv(\"/sbin/su-exec\", args)\n\n\nif __name__ == \"__main__\":\n    main(sys.argv, os.environ)\n", "path": "docker/start.py"}]}