Phoenix container deployment

Hello,

I have a sample app and I want to dockerize it.

It’s just a sample app, and I want to create the db and run migrations when the containers are created.

This is what I have:

I’m using the container in this guide:

I added this line in prod.secret.exs

database_url = “ecto://postgres:postgres@db/lists_dev”
This is a good way of setting the user, password and host for de database? Security it’s not an issue.

Created this module:

defmodule Lists.Release do
  @moduledoc false

  @start_apps [:postgrex, :ecto, :ecto_sql]

  @myapps [:lists]

  def create_and_migrate() do
    createdb()
    migrate()
  end

  def createdb do
    # Start postgrex and ecto
    IO.puts("Starting dependencies...")

    # Start apps necessary for executing migrations
    Enum.each(@start_apps, &Application.ensure_all_started/1)

    Enum.each(@myapps, &create_db_for/1)
    IO.puts("createdb task done!")
  end

  def create_db_for(app) do
    for repo <- get_repos(app) do
      :ok = ensure_repo_created(repo)
    end
  end

  defp ensure_repo_created(repo) do
    IO.puts("create #{inspect(repo)} database if it doesn't exist")

    case repo.__adapter__.storage_up(repo.config) do
      :ok -> :ok
      {:error, :already_up} -> :ok
      {:error, term} -> {:error, term}
    end
  end

  def migrate() do
    IO.puts("Start running migrations..")
    Enum.each(@myapps, &run_migrations_for/1)
    IO.puts("migrate task done!")
  end

  def run_migrations_for(app) do
    IO.puts("Running migrations for '#{app}'")

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

    IO.puts("Finished running migrations for '#{app}'")
  end

  defp get_repos(app) do
    Application.load(app)
    Application.fetch_env!(app, :ecto_repos)
  end

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

From a bash file that I called from the dockerfile I execute:

bin/lists eval "Lists.Release.create_and_migrate()"

bin="bin/lists"

# start the elixir application

exec "$bin" "start"

When I build the container I have this error.

** (RuntimeError) enviroment variable SECRET_KEY_BASE is missing. You can generate one by calling: mix phx.gen.secret

I tried to add to the dockerfile the line:

RUN mix phx.gen.secret

but It doesn’t work.

I know that this is a strange case, but I’m trying to end up with a dockerfile that could create the database, migrate and run by itself. Security it’s not an issue.

Thanks!

You need to set the SECRET_KEY_BASE env variable. You can set it via -e option to docker run like this:

$ secret=`mix phx.gen.secret`
$ docker run -e SECRET_KEY_BASE=$secret ...
1 Like