I finished up Dave’s Elixir for Programmers course (really enjoyed it, review coming soon) but it did leave me with one big question coming out of it.
Dave emphasizes the non-umbrella, multi-application approach. I like everything about the approach from a separation standpoint. My biggest question was about how to deploy it as a single unit so that it could be deployed on say AppEngine, Kubernetes, Heroku, Gigalixir, etc.
Aside from Heroku, most deployments revolve around Distillery. What would be the proper way to package up those apps in a release?
Here’s the public code from the end of the course:
Essentially you have an app with:
- Dictionary (word list process)
- Hangman (game logic that uses the dictionary)
And then 3 different interfaces to the game:
- Text Client
- Gallows (web client)
- Socket Gallows (channels)
The two big questions I have with this approach vs umbrellas are around deployments on a single BEAM and dependencies.
In the Phoenix docs discussing Umbrellas there is a Don’t Drink the Kool-Aid section that mentions the following:
If you find yourself in a position where you want to use different configurations to different applications in the same umbrella or to use different dependency versions, then it is likely your codebase have grown beyond what umbrellas can provide.
The good news is that breaking an umbrella apart is quite straightforward, as you simply need to move applications outside of the umbrella project’s apps/ directory. In the worst case scenario, you can discard the umbrella project and all related configuration (build_path, config_path, deps_path and lockfile) and still leverage the “mono-repo” pattern by keeping all applications together in the same repository. Each application will have its own dependencies and configuration. Dependencies between those applications can still be explicitly listed by using the :path option (in contrast to :git).
From reading that it makes it sound as if:
The Umbrella would have a shared dependency tree, so if a dependency in one app had a hard requirement on a specific version of a package all of the dependencies within the umbrella would be stuck with that.
The non-umbrella version would be able to still live as a single mono-repo and presumably deployed as a unit…but have their own untangled dependency trees that could include different versions of the exact same package for each application’s own uses.
If that is actually the case, it definitely seems like the non-umbrella approach would win best architecture with a landslide as long as the deployment questions are easy enough to answer.