如何使用 elixir phoenix 版本和指南中的示例 MyApp.Release.rollback 在 docker 容器中回滚数据库
How to rollback database in docker container using elixir phoenix releases and the example MyApp.Release.rollback in the guides
当我试图通过 docker 容器中的 phoenix 应用程序 运行ning 回滚数据库时,我不知道如何回滚数据库。我正在尝试在本地模拟在远程服务器上迁移时的情况。
我 运行在本地 运行ning:
docker run -it -p 4000:4000 -e DATABASE_URL=ecto://postgres:postgres@host.docker.internal/my_app_dev -e SECRET_KEY_BASE=blahblah my-app-tag:v1
我查看 运行ning 容器:
docker ps
我bash进容器
docker exec -it 8943918c8f4f /bin/bash
cd 进入 app/bin
cd bin
尝试回滚
./my_app rpc 'MyApp.Release.rollback(MyApp.Repo, "20191106071140")'
=> 08:43:45.516 [info] Already down
如果这在 运行 通过应用程序时确实有效,它应该在我做不同的事情时爆炸。但事实并非如此。
如果我尝试 eval
./my_app eval 'MyApp.Release.rollback(MyApp.Repo, "20191106071140")'
=>
08:46:22.033 [error] GenServer #PID<0.207.0> terminating
** (RuntimeError) connect raised KeyError exception: key :database not found. The exception details are hidden, as they may contain sensitive data such as database credentials. You may set :show_sensitive_data_on_connection_error to true when starting your connection if you wish to see all of the details
(elixir) lib/keyword.ex:393: Keyword.fetch!/2
(postgrex) lib/postgrex/protocol.ex:92: Postgrex.Protocol.connect/1
(db_connection) lib/db_connection/connection.ex:69: DBConnection.Connection.connect/2
(connection) lib/connection.ex:622: Connection.enter_connect/5
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: nil
** (EXIT from #PID<0.163.0>) shutdown
我试图确保我知道如何将应用程序部署到远程(Heroku、AWS)并让应用程序在每次部署时自动迁移,但也可以选择 运行 回滚命令一次 1 个步骤。
我没有找到任何信息。上面的调试是在远程服务器上创建此 migrate/rollback 功能的第一步,但首先在我的本地计算机上进行测试。
migrate/rollback代码直接取自https://hexdocs.pm/phoenix/releases.html#ecto-migrations-and-custom-commands
任何 help/direction 将不胜感激。
谢谢
首先,rpc
调用应该会成功。确保在 运行 my_app rpc
之前确实在问题 up 中进行了迁移。 请注意,第二个参数是要恢复到的版本,而不是要恢复的迁移。
关于eval
。在尝试访问其配置之前,应该 start
或至少 load
应用程序。根据 documentation:
You can start an application by calling Application.ensure_all_started/1
. However, if for some reason you cannot start an application, maybe because it will run other services you do not want, you must at least load the application by calling Application.load/1
. If you don't load the application, any attempt at reading its environment or configuration may fail. Note that if you start an application, it is automatically loaded before started.
要成功迁移,需要 Ecto
应用程序 Ecto.Adapters.SQL.Application
已启动 并且 您的应用程序已加载(以访问配置。)
就是说,这样的事情应该可行。
def my_rollback(version) do
Application.load(:my_app)
Application.ensure_all_started(:ecto_sql)
Ecto.Migrator.with_repo(MyApp.Repo,
&Ecto.Migrator.run(&1, :down, to: version))
end
并将其命名为
./my_app eval 'MyApp.Release.my_rollback(20191106071140)'
不过,rpc
应该开箱即用地启动所需的应用程序(根据您收到的消息,确实如此)所以我建议您三重检查您的迁移请求降级已经启动,您传递了要降级到的正确版本。
这里有两个问题,感谢@aleksei-matiushkin,我让它工作了。
第一个问题是函数中没有 Application.load(:my_app)
。
第二个问题是我将回滚函数(我的和@aleksei-matiushkin)作为字符串而不是 int 调用。现在我这样称呼它:./my_app eval 'MyApp.Release.my_rollback(20191106071140)'
文件现在看起来像这样:
defmodule MyApp.Release do
@app :my_app
def migrate do
for repo <- repos() do
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
end
end
def rollback(repo, version) do
setup_for_rollback()
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version))
end
def my_rollback(version) do
setup_for_rollback()
rollback(MyApp.Repo, version)
end
defp setup_for_rollback() do
Application.load(@app)
Application.ensure_all_started(:ecto_sql)
end
defp repos do
Application.load(@app)
Application.fetch_env!(@app, :ecto_repos)
end
end
我不确定这是否是惯用的实现。除了 Application.ensure_all_started(:ecto_sql)
之外,我没有任何问题,但由于有人推荐我想我会保留它。
当我试图通过 docker 容器中的 phoenix 应用程序 运行ning 回滚数据库时,我不知道如何回滚数据库。我正在尝试在本地模拟在远程服务器上迁移时的情况。
我 运行在本地 运行ning:
docker run -it -p 4000:4000 -e DATABASE_URL=ecto://postgres:postgres@host.docker.internal/my_app_dev -e SECRET_KEY_BASE=blahblah my-app-tag:v1
我查看 运行ning 容器:
docker ps
我bash进容器
docker exec -it 8943918c8f4f /bin/bash
cd 进入 app/bin
cd bin
尝试回滚
./my_app rpc 'MyApp.Release.rollback(MyApp.Repo, "20191106071140")'
=> 08:43:45.516 [info] Already down
如果这在 运行 通过应用程序时确实有效,它应该在我做不同的事情时爆炸。但事实并非如此。
如果我尝试 eval
./my_app eval 'MyApp.Release.rollback(MyApp.Repo, "20191106071140")'
=>
08:46:22.033 [error] GenServer #PID<0.207.0> terminating
** (RuntimeError) connect raised KeyError exception: key :database not found. The exception details are hidden, as they may contain sensitive data such as database credentials. You may set :show_sensitive_data_on_connection_error to true when starting your connection if you wish to see all of the details
(elixir) lib/keyword.ex:393: Keyword.fetch!/2
(postgrex) lib/postgrex/protocol.ex:92: Postgrex.Protocol.connect/1
(db_connection) lib/db_connection/connection.ex:69: DBConnection.Connection.connect/2
(connection) lib/connection.ex:622: Connection.enter_connect/5
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: nil
** (EXIT from #PID<0.163.0>) shutdown
我试图确保我知道如何将应用程序部署到远程(Heroku、AWS)并让应用程序在每次部署时自动迁移,但也可以选择 运行 回滚命令一次 1 个步骤。
我没有找到任何信息。上面的调试是在远程服务器上创建此 migrate/rollback 功能的第一步,但首先在我的本地计算机上进行测试。
migrate/rollback代码直接取自https://hexdocs.pm/phoenix/releases.html#ecto-migrations-and-custom-commands
任何 help/direction 将不胜感激。
谢谢
首先,rpc
调用应该会成功。确保在 运行 my_app rpc
之前确实在问题 up 中进行了迁移。 请注意,第二个参数是要恢复到的版本,而不是要恢复的迁移。
关于eval
。在尝试访问其配置之前,应该 start
或至少 load
应用程序。根据 documentation:
You can start an application by calling
Application.ensure_all_started/1
. However, if for some reason you cannot start an application, maybe because it will run other services you do not want, you must at least load the application by callingApplication.load/1
. If you don't load the application, any attempt at reading its environment or configuration may fail. Note that if you start an application, it is automatically loaded before started.
要成功迁移,需要 Ecto
应用程序 Ecto.Adapters.SQL.Application
已启动 并且 您的应用程序已加载(以访问配置。)
就是说,这样的事情应该可行。
def my_rollback(version) do
Application.load(:my_app)
Application.ensure_all_started(:ecto_sql)
Ecto.Migrator.with_repo(MyApp.Repo,
&Ecto.Migrator.run(&1, :down, to: version))
end
并将其命名为
./my_app eval 'MyApp.Release.my_rollback(20191106071140)'
不过,rpc
应该开箱即用地启动所需的应用程序(根据您收到的消息,确实如此)所以我建议您三重检查您的迁移请求降级已经启动,您传递了要降级到的正确版本。
这里有两个问题,感谢@aleksei-matiushkin,我让它工作了。
第一个问题是函数中没有 Application.load(:my_app)
。
第二个问题是我将回滚函数(我的和@aleksei-matiushkin)作为字符串而不是 int 调用。现在我这样称呼它:./my_app eval 'MyApp.Release.my_rollback(20191106071140)'
文件现在看起来像这样:
defmodule MyApp.Release do
@app :my_app
def migrate do
for repo <- repos() do
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
end
end
def rollback(repo, version) do
setup_for_rollback()
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version))
end
def my_rollback(version) do
setup_for_rollback()
rollback(MyApp.Repo, version)
end
defp setup_for_rollback() do
Application.load(@app)
Application.ensure_all_started(:ecto_sql)
end
defp repos do
Application.load(@app)
Application.fetch_env!(@app, :ecto_repos)
end
end
我不确定这是否是惯用的实现。除了 Application.ensure_all_started(:ecto_sql)
之外,我没有任何问题,但由于有人推荐我想我会保留它。