Working with Docker + ember-cli in Development

I am breaking this subject out from here, as it is a separate issue.

Does anyone have a working Dockerfile with the following stuff working?

  • Use the ‘standard’ docker tools for dev on OS X. (docker-machine, docker-compose, boot2docker, virtualbox)
  • Mount my application code as a volume so I can edit it on my host machine (Mac)
  • Ability to cache dependencies so that I dont need to redo npm/bower install build step when I only change app code.
  • Build in a similar timeframe to building on the host machine.

I will try and put together an example Dockerfile for ember-cli-todos also to see if it has the same issues we are seeing in our environment.

3 Likes

you haven’t actually said what your problem is.

also, this form isn’t a bug-tracker, likely not the best venue for this?

@stefan my problem is I cannot achieve the goals in the list with my current understanding of docker and ember-cli.

A discussion forum seems like a totally reasonable place to see if others in the community have solved these issues in their setups to me, especially since I am not sure if it is a gap in context or a bug. If I can narrow down the issue in the context of ember-cli-todos I will open a github issue with specifics.

Found a workaround to the biggest issue underlying this stuff which is volume behavior. I opened an issue → Docker + ember-cli applications in Development · Issue #3679 · ember-cli/ember-cli · GitHub

I still don’t think this really qualifies as a ‘bug’ so not sure what to do with it.

Keep in mind is that ember-cli is a strictly build-time tool. It’s not something you’d ever want to deploy as part of your app infrastructure.

So personally I think it’s not a good candidate for something you’d want to package up in docker. Whereas your API server may be a great candidate for packaging that way, and ember-cli has built-in support for proxying to a separate server during development.

I do something similar (with straight vagrant, not docker, but same concept). My API server runs in a VM, but ember-cli runs natively on the host OS. This is much nicer than running ember-cli in the VM – it’s faster, and it avoids all the synchronization shenanigans while you’re editing code.

This is what we are doing at the moment also and it works well. The way I am thinking about this and why it is important to have support for docker:

  1. Enables synchronization between build environments for everyone on the team
  2. Our build environment is a piece of our infrastructure which we want to be the same between ‘dev’ and ‘prod’
  3. This creates a clear path to idempotent builds

What I am thinking is we would have a ‘builder’ container that does this task, and is a privately published image, any time we change dependencies we update the image. Our CI can then use this image to build and deploy application code changes that are identical to the developers intended changes.

I don’t think this is entirely true, I suspect the biggest pane is the unstable npm install, as managing node/npm versions is more or less trivial when using tools like nave or nvm. To fix the npm install problem you will need to:

  • commit all of node_modules
  • work with NPM to help them fix shrinkwrap
  • user a shrink-wrap alternative

or docker wont help at all. So if the above is solved, I suspect docker experience becomes nicer.

Also, related to the size of the node_modules tree, (which pains me) we are working hard to drop the use of bower entirely, and as it turns out bower is a substantial portion of ember-cli’s node_module tree.

Why do we bundle it? We had to many issues with users having old/broken outdated or incompatible versions of bower installed :frowning:

My stance on docker for ember-cli is as such: It should be possible and practical, but docker usage is in the minority and time is at a premium so the primary goal is stability on the metal. I don’t believe my stance is incompatible with docker, as as we improve stability on metal it will also benefit the container approach.

Now, if you want to help champion the docker love, (as maybe these threads and issue hint you may be) I will work hard to enable you.

So, in the scenario I am describing, you would only ever do this once, which is what would give you the possibility of idempotent builds. Consider the following workflow:

  1. We start a new project, and I pull in a bunch of dependencies with npm install and bower install (in a container so the compiled builds are correct)
  2. I thoroughly test this setup, and decide it is good to go.
  3. I create a new image called 'my-ember-project-builder' and publish it to our private docker registry.
  4. I update our docker-compose.yml to use this version of the image
  5. developers and our CI pull the image, can edit application code and as long as they are not changing dependencies, they never run npm install.

When a dependency needs to be updated you do 1,2,3 again, then on step 4 you point it to the new builder image. Does that make more sense?

Happy to keep pushing on the example and write up a guide and or present this. The biggest issue and my remaining question is can we get the entire project source tree (less the dependencies) on a volume.

Right now in the example I setup, because certain things are in the root of the project, you would have to rebuild if you changed .ember-cli for example. This is probably acceptable for me personally but hard to explain to others. I can’t find any recent official documentation that says NODE_PATH still works, or any references that ember-cli would support it if it does. It seems like .bowerrc supports moving bower_components out of the project path, but is there a way to do that with node_modules?

You might find this repo helpful. It is a collection of Compose set-ups for working with node apps. It looks like the “magic” there is to start with a file structure like:

app
    package.json
    index.js

But copy it to the container as:

/src
    package.json
    app
        index.js

That is, “package.json” is moved up a level in the container so that the modules are not installed in the same folder as your app code. That allows you to have Compose mount “app” as “/src/app” without needing to rebuild the image for every code change.

This strategy is not currently possible with ember-cli.

See: https://github.com/ember-cli/ember-cli/issues/3735

I thought I would mention that SANE (http://sanestack.com) does what was mentioned above: running the API server (in this case Sails.js) in a docker container. You might take a look and see if it gives you any ideas.