faradayio / cage

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

Cage should favour pulling images rather than building them #69

Closed camjackson closed 6 years ago

camjackson commented 7 years ago

Imagine I'm a brand new contributor to a project, with no docker images on my machine. I clone a cage repo and run cage up, and it creates compose files (in the .cage directory) that have snippets like this:

---
"services": 
  "my-service": 
    "image": "my-org/my-service"
    "build": "git@github.com:my-org/my-service.git"
    "command": "yarn start"
...

Currently I get this output:

ERROR: Error trying to use git: exit status 128 (Cloning into '/var/lib/docker/tmp/docker-build-git708053926'...
Host key verification failed.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
)
Error: error running 'docker-compose -p my-cage -f /path/to/my-cage/.cage/pods/my-pod.yml up -d'

Now, I aside from the fact that the git crash seems like a bug, I'm surprised that it's trying to do anything with git at all! I was expecting that it would just pull the prebuilt my-org/my-service image, and start up a container. If I manually remove the "build": ... line from .cage/pods/my-pod.yml, and manually invoke docker-compose on that file, then it works exactly as I expect. But because cage is putting the build line in the compose file, it causes docker compose to try to build the image rather than pull it.

This is especially important for projects with unorthodox docker build systems like OpenShift's source-to-image tool which creates docker images without a Dockerfile present.

At the moment my work around is to acquire all the pre-built images before running cage up, either by docker pull-ing or building them all one-by-one. Once I have the images locally, then docker-compose stops trying to build images when I run cage, and everything works. But it would be nice not to have to do this.

emk commented 7 years ago

Yeah, I don't necessarily any good answers here. This is docker-compose just doing its thing, as far as I know. If anybody knows how to get more reasonable behavior out of docker-compose, I'd love to hear it.

emk commented 7 years ago

If I sounded frustrated in my last comment, it's because I'm deeply annoyed every time this happens to me, too, and I agree it would be lovely to fix it. I just don't know how to proceed. :confused:

camjackson commented 7 years ago

All good! :)

Is there some way cage could omit the build line from the generated compose file in scenarios like this? At least for my own use cases, I'm always running pre-built images, either with or without the source code mounted in. Building the images locally isn't part of my workflow, so I don't need the build line in the final compose file at all.

I'm guessing that it ends up there because I have the equivalent line in my cage pod file. But I only have it in that file so that cage knows where to get my source code from when I mount. What if cage read that config for its own purposes, but didn't "forward" it on down to docker-compose, so to speak?

emk commented 7 years ago

Hmm, that's a potentially interesting idea. I'd have to think about how it would work, and if there's any reasonable way to do it without adding lots of flags to the CLI. I don't have the cycles for that right now, but I'll take a look again the next time I'm making other cage changes.

camjackson commented 7 years ago

Simple but possibly dumb idea: just don't ever put the build: line in the generated compose file? What use case does it serve there?

emk commented 7 years ago

It's there for people who don't have a CI system, theoretically. I'm not sure that it's a good idea, and since we re-generate the *.yml files every time we run, we could maybe only emit build: for a cage build subcommand and omit it otherwise.

Basically, given a choice between:

  1. Spending an hour thinking about an issue to find the correct answer, and writing 5x the code,
  2. Or just adding an easy flag,

I strongly prefer (1). I feel like flags are too often a design cop-out, and with a bit of design effort, they can frequently be avoided entirely and the final product will be much better.

camjackson commented 7 years ago

Definitely agree on your last point. Flags should be a last resort.

Emitting build only when building seems like a decent option.

emk commented 7 years ago

OK, so I think we agree on the correct design. I can't promise to get to this right away, but the next time I work on cage, I'm happy to try implementing it. Thank you for the suggestion!

camjackson commented 7 years ago

I decided to have a play with something simple. Not sure if it's at all the right approach: #70.

emk commented 6 years ago

I'm closing this issue in favor of #70, so that we have fewer things to track for the release. :-)