Docker and grunt-based workflow automation

I'm looking for a Docker-based project setup which enables:

  1. Development environment to most closely match production
  2. Best of breed workflow automation tools for all developers
  3. Highly portable/quick to set-up development environment, which supports Linux, OSX, and Windows. Currently we use Vagrant and that seems to be the most obvious choice still.

To satisfy #1:

  • Same app container (node.js + Apache) for dev, test, staging and production
  • Do not add any custom workflow tools to the container just for development's sake

To satisfy #3:

  • Do not require developers to all install their own dev tools for their respective environments/OSes (e.g. getting them to install node.js, npm, grunt, etc within the host)

So then to still satisfy #2, the idea I have is:

  • have a second "dev" container which shares files with the node/apache container and runs all the workflow automation.
  • run all the grunt watch/rebuild/reload/browser-sync etc from within that.
  • If using Vagrant, the file sharing would essentially go as host->dev container->app container

Are there any flaws in the above model, or perhaps better ideas?

One potentially missing point is whether to - and if so then how to - avoid performing a full build of containers in production each time. Without risking a mismatch of production vs other containers, I'd like to "package up" the container so that when new code is pushed to production, the app server only needs to restart, instead of npm install, etc. Particularly, once we're pushing to production, it should no longer have to pull anything from third party servers in order to run.

This is a bit broad question where answers will be opinionated rather then backed by objective arguments, but here's what I would change there:

  1. Node.js is fine, but I would choose nginx instead of Apache. Both Node.js and Nginx are event-based and allow much more throughput, which is one of advantages of Node.js. But this might vary, like if you need certain Apache-only modules, but Nginx seems more natural to put in front of Node.

  2. Why do you want to have a separate container? To minimize the production container by it not having to have dev tools?

I really think that having, say, grunt.js in the production container not too heavy, but again, you seem to try to minimize impact. Anyway, alternatively you can have both code and grunt watch etc inside one container and deploy like that. Pros are that you're simplifying setup, cons are that your production build might install a few extra libs. Which you can mitigate by, for example, setting NODE_ENV to production when deploying production container so that on startup, your scripts will know not to load certain dev tools.