Configuration files should be more templatable in the standard images #11489
Comments
See also: #11203 (configuration fragments should merge recursively) — though doesn't really address all the points here. |
If the solution to this issue is arbitrary templating (e.g. env vars for any value), in my mind that would also solve the problems the #11203 is trying to solve - e.g. there could be a single config file and the DB connection pool size / worker name / etc settings could be templated in |
one possible method may be to use the same method that mautrix bridges uses, which is just to accept an environment variable for any configuration parameter class Config(BaseBridgeConfig):
def __getitem__(self, key: str) -> Any:
try:
return os.environ[f"MAUTRIX_FACEBOOK_{key.replace('.', '_').upper()}"]
except KeyError:
return super().__getitem__(key) So for some configuration like I think this would be pretty quick to implement, and would make it vastly easier to use docker compose with Synapse, as well as making it viable to version-control the config files without worrying about leaking sensitive secrets. However I suspect this sort of extreme flexibility may lead to many more bugs and user error. For example, what happens if Synapse adds a config that happens to match a common environment variable, like One method is to just add a good prefix like what mautrix does. We could also maintain a whitelist of accepted environment variables, so that it is clear to both developers and users which environment variables can be configured. Though we would have to update the whitelist any time a whitelisted configuration gets renamed. |
This comment has been minimized.
This comment has been minimized.
@benbz, @woojoo666: regarding the ability to specify values for any setting via an env var, see #5518 (comment). In particular, how would you represent a list of listeners, each with their own set of sub-options? At the moment this looks like: listeners:
- port: 8448
type: http
tls: true
resources:
- names: [client, federation]
compress: false
- port: 8008
tls: false
bind_address: ''
type: http
x_forwarded: true
resources:
- names: [client, federation, consent]
compress: false
additional_resources:
"/_matrix/saml2/pick_username":
module: matrix_synapse_saml.pick_username_resource
- port: 9093
type: http
resources:
- names: [replication]
- port: 9000
bind_address: 127.0.0.1
type: manhole
- port: 9111
bind_address: ''
type: replication
- port: 9050
type: metrics And let's take the removal of |
Sorry I missed this question. For my purposes I don't need that level of functionality (though I'm sure if it was available I'd make use of it), I just need simple value substitution. |
an example of what you're envisaging here would be super helpful. |
worker_app: synapse.app.generic_worker
worker_name: <WORKER_IDENTIFIER>
database:
name: psycopg2
args:
application_name: <WORKER_IDENTIFIER>
.... Where |
I'm not really following - or rather, I'd like a more explicit example. Which env vars (plural?) would be used to pass the value to be substitiuted for |
Here is a more fleshed out example using federation senders. Let's say I have a StatefulSet that's named ...
federation_sender_instances:
- federation-sender-0
- federation-sender-1
- federation-sender-2
- federation-sender-3
...
worker_name: federation-sender-0
...
worker_name: federation-sender-1
...
worker_name: federation-sender-2
...
worker_name: federation-sender-3
... However given I know that the hostnames for a 4 replicas would be ...
federation_sender_instances:
- federation-sender-0
- federation-sender-1
- federation-sender-2
- federation-sender-3
...
worker_name: <WORKER_IDENTIFIER>
... Scaling up/down is a question of rewriting the |
An alternative that would negate my particular need for any of this would be:
|
I agree, environment variables aren't the best when good, managed configuration is available. In my case, Docker Swarm doesn't offer a very good managed configuration solution (it can't update existing configs in-place) so I wrote a tool to wrap the synapse image at boot: One big issue I can foresee is arbitrary keys in yaml files, so a |
I just got pointed here - after reading, https://github.com/traefik/traefik jumps right into my mind. They've managed to accept every configuration option in a yaml-file, as command line parameter or as env-var. See their docs - it might need some adaptions here, but it might also be worth a shot. |
Description:
In container driven worlds, when simple templating of a config file is desired, there are a few ways to go about it, but they're not 100% easy to use, for example cases like these require extending the synapse container with scripts or even extra docker containers:
A while ago we were able to provide templating via some fixed environment variables but removed that due to maintenance complexity as everything needed to be a environment variable.
We have the debian system that templates from debconf: https://github.com/matrix-org/synapse/blob/develop/debian/manage_debconf.pl
We currently have the --generate-config option which templates out synapse configuration based on environment variables, but only a limited number of values are supported https://github.com/matrix-org/synapse/blob/develop/docker/start.py#L130 and it relies on being able to write the generated result back out and have it persisted.
We can also currently use a conf.d/ type configuration, and be responsible for writing parts of the config out from different sources, but that gets complicated if the configuration is nested, eg sharing the database password from one source and the database hostname from another requires merging two trees of configuration.
We could create some specific syntax for use in the config file, eg
hostname: "${ENV['POSTGRES_HOST']}"
to allow values to be read from environment variables, which might deal with a lot of the cases - provide a static config file and specify which two or three secrets are to be provided.Or maybe we could get value from loosening up the existing
--generate-config
templating so it could run before every start (so doesn't run and exit) but only templates the configuration files; not the other files it currently makes.We find ourselves repeating these slight configurations in a lot of tiny built images, and I wonder if we could replace them with a single standard templating option.
I'm not sure of the right answer here; but it's currently painful to have to reimplement the templating of synapse config files again and again in each usecase, so creating this issue to see if we can make something simpler here.
The text was updated successfully, but these errors were encountered: