Edeliver + Distillery Ecto migrate probleem "Internal Server Error"

I’m experimenting with “veil” an email based (passwordless) authentication package and edeliver and distillery.

It looks like my database migration is not happening when I use edeliver/distillery?

Are there any suggestions on how to debug this as I’m new to both postgres and elixir. Here is what I was able to pull from the logs.

===== ALIVE Mon Sep 17 23:58:28 UTC 2018
00:00:00.007 [error] Task #PID<0.1939.0> started from #PID<0.1938.0> terminating ^H
** (Postgrex.Error) ERROR 42P01 (undefined_table): relation "veil_requests" does not exist
    (ecto) lib/ecto/adapters/sql.ex:431: Ecto.Adapters.SQL.execute_and_cache/7
    (ecto) lib/ecto/repo/queryable.ex:133: Ecto.Repo.Queryable.execute/5 ^H
    (ecto) lib/ecto/repo/queryable.ex:37: Ecto.Repo.Queryable.all/4
    (myapp) lib/myapp/veil/veil.ex:210: myapp.Veil.delete_expired_requests/0
    (elixir) lib/task/supervised.ex:89: Task.Supervised.do_apply/2
    (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Function: #Function<0.32921185/0 in myapp.Veil.Clean.expired/0>
    Args: []
00:00:00.007 [error] Task #PID<0.1940.0> started from #PID<0.1938.0> terminating ^H
** (Postgrex.Error) ERROR 42P01 (undefined_table): relation "veil_sessions" does not exist
    (ecto) lib/ecto/adapters/sql.ex:431: Ecto.Adapters.SQL.execute_and_cache/7
    (ecto) lib/ecto/repo/queryable.ex:133: Ecto.Repo.Queryable.execute/5 ^H
    (ecto) lib/ecto/repo/queryable.ex:37: Ecto.Repo.Queryable.all/4
    (myapp) lib/myapp/veil/veil.ex:219: myapp.Veil.delete_expired_sessions/0
    (elixir) lib/task/supervised.ex:89: Task.Supervised.do_apply/2
    (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Function: #Function<1.32921185/0 in myapp.Veil.Clean.expired/0>
    Args: []

Well, distillery does not run your migrations, it just bundles a release. And if edeliver runs your migrations (as it is the tool which deploys to your server and should set it up) depends on your configuration.

Without knowing your setup, we can only assume you are running a default setup, which simply doesn’t run migrations, as it can not assume there were any, since edeliver and distillery are agnostic to the libraries you use. You might use a different way to connect to your database, even you might not use a database at all, etc.

1 Like

That’s a good point. So in the edeliver config file I used a script I saw on a blog post and simply added

mix ecto.create
mix ecto.migrate

but I’m starting to suspect that may not be the correct way to migrate via production?

pre_erlang_clean_compile() {
  status "Running phx.digest" # log output prepended with "----->"
  __sync_remote " # runs the commands on the build host
    # [ -f ~/.profile ] && source ~/.profile # load profile (optional)
    source ~/.profile
    # echo \$PATH # check if rbenv is in the path
    mix ecto.create
    mix ecto.migrate

    set -e # fail if any command fails (recommended)
    cd '$BUILD_AT/assets' # enter the build directory on the build host (required)

    # prepare something
    npm install
    ./node_modules/brunch/bin/brunch build --production

    cd ..
    mkdir -p priv/static # required by the phx.digest task
    # run your custom task
    APP='$APP' MIX_ENV='$TARGET_MIX_ENV' ECTO_REPOSITORY="myapp.Repo" PORT=443 $MIX_CMD phx.digest $SILENCE 
  "
}

That runs both tasks on the build host with the config for whatever MIX_ENV is active them, probably dev.

You need to run it after deploy on the prod host. This is non trivial as usually neither mix nor your source code are available there.

1 Like

of course. I think I was just still trying to wrap my head around the new language and db.

I think I solved it by having

  1. edeliver as apart of the extra applications
  2. running

mix edeliver migrate production

instead of

mix edeliver migrate

I’ve gotten the db’s to migrate. Thanks for letting me attempt to talk through it with some feedback.

This is my config from a recent project with automatic migration. I didn’t come up with it all but a can’t remember where I got it from either to link directly to the originator.

pre_erlang_get_and_update_deps() {
  if [ "$TARGET_MIX_ENV" = "prod" ]; then
    __sync_remote "
      set -e
      cd '$BUILD_AT'
      mkdir -p priv/static
      mix deps.get
      cd '$BUILD_AT/assets'
      npm install  --no-warnings
      npm run deploy  --no-warnings
      cd '$BUILD_AT'
      APP='$APP' MIX_ENV='$TARGET_MIX_ENV' $MIX_CMD ecto.migrate $SILENCE
      APP='$APP' MIX_ENV='$TARGET_MIX_ENV' $MIX_CMD phx.digest $SILENCE
    "
  fi
}
2 Likes

Awesome. Thanks for sharing