Skip to content
This repository has been archived by the owner on Jun 13, 2021. It is now read-only.

Cannot use variable substitution on service image fields #481

Open
kinghuang opened this issue Mar 13, 2019 · 6 comments
Open

Cannot use variable substitution on service image fields #481

kinghuang opened this issue Mar 13, 2019 · 6 comments

Comments

@kinghuang
Copy link

Description

PR #432 introduced a change to Forbid variable substitution on service's image field. This change significantly impacts my ability to use docker-app in CI/CD pipelines.

Use Case

Let's say there are two repositories. image-repo produces a Docker image, and app-repo produces a Docker app that includes a service using the image produced by image-repo. The app might look something like the following.

name: app-repo
---
version: "3.7"
services:
  some_service:
    image: ${image.repository}:${image.tag}
---
image:
  repository: some-registry.example.com/image-repo
  tag: 1.0.0

image-repo contains a GitLab CI/CD configuration that builds Docker images and deploys review apps for feature branches. In the build job, an image is built and tagged using $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME, where CI_REGISTRY_IMAGE is the address of the image registry for the project, and CI_COMMIT_REF_NAME is the name of the branch being built. The review job then deploys a review app with this in-development image by passing in the image repository and tag as arugments.

docker-app deploy some-registry.example.com/app-repo:1.0.0 \
--set image.repository=$CI_REGISTRY_IMAGE \
--set image.tag=$CI_COMMIT_REF_NAME \
review-app-$CI_COMMIT_REF_NAME

There may be many review apps deployed at once.

Being unable to set service images using variables will make it impossible to use Docker Apps in CI/CD workflows, where it is necessary to dynamically set the image for one or more services.

Steps to reproduce the issue:

  1. Using a build of docker-app on master, use one or more variables to specify a service image.
  2. Attempt to render the app.

Describe the results you received:

docker-app says, “variables are not allowed in the service's image field.”

Describe the results you expected:

docker-app 0.6.0 renders the app with the variables filled in for the image.

Additional information you deem important (e.g. issue happens only occasionally):

Output of docker version:

Docker version 19.03.0-dev, build 81ac432c

Output of docker-app version:

Version:      v0.6.0-132-g803e955227
Git commit:   803e9552
Built:        Tue Mar 12 23:32:56 2019
OS/Arch:      darwin/amd64
Experimental: off
Renderers:    none

Output of docker info:

Not applicable.

Additional environment details (AWS, VirtualBox, physical, etc.):

macOS 10.13.6.

@simonferquel
Copy link
Contributor

Hi, thanks for the feedback.

We had to introduce this change because with wanted to have packages pushed to the registry trully immutable (meaning that once you push a package, all service images are pinned to a particular version).
We recognize that this is a regression for some users, but in the general case it will make it easier to support things like application-level image security scanning, application-level image promotion flows etc.

However, we have ideas about how to mitigate this issue. For this, we will have to bring a notion of "build-time" parameters in addition to our current "install-time" parameters. To understand why we need this, you need a bit of context:

what happen when I call docker app install|render|inspect

We recently refactored docker-app in a way that embrace the CNAB specification. It implies than we now have a build operation on a docker-app source package that generates a CNAB bundle with an invocation image. When you do a docker app install|render|inspect on a docker-app package in its source form, this operation is done transparently, but the actual implementation of install, renderandinspect` is actually embedded in the CNAB bundle invocation image that is just run by docker-app.

service image immutability requirements

When you pull/push a docker-app to the registry, you don't push the docker-app source itself, but you push the generated CNAB bundle (ensuring interop with other cnab tools in the ecosystem). This bundle and the associated push/pull operation is the thing that requires component image freezing. But in its source form, a docker-app package may not require this. The problem we have is that every parameter we have in the source form is translated into a CNAB install-time parameter (for now). If we introduced build time parameters (similar to Dockerfile's build args), we could do the service name interpolation before generating the CNAB. That means that as soon as you have the package source code, you can modify service images using build time parameters, but once it is built into a cnab and pushed to a registry, these service images are frozen.

Please note that this is not implemented (it is not even designed yet, and we don't even have thought about the UX related to this feature), but we are aware of this limitation and want to work on this.

@kinghuang
Copy link
Author

Thanks for the detailed explanation, @simonferquel! I surmised some of that in the Slack discussion, but wasn't aware of things like the role of the CNAB bundle invocation image.

The service image immutable requirements make perfect sense for producing finished bundles. Freezing the images into the app bundle will help ensure consistent app installs.

The challenge is how to handle use cases where I don't want service image immutability. During the development of the images that go into an app, I want to be able to continuously deploy (install) review apps with one or more images that are changing with each git commit.

I think the idea of build-time parameters can help. But, the image-repos in my example will need to get the app's source, which is in app-repo. So, I'm going to need a way to distribute bundles in source form, as opposed to finished form with images baked in.

Can there be an option to push a source bundle to the registry that can be pulled and used to build a finished bundle? That way the image-repo projects can pull the source bundle, set build-time arguments, and build/install the bundle for review purposes.

@dschulten
Copy link

Unfortunately the readme of docker-app still shows you how docker-app can be used to parameterize image versions. Maybe it would be good to put a big caveat into the readme that versioning of images is under construction :-)

@kinghuang
Copy link
Author

I had a good conversation with @chris-crone about this and #508 a couple weeks ago. But, they were about development use cases. I've just upgraded another existing 0.6.0 app and ran into this problem in a non-development scenario.

The app I upgraded deploys streaming processing, including Kafka Connect, into a specialized cluster. Confluent's Kafka Connect images come in an "out of the box" config with a default set of connectors (confluentinc/cp-kafka-connect) and a base image that you can extend with extra connectors (confluentinc/cp-kafka-connect-base). I have custom Connect images that have extra libraries and configurations to match data systems I'm working with.

With docker-app 0.6.0, it was trivial to deploy this app and specify the custom image to use for the connect service. With 0.8.0, it's both impossible to specify a custom image, and pass in a config file with the connector details for a particular instance (#535).

@jhrabi
Copy link

jhrabi commented Aug 27, 2020

Is there any update on this? We're still having to use 0.6.0 to support use requirements and it's release is coming up on 2 years...

@javieryanez
Copy link

I am the same as jhrabi, using the old v0.6.0, because I cannot define a different tag in each execution environment (dev, test, stage, production...)

Any suggestion of how I could solve that different environments share the same configuration but with different image tags?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants