terenceponce
I’m running a Phoenix app on a Kubernetes cluster (through Digital Ocean) and I was able to deploy my app with minimal issues for the most part.
However, for some reason, calling Ecto.Migrator keeps saying “migrations already up” when in reality, it hasn’t actually done anything. Even the schema_migrations table is empty.
This isn’t the first time I’ve done a deployment setup like this so I am dumbfounded as to why this is happening in the first place. I definitely have a few migration files in the app, but they have not run at all.
Here is the release task module that I’m using:
defmodule MyApp.ReleaseTasks do
@moduledoc false
@app :my_app
def migrate do
load_app()
# migrate database
for repo <- repos() do
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
end
# migrate event store
config = MyApp.EventStore.config()
:ok = EventStore.Tasks.Migrate.exec(config, [])
end
def rollback(repo, version) do
load_app()
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version))
end
def seed do
for repo <- repos() do
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &MyApp.ReleaseTasks.run_seed_for(&1))
end
end
def init_event_store do
load_app()
config = MyApp.EventStore.config()
:ok = EventStore.Tasks.Init.exec(config, [])
end
def run_seed_for(repo) do
seed_script = priv_path_for(repo, "seeds.exs")
if File.exists?(seed_script) do
IO.puts("Running seed script...")
Code.eval_file(seed_script)
end
end
defp repos do
Application.fetch_env!(@app, :ecto_repos)
end
defp load_app do
{:ok, _} = Application.ensure_all_started(:postgrex)
{:ok, _} = Application.ensure_all_started(:ssl)
:ok = Application.load(@app)
end
defp priv_path_for(repo, filename) do
app = Keyword.get(repo.config, :otp_app)
repo_underscore =
repo
|> Module.split()
|> List.last()
|> Macro.underscore()
priv_dir = "#{:code.priv_dir(app)}"
Path.join([priv_dir, repo_underscore, filename])
end
end
This is my app’s config/releases.ex file:
import Config
config :my_app, MyAppWeb.Endpoint,
http: [
port: String.to_integer(System.fetch_env!("PORT")),
transport_options: [socket_opts: [:inet6]]
],
url: [
host: System.fetch_env!("HOST"),
port: String.to_integer(System.fetch_env!("PORT"))
],
server: true,
secret_key_base: System.fetch_env!("SECRET_KEY_BASE")
config :my_app, MyApp.Repo,
hostname: System.fetch_env!("DB_HOSTNAME"),
username: System.fetch_env!("DB_USERNAME"),
password: System.fetch_env!("DB_PASSWORD"),
database: System.fetch_env!("DB_NAME"),
port: System.fetch_env!("DB_PORT"),
pool_size: String.to_integer(System.fetch_env!("DB_POOL_SIZE")),
ssl: true,
ssl_opts: [
cacertfile: System.fetch_env!("DB_CERT")
]
config :my_app, MyApp.EventStore,
hostname: System.fetch_env!("EVENTSTORE_DB_HOSTNAME"),
username: System.fetch_env!("EVENTSTORE_DB_USERNAME"),
password: System.fetch_env!("EVENTSTORE_DB_PASSWORD"),
database: System.fetch_env!("EVENTSTORE_DB_NAME"),
port: System.fetch_env!("EVENTSTORE_DB_PORT"),
pool_size: String.to_integer(System.fetch_env!("EVENTSTORE_DB_POOL_SIZE")),
ssl: true,
ssl_opts: [
cacertfile: System.fetch_env!("EVENTSTORE_DB_CERT")
]
This is the Dockerfile that I’m using:
FROM beardedeagle/alpine-phoenix-builder:1.11.3 AS build
WORKDIR /app
RUN mix local.hex --force && \
mix local.rebar --force
ENV MIX_ENV=prod
COPY mix.exs mix.lock ./
COPY config config
RUN mix do deps.get, deps.compile
COPY lib lib
COPY rel rel
RUN mix do compile, release
FROM alpine:3.13 AS app
RUN apk add --no-cache openssl ncurses-libs
WORKDIR /app
EXPOSE 4000
RUN chown nobody:nobody /app
USER nobody:nobody
COPY --from=build --chown=nobody:nobody /app/_build/prod/rel/my_app ./
ENV HOME=/app
CMD ["bin/my_app", "start"]
I can confirm that the required environment variables are present inside the pod that gets created from the Kubernetes deployment so I don’t think there are any issues with that.
Also, running the commands from the release tasks module don’t result in any errors. The only issue is that running bin/my_app eval "MyApp.ReleaseTasks.migrate outputs “Migrations already up” when that is not in fact the case.
Another thing I could point out is that I am using commanded/eventstore for this app and running the migrations for the event store actually works.
Any help is appreciated.
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #phoenix_html
- #iex
- #graphql
- #ai
- #genstage
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex











Showing Posts 1 to 3- Show Best Posts
- Show All Posts (oldest first)
- Show All Posts (newest first)
Exadra37
I deploy with docker, but I don’t use Kubernetes, instead plain
docker-compose.ymlfile.I don’t see how I can help you with your issue, but you can try out my
docker-compose.ymlfile:If you continue to see the problem with migrations with this docker-compose file then you must have some issue in the Kubernetes configuration.
The
.envfile to be at same level ofdocker-compose.yml:Build the release with:
Run the release with:
I also use a Docker image based on the official guide, but I have fixed the insecure use of
nobodyuser:My Dockerfile:
benwilson512
Can you dump the contents of the migrations table and make sure somehow those rows didn’t get added?
terenceponce
Your suggestion made me look back at my Dockerfile line by line and I found out that I wasn’t actually copying the
privfolder.Rookie mistake, but it’s fixed now. I even removed the use of
nobodyas mentioned in the link that you shared.Here is the final Dockerfile that I’m using now: