-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
extends
on a service from a file with include
#12533
Comments
Real-world exampleThis should better illustrate what I attempted to do, although this won't work as-is. I link two references of earlier less granular approaches (that do work) at the end of this response. # includes/base.yaml
services:
dms:
image: ${WITH_IMAGE:-ghcr.io/docker-mailserver/docker-mailserver:latest}
hostname: mail.example.test Due to # includes/auth/file.yaml
services:
dms:
configs:
- source: dms-accounts-${WITH_ACCOUNT_DOMAIN:-example}
target: /tmp/docker-mailserver/postfix-accounts.cf
configs:
dms-accounts-example:
content: |
[email protected]|{SHA512-CRYPT}$$6$$sbgFRCmQ.KWS5ryb$$EsWrlYosiadgdUOxCBHY0DQ3qFbeudDhNMqHs6jZt.8gmxUwiLVy738knqkHD4zj4amkb296HFqQ3yDq4UXt8.
[email protected]|{SHA512-CRYPT}$$6$$sbgFRCmQ.KWS5ryb$$EsWrlYosiadgdUOxCBHY0DQ3qFbeudDhNMqHs6jZt.8gmxUwiLVy738knqkHD4zj4amkb296HFqQ3yDq4UXt8.
# Same as above, only change is `example.test` => `remote.test`:
# Presumably while `include` can use ENV for dynamic config, the resource still needs a unique name
# if multiple variants would be merged.
dms-accounts-remote:
content: |
[email protected]|{SHA512-CRYPT}$$6$$sbgFRCmQ.KWS5ryb$$EsWrlYosiadgdUOxCBHY0DQ3qFbeudDhNMqHs6jZt.8gmxUwiLVy738knqkHD4zj4amkb296HFqQ3yDq4UXt8.
[email protected]|{SHA512-CRYPT}$$6$$sbgFRCmQ.KWS5ryb$$EsWrlYosiadgdUOxCBHY0DQ3qFbeudDhNMqHs6jZt.8gmxUwiLVy738knqkHD4zj4amkb296HFqQ3yDq4UXt8. # includes/features/getmail.yaml
services:
dms:
environment:
ENABLE_GETMAIL: 1
# Reduce the polling frequency to 1 minute for quicker testing:
GETMAIL_POLL: 1
configs:
- source: getmail-jane
target: /tmp/docker-mailserver/getmail/jane.cf
configs:
# Basic getmail config to retrieve mail from an account at another mail server via IMAP credentials:
getmail-jane:
content: |
[retriever]
type = SimpleIMAPSSLRetriever
server = mail.remote.test
username = [email protected]
password = secret
[destination]
type = MDA_external
path = /usr/lib/dovecot/deliver
allow_root_commands = true
arguments = ("-d","[email protected]") An alternative feature similar to # includes/features/fetchmail.yaml
services:
dms:
environment:
ENABLE_FETCHMAIL: 1
# Reduce the polling frequency to 10 seconds for quicker testing:
FETCHMAIL_POLL: 10
configs:
- source: fetchmail
target: /tmp/docker-mailserver/fetchmail.cf
configs:
# Basic fetchmail config to retrieve mail from an account at another mail server via IMAP credentials:
fetchmail:
content: |
poll 'mail.remote.test' proto imap
user '[email protected]'
pass 'secret'
is '[email protected]'
no sslcertck NOTE: Opted to treat
# compose.yaml
# A composition of modular snippets instead of
services:
dms:
extends:
service: dms
include:
- path:
- includes/base.yaml
- includes/auth/${WITH_AUTH:-file}.yaml
- includes/features/${WITH_FEATURE:-getmail}.yaml
# Another instance of DMS to act as a third-party MTA for this example:
remote-mta:
hostname: mail.remote.test
extends:
service: dms
include:
- env_file: remote.env
path:
- includes/base.yaml
- includes/auth/${WITH_AUTH:-file}.yaml # remote.env
# NOTE: This file is required as `env_file` doesn't support inlined content,
# nor any `environment` equivalent supported.
WITH_ACCOUNT_DOMAIN=remote # compose.override.yaml
# NOTE: Certs were provisioned only once via a separate `compose.yaml`.
# Various images could produce the files (eg: certbot, traefik, caddy, smallstep/step-ca)
volumes:
custom-certs:
name: tls-remote-test
external: true
services:
# If needed to support verifying TLS connection, add private CA to trust store:
dms:
configs:
- source: dms-trust-custom-ca
target: /tmp/docker-mailserver/user-patches.sh
volumes:
- custom-certs:/srv/custom-certs:ro
# Configure with TLS support:
remote-mta:
environment:
SSL_TYPE: manual
SSL_CERT_PATH: /srv/custom-certs/remote.test/cert.pem
SSL_KEY_PATH: /srv/custom-certs/remote.test/key.pem
volumes:
- custom-certs:/srv/custom-certs/:ro
configs:
dms-trust-custom-ca:
content: |
#!/bin/bash
cp /srv/custom-certs/ca/cert.pem /usr/local/share/ca-certificates/smallstep-ca.crt
update-ca-certificates This example above was derived from:
Rather than the single file approach, as I add more examples I thought it'd be nicer to modularize, but that gets a bit more complicated with more than one instance of the service in an example. Users could then use This is probably niche, so feel free to close. It might be better suited to leaning on other tooling focused on templating. |
|
That's what I originally expected and wanted, thinking that the file boundary would have been sufficient for extending a service file that has
That doesn't really work when there isn't a sequential hierarchy, such as with layering multiple feature snippets. That's where See the larger example I provided where a 2nd instance diverges. This is perhaps too niche of a use-case for Compose to support, I don't mind looking into other approaches. I may just need to accept that the modularity can't be as DRY as I was aiming for, or rely on additional tooling. I think for example I could use |
Description
This
include
works if the latter invalid section is removed:The extend attempt is invalid as
include
hasn't been processed/resolved when theextends
logic runs? Yet it's valid to usedepends_on: [example]
, that feels a tad inconsistent.Attempting to workaround that I assumed a separate compose file that extends
compose.include.yaml
to get mergedexample
service to target might work:This also fails. Perhaps the
extends.service
logic is failing because it only understands to check a YAML file forservices.<NAME>
exists, which occurs without resolvinginclude
? Whiledepends_on
is working presumably as a later stage/step once the compose config is fully generated?I attempted to try another approach with variable interpolation on the service name key and pair that with
include.path.env_file
to have a dynamic service name to avoid the conflicting/overlapping service name if using multipleinclude
entries instead ofextends.service
. That doesn't work as variable interpolation isn't available for YAML keys.Similarly fragments and extensions are locked to the scope of the same YAML document, so I cannot leverage
include
or merge (multiple CLI-f
) to share modular config in a DRY manner.include
is great, for layering multiple compose configs into a single document which I wanted for demonstrating permutations/variants to demonstrate various features for a service. It is rather dependent upon the same service name however, which wouldn't be an issue ifextends
were compatible in a way that the composedinclude
service could be imported under a different service name, usingenv_file
ofinclude
to adjust the dynamic configuration differences (or overriding viaextends
).It would seem that you'd need to use separate
compose.yaml
files instead and start each separately, which is a bit more work when you need saynetworks.default
shared between them, requiring the network to be managed separately (or have one define it, while the other uses external).With this limitation around the service name, I don't think I can easily use
environment
/configs
of services withincludes
, but would need to useenv_file
/volumes
instead to refer to external files of the same content as that would avoid the dependency on service name.The text was updated successfully, but these errors were encountered: