Rackla is difficult to deploy to staging/production
beno opened this issue · comments
It turns out it needs to be added to the ill-documented :included_applications
list in Mixfile.application/0
. Adding :rackla
to the :applications
list (as is standard practice for all production dependencies) produces an error. See also this post of mine on elixirforum.
Thanks for the report! I'll take a look at it as soon as I can!
(I'm presuming that you are using Rackla as an dependency from Hex. If you have cloned the code, then this is not applicable.)
To start, this is the cause of the error:
When you add :rackla
as an application to start, Elixir (or Mix) will try to launch lib/rackla/application.ex, this file is in turn dependent on lib/rackla/router_gen_server.ex which in turn is dependent on lib/router.ex.
Neither of these three files are packaged into the Rackla package published to Hex. While I could add application.ex
and router_gen_server.ex
and ship them off, router.ex
is something you as the consumer will want to define yourself. In fact, you should want to define all three of them yourself.
Cause: this line should not be present when I publish to Hex
Line 20 in 7f459b6
Something like this should be added to the documentation:
When you use Rackla as a dependency, your project should be responsible for launching the web-server (Cowboy) and define your own Plug Router.
You can do this as demonstrated here in the Plug documentation: https://github.com/elixir-lang/plug#supervised-handlers
In the Rackla example project, I did it with these three files (I should probably simplify this to look more like the Plug documentation).
Include Rackla as a dependency:
defp deps do
[{:rackla, "~> 1.1"}, {:cowboy, "~> 1.0"}]
end
Start :cowboy
, :plug
and :hackney
(and :rackla
but I have to fix this bug first so omit this for now) - and also your own application using mod:
(replace Rackla.Application
with whatever your Application module is called):
def application do
[applications: [:logger, :cowboy, :plug, :hackney], mod: {Rackla.Application, []}]
end
Does it make sense, maybe you've done something similar already?
Right now I use the same repository for my the demo setup you can clone as well as the code I use to publish to Hex. I will split this up into two different repositories:
- Pure Rackla code which will be used to build the app and publish to Hex.
- Minimal example implementation (similar to the repo today) but here I will use Rackla as a proper dependency from Hex - not use the code directly (this was a bad idea).
This should ensure that we never encounter this problem again and the users of Rackla will have a reference implementation that they can follow and use.
I've committed a test version with a small fix, you can try it by using this as the dependency instead:
{:rackla, "~> 1.1", git: "git://github.com/antonfagerberg/rackla.git", branch: "feature/application"}
Then it should be possible to add :rackla
to applications:
as well.
You still need to define your own Router etc as mentioned before.
Hey thanks a lot. I will give it a try asap. To clarify, the problem here is that dependencies need to be explicitly listed in the applications list, even if they are just libraries, and this requirement only applies to building a production release. So even if in development all seems fine and the code picks up the dependency from deps
, it is only production this fails at runtime because the libraries aren't bundled (even though it does compile). To me this seems highly inconsistent and un-DRY, but people on elixirforum don't seem to mind. So the rule is, whatever you put in deps, you put in applications. Except the only: :dev
deps of course, but the meaning of that flag has fully escaped me by now.
I will let you know how it goes.
Thanks for the clarification!
I've made some additional progress. The develop
branch in this repo should now be stripped of all non-library related code. (So you should be able to reference {:rackla, "~> 1.2", git: "git://github.com/antonfagerberg/rackla.git", branch: "develop"}
now in your code instead).
I moved and refactored the other code, which should serve as a reference implementation of a complete project using Rackla as a library, to this repo: https://github.com/AntonFagerberg/rackla_skeleton
In the end, I think splitting up the project like this was actually kinda nice - more loose coupling. Also, there is apparently a need for me to use it as a library myself to avoid these bugs :)
Hopefully I didn't screw up too much things. If everything looks good and it seems to work for you, I'll make a proper 1.2.0 release soon!