Search code examples
elixirproduction-environmentelixir-mix

Running mix tasks in production


I have a number of tasks and jobs that I would like to be able to execute manually on a production elixir application. Currently, I have been performing them by running the code inside the remote_console. I Attempted to run them by using /bin/my_app command MyModule my_func, but I get errors about resources being used by another Erlang node.

I would prefer to use the /bin/my_app command MyModule my_func style so I can run the bash scripts using ssh.

What's is the recommended way to run remote tasks on Elixir application?


Solution

  • Running mix tasks in production is not possible, since mix is not part of the application release.

    However, it is obviously possible to include any code in the final application release, so you can add the code that would run migrations on app start.

    Documentation for Ecto.Migrator module contains a sample migration runner:

    defmodule MyApp.Release do
      @app :my_app
    
      def migrate do
        for repo <- repos() do
          {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
        end
      end
    
      def rollback(repo, version) do
        {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version))
      end
    
      defp repos do
        Application.load(@app)
        Application.fetch_env!(@app, :ecto_repos)
      end
    end
    

    Then, a command to run migration can be included as part of the release start up:

    bin/my_app eval "MyApp.Release.migrate"