Create Sqlite DB with mix releases and docker

Hello,

i am trying to deploy a phoenix 1.6 application and following the official recommendations and Dockerfile about deploying with releases in a docker container.

Because mix is not available in the final image after the release was build i cant figure out a way to create the database. I tried to create and modify the recommended Release module (inspired by the mix ecto.create task) but Exqlite fails with {:error, :database_open_failed}.

Here is my release module (i changed it back to MyApp)

defmodule MyApp.Release do
  @app :my_app

  def migrate do
    load_app()

    for repo <- repos() do
      {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
    end
  end

  def create do
    load_app()

    for repo <- repos() do
      repo.__adapter__.storage_up(repo.config)
    end
  end

  def rollback(repo, version) do
    load_app()
    {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version))
  end

  defp repos do
    Application.fetch_env!(@app, :ecto_repos)
  end

  defp load_app do
    Application.load(@app)
  end
end

I try to execute it with eval "MyApp.Release.create"

The command fails with

web_1  | ** (MatchError) no match of right hand side value: {:error, :database_open_failed}
web_1  |     lib/ecto/adapters/sqlite3.ex:422: Ecto.Adapters.SQLite3.storage_up_with_path/2

Is there a better way to create the database or has anybody a solution for my problem? Is it because the elixir user in the final container has not the necessary permissions to create the file? How to work around that?

You can attach a volume with database to the running container and pass the path to the container with env vars. Note that if you create the database within the container, the data written to it would be lost when container restarts. I’m not sure how sqlite open can fail though, maybe not enough permissions?

In production credentials are usually stripped to a minimum, so that the db user isn’t even allowed to create databases. Usually the database is therefore created out of band / before initial deployment.

1 Like