Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ARG MIX_ENV=prod
ENV HOME=/opt/app/ SHELL=/bin/bash MIX_ENV=$MIX_ENV
WORKDIR /opt/build

# Cache dependencies
# Build & cache dependencies
COPY mix.exs mix.lock ./
COPY apps/cf/mix.exs ./apps/cf/
COPY apps/cf_atom_feed/mix.exs ./apps/cf_atom_feed/
Expand All @@ -18,12 +18,10 @@ COPY apps/db/mix.exs ./apps/db/
RUN mix local.hex --force
RUN mix local.rebar --force
RUN HEX_HTTP_CONCURRENCY=4 HEX_HTTP_TIMEOUT=180 mix deps.get --only $MIX_ENV

# Build dependencies
COPY . .
RUN mix deps.compile

# Build app
COPY . .
RUN mix compile
RUN mix release

Expand Down
15 changes: 14 additions & 1 deletion apps/db/lib/db/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,20 @@ defmodule DB.Application do
require Logger

def start(_type, _args) do
# Define workers and child supervisors to be supervised
case DB.Repo.ensure_storage_created() do
:ok ->
start_repo_and_migrate()

{:error, reason} ->
Logger.error(
"Could not create or reach Postgres database #{inspect(DB.Repo.config()[:database])}: #{reason}"
)

{:error, {:could_not_create_database, reason}}
end
end

defp start_repo_and_migrate do
children = [
# Starts a worker by calling: DB.Worker.start_link(arg1, arg2, arg3)
# {DB.Worker, [arg1, arg2, arg3]},
Expand Down
30 changes: 27 additions & 3 deletions apps/db/lib/db/release_tasks.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ defmodule DB.ReleaseTasks do
:ssl,
:postgrex,
:ecto,
:ecto_sql,
:logger
]

Expand All @@ -27,6 +28,17 @@ defmodule DB.ReleaseTasks do
:init.stop()
end

@doc """
Loads dev seed data (Cypress video + admin user) via `DB.Seeds.seed_dev_data/0`.
For local integration tests against a prod release — not for production containers.
"""
def seed_dev_data_release do
init()
{:ok, _} = Application.ensure_all_started(:bcrypt_elixir)
DB.Seeds.seed_dev_data()
:init.stop()
end

def seed do
init()

Expand Down Expand Up @@ -68,17 +80,29 @@ defmodule DB.ReleaseTasks do
def priv_dir(app), do: "#{:code.priv_dir(app)}"

defp init do
# Load the code, but don't start it
:ok = Application.load(:db)
# Load the code, but don't start it (eval may already have :db loaded)
case Application.load(:db) do
:ok -> :ok
{:error, {:already_loaded, :db}} -> :ok
{:error, reason} -> raise "Application.load(:db) failed: #{inspect(reason)}"
end

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

Logger.info("Dependencies started, loading runtime configuration...")

case DB.Repo.ensure_storage_created() do
:ok ->
:ok

{:error, reason} ->
raise "Could not ensure Postgres database exists: #{reason}"
end

# Start the Repo(s) for myapp
Logger.info("Starting repos..")
Enum.each(@repos, & &1.start_link(pool_size: 1))
Enum.each(@repos, & &1.start_link(pool_size: 2))
end

defp run_migrations_for(app) do
Expand Down
31 changes: 31 additions & 0 deletions apps/db/lib/db/repo.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,35 @@
defmodule DB.Repo do
use Ecto.Repo, otp_app: :db, adapter: Ecto.Adapters.Postgres
use Scrivener, page_size: 10

require Logger

@doc """
Ensures the configured database exists on Postgres (runs `CREATE DATABASE` via
the adapter). Uses `maintenance_database` (default `"postgres"`).

Safe to call when the DB already exists (`:already_up`).

Call **before** `start_link`; returns `:ok` or `{:error, reason}`.
"""
@spec ensure_storage_created() :: :ok | {:error, term()}
def ensure_storage_created do
adapter = __adapter__()
opts = config()

case adapter.storage_up(opts) do
:ok ->
Logger.info("Created Postgres database #{inspect(opts[:database])}")
:ok

{:error, :already_up} ->
:ok

{:error, reason} ->
{:error, format_storage_error(reason)}
end
end

defp format_storage_error(reason) when is_binary(reason), do: reason
defp format_storage_error(reason), do: inspect(reason)
end
12 changes: 10 additions & 2 deletions apps/db/lib/db/seeds.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,16 @@ defmodule DB.Seeds do
before the admin user so the video keeps `id == 1` and `hash_id == "Jzqg"`.
"""
def seed_dev_data(repo \\ Repo) do
seed_cypress_video_and_statement(repo)
seed_dev_admin_user(repo)
env = Application.get_env(:db, :env)

if env != :dev and env != :test do
Logger.warning("API is running in non-dev mode. Skipping dev seeds.")
:ok
else
seed_cypress_video_and_statement(repo)
seed_dev_admin_user(repo)
end

:ok
end

Expand Down
Loading