How to run custom tasks in production by manually calling them?

I compile and deploy my Phoenix projects manually, with no third-party library such distillery, and with a help of the commands “mix compile” and “mix release”, basically.

I need a way to run custom commands or tasks on a server in the production mode. It’d be similar to running migrations. But I’ve bewildered as for how it’s done. A project itself may or may not be up and running when a command or task is being executed. And I need to be able to pass some arguments to a said command-task.

How to do it?

  1. I’m aware of

defmodule Mix.Tasks.MyTask1 do .... but how would I do it in production, on a server? Is this even a proper and recommended way to run them on a server in production?

  1. I’m aware of bin/my_app eval 'MyProject.MyTask1' but why does it exist if there’s the other abovementioned approach? Again, is this one a proper and recommended way to run them on a server in production?

  2. Are there other approaches?

I’m bewildered. Which one to use, in what circumstances? How to use them properly?

Your second option (/bin/app eval …) looks right. Mix is a build tool and is not a part of your release. There’s a nice example of how this can be done in the Phoenix “Deploying with releases” docs.

For passing arguments, you should be able to just pass them as arguments to the command you’re running — the mix release docs have the example of bin/RELEASE_NAME eval "IO.puts(:hello)".

That doesn’t answer the question of “how to pass an argument to my custom function”

bin/RELEASE_NAME eval "IO.puts(:hello)"

because it passes some code to eval

For instance:


defmodule MyApp.Release do
  @app :my_app

  def abc(a1, b1, c1) do
    # [.......]

How to pass a1, b1, c1 to abc() in

$ _build/prod/rel/my_app/bin/my_app eval " ???"


Just pass them? Eg

$ _build/prod/rel/my_app/bin/my_app eval ", \"str\", :atom)"

You’re basically calling a function the same way as you would in IEx, so you can pass any elixir data type.

1 Like