faradayio / cage

Develop and deploy complex Docker applications
http://cage.faraday.io
Apache License 2.0
307 stars 26 forks source link

Add a way to avoid eager interpolation of environment variables. #85

Open khuey opened 6 years ago

khuey commented 6 years ago

I sometimes want docker-compose to do the interpolation, rather than cage. For example, I have a local testing script that turns arguments into environment variables to smuggle them through docker into the container, which then has a wrapper script that turns them back into arguments to call the interesting binary inside my container. Cage eagerly interpolates the environment variables, which is fine when calling cage up from the testing script but if I try to do cage status or cage logs or whatever from another terminal window it tries (and fails) to eagerly interpolate again.

As far as I see there's no workaround for this, but I'd like to see either a cage argument or maybe special syntax to allow deferring the interpolation.

I'm happy to implement this myself with some guidance on what would be accepted :)

emk commented 6 years ago

Good question! There are a couple of very complex issues here.

  1. In general, you should do most of your environment overriding in pods/targets/$TARGET/common.env files, and not rely on docker-compose features to do it for you. The various docker-based interpolation mechanisms are often ill-defined in the presence of a tool like cage, and it's hard to spec really sensible behaviors.
  2. cage needs to read many of these values in order to do its job, and once it reads a value, any interpolations are officially set in stone. In particular, I would consider it a bug for cage to interpolate a value for internal use, and then to pass it through as an uninterpolated value to docker-compose. This is because cage may use the value of one field to compute the values of other fields, and I refuse to ever open that can of worms. :-)
  3. I think that there's a mechanism for selective interpolation, where cage will leave alone values that it doesn't care about, and pass them through. I'm not 100% convinced that this is a good idea, and it seems fragile to me, because a new cage plugin might need to look at a value that was previously untouched. And it's possible that I completely deactivated this at some point.

For the use case you describe, would it be possible to set useful defaults?

emk commented 4 years ago

Hello! cage was very minimally maintained for several years, and I'm sorting through old issues. I'm going to go ahead and close this issue for inactivity, but please feel free to reopen it if anybody is still interested.

khuey commented 4 years ago

fwiw you have issues configured so I can't reopen them even if I wanted to ;)

emk commented 4 years ago

Re-opened. :-) Sorry about that.

Anyway, I think that a lot of it comes down to this:

I sometimes want docker-compose to do the interpolation, rather than cage.

...and this:

cage needs to read many of these values in order to do its job, and once it reads a value, any interpolations are officially set in stone. In particular, I would consider it a bug for cage to interpolate a value for internal use, and then to pass it through as an uninterpolated value to docker-compose.

cage simply cannot do its job without parsing the contents of quite a few fields, which requires interpolation. It actually tries to avoid touching fields that it doesn't need, though I'm not sure that's actually a good idea.

I recommend using pods/targets/test/{common.env,*.yml} to pass environment-specific values to tests.