如何在 Ubuntu 16.04 上使用 MySQL 部署 Elixir-Phoenix 应用程序

作者选择了 Code.org作为 Write for Donations计划的一部分,以获得 300 美元的捐款。

介绍

在教程中(https://andsky.com/tech/tutorials/how-to-automate-elixir-phoenix-deployment-with-distillery-and-deliver-on-ubuntu-16-04),您创建了一个没有数据库的Phoenix应用程序,并将其部署到一个生产服务器上(https://github.com/deliver/deliver).大多数现实世界的应用程序需要一个数据库,需要对部署过程进行一些修改。

您可以使用 edeliver 同时将应用程序和数据库更改推向生产服务器,以便在部署期间管理数据库更改。

在本指南中,您将配置现有 Phoenix 应用程序以使用 Phoenix-EctoMariaex连接到 MySQL 数据库。 Ecto 是一个为 Phoenix 应用程序广泛使用的数据库包装程序。 Mariaex 是一个与 Ecto 集成并与 MySQL 和 MariaDB 数据库进行交谈的数据库驱动程序。

您还将在您的开发机器上创建一个简单的地址簿,该地址簿使用数据库,并使用 edeliver 将更改部署到您的生产服务器上。

前提条件

要完成本教程,您将需要:

  • 联合国 完成的凤凰网应用程序来自教程[如何用Distillery和edeliver自動放出Elixir凤凰网部署 (https://andsky.com/tech/tutorials/how-to-automate-elixir-phoenix-deployment-with-distillery-and-edeliver-on-ubuntu-16-04). 这个应用程序应该使用Let's加密证书运行在Nginx后面,并和edelivers一起被部署.
  • MySQL通过跟随如何在Ubuntu 16.04上安装 MySQL而安装在您的服务器上.
  • MySQL 安装在您的本地开发机上,以便在部署之前测试数据库。 .

步骤1 — 将Mariaex和Ecto添加到您的应用程序中

通常情况下,Phoenix 应用程序不会直接建立连接到数据库并执行 SQL 查询,而是使用 database driver 连接到所需的数据库,然后使用 database wrapper 查询数据库。

数据库驱动程序是一个Elixir应用程序,它负责使用数据库的日常任务,如建立连接,关闭连接和执行查询。数据库包装程序是数据库驱动程序的顶部的一层,允许Elixir程序员使用Elixir代码创建数据库查询,并提供查询组成(查询链)等额外功能。

数据库包装器,因此与数据库互动的应用程序代码,在很大程度上是相同的,无论使用的数据库。

由于您在创建应用程序时提供了),该应用程序既没有Ecto也没有Mariaex安装。您现在将在您的项目中添加Ecto和Mariaex作为依赖。

注意:Phoenix 应用程序默认使用 PostgreSQL. 使用 MySQL 数据库生成新应用程序,请使用命令 mix phx.new --database mysql myproject

首先,切换到包含您的Phoenix项目的目录。

1[environment local]
2cd ~/myproject

然后打开mix.exs文件,其中包含您的应用程序的依赖列表。

1[environment local]
2nano mix.exs

查找以下代码块:

 1[label ~/myproject/mix.exs]
 2  defp deps do
 3    [
 4      {:phoenix, "~> 1.3.0"},
 5      {:phoenix_pubsub, "~> 1.0"},
 6      {:phoenix_html, "~> 2.10"},
 7      {:phoenix_live_reload, "~> 1.0", only: :dev},
 8      {:gettext, "~> 0.11"},
 9      {:cowboy, "~> 1.0"},
10      {:edeliver, "~> 1.4.3"},
11      {:distillery, "~> 1.4"}
12    ]
13  end

将Mariaex和Phoenix-Ecto添加为依赖:

 1[label ~/myproject/mix.exs]
 2  defp deps do
 3    [
 4      {:phoenix, "~> 1.3.0"},
 5      {:phoenix_pubsub, "~> 1.0"},
 6      {:phoenix_html, "~> 2.10"},
 7      {:phoenix_live_reload, "~> 1.0", only: :dev},
 8      {:gettext, "~> 0.11"},
 9      {:cowboy, "~> 1.0"},
10      {:edeliver, "~> 1.4.3"},
11      {:distillery, "~> 1.4"},
12      {:phoenix_ecto, "~> 3.2"},
13      {:mariaex, "~> 0.8.2"}
14    ]
15  end

<$>[警告] 警告: 为了避免潜在的配置问题,请双重检查您在前一条行末尾已添加一个字符号(,),然后输入新的phoenix_ecto

保存并关闭mix.exs. 然后运行以下命令来下载您刚刚添加到项目的依赖。

1[environment local]
2mix deps.get

您将看到此输出,当您的依赖安装时:

 1[environment local]
 2[secondary_label Output]
 3Running dependency resolution...
 4...
 5* Getting phoenix_ecto (Hex package)
 6  Checking package (https://repo.hex.pm/tarballs/phoenix_ecto-3.3.0.tar)
 7  Fetched package
 8* Getting mariaex (Hex package)
 9  Checking package (https://repo.hex.pm/tarballs/mariaex-0.8.3.tar)
10  Fetched package
11...

输出显示,Mix 检查了包之间的兼容性,并从 Hex 存储库中获得了包和它们的依赖性。

有了 Ecto 和 Mariaex,您可以设置 Ecto 存储库。

步骤 2 — 在您的应用程序中设置 Ecto 存储库

Phoenix 应用程序通过名为 Ecto 的数据库包装器访问数据库。数据库包装器在您的项目中以 Elixir 模块的形式实现。您可以随时导入此模块,以便与数据库进行交互,并使用该模块提供的功能。

此存储模块必须包含Ecto.Repo宏,以提供访问 Ecto 定义的查询函数,此外,它还必须包含代码,以在名为init的函数中初始化传递给数据库适配器的选项。

如果您在创建Phoenix项目时没有使用 - no-ecto旗帜,Phoenix 会自动为您生成此模块。

让我们在lib/myproject目录中创建一个名为repo.ex的文件中的模块。

1[environment local]
2nano lib/myproject/repo.ex

将下列代码添加到文件中以定义存储库:

 1[label ~/myproject/lib/myproject/repo.ex]
 2defmodule Myproject.Repo do
 3  use Ecto.Repo, otp_app: :myproject
 4
 5  @doc """
 6  Dynamically loads the repository url from the
 7  DATABASE_URL environment variable.
 8  """
 9  def init(_, opts) do
10    {:ok, Keyword.put(opts, :url, System.get_env("DATABASE_URL"))}
11  end
12end

默认情况下,Phoenix 项目定义了)。

保存并关闭repo.ex

Phoenix 项目使用轻量级 Elixir 流程来协同和故障容忍。 Supervisors 管理这些流程并重新启动它们,如果它们崩溃。

您刚刚添加的Myproject.Repo模块实现了一个管理员,管理连接到数据库的流程. 要启动这个管理员,您必须将其添加到项目的监督树。

lib/myproject文件夹中打开application.ex文件。

1[environment local]
2nano lib/myproject/application.ex

查找以下定义监督树的代码块:

1[label ~/myproject/lib/myproject/application.ex]
2...
3    children = [
4      # Start the endpoint when the application starts
5      supervisor(MyprojectWeb.Endpoint, []),
6      ...
7    ]
8...

您可以看到应用程序终端MyprojectWeb.Endpoint正在作为管理员启动,并将Myproject.Repo添加到此列表中:

1[label ~/myproject/lib/myproject/myproject.ex]
2    children = [
3      # Start the Ecto repository
4      supervisor(Myproject.Repo, []),
5      # Start the endpoint when the application starts
6      supervisor(MyprojectWeb.Endpoint, []),
7      ...
8    ]

如果您跳过此步骤,ECTO 将不会创建与数据库互动的流程,任何尝试与数据库互动都会导致应用程序崩溃。

保存并关闭application.ex在继续之前。

最后,在应用程序配置中指定 Ecto 存储库,以便您可以使用ecto.createecto.migrate等混合任务来创建和管理数据库。

打开配置文件在config/config.exs

1[environment local]
2nano config/config.exs

在文件的末尾找到下列行:

1[label ~/myproject/config/config.exs]
2import_config "#{Mix.env}.exs"

此行允许环境特定的配置文件,如prod.exstest.exs,在必要时取代config.exs中的设置。

1[label ~/myproject/config/config.exs]
2...
3
4config :myproject,
5  ecto_repos: [Myproject.Repo]
6...

保存您的更改并关闭文件。

现在你已经配置了 Ecto,继续将数据库凭据添加到应用程序中。

步骤 3 – 使用 MySQL 凭证配置您的应用程序

有三种情况下,您的应用程序会连接到数据库:开发过程中,测试过程中和生产过程中。

相应地,Phoenix提供三个环境特定的配置文件,其中包含与应用程序运行环境相关的身份证件. 这些文件位于项目根中的config目录中。

首先,让我们配置开发环境,打开dev.exs。

1[environment local]
2nano config/dev.exs

添加以下行来配置数据库适配器为Ecto.Adapters.MySQL,因为我们正在使用MySQL。

1[label ~/myproject/config/dev.exs]
2config :myproject, Myproject.Repo,
3  adapter: Ecto.Adapters.MySQL

接下来,在相同的代码块中指定所需的数据库名称。

1[label ~/myproject/config/dev.exs]
2config :myproject, Myproject.Repo,
3  adapter: Ecto.Adapters.MySQL,
4  database: "myproject_dev"

在这里,我们将开发数据库名称定义为「myproject_dev」。 这是 Phoenix 应用程序用于数据库的命名惯例。 按照这一惯例,生产数据库将被命名为「myproject_prod」和测试数据库为「myproject_test」。

现在,为您的开发数据库服务器提供主机名、用户名和密码。

1[label ~/myproject/config/dev.exs]
2config :myproject, Myproject.Repo,
3  adapter: Ecto.Adapters.MySQL,
4  database: "myproject_dev",
5  username: "root",
6  password: "password",
7  hostname: "localhost"

最后,将池大小设置为适当的数目。池大小是应用程序可以拥有的数据库连接的最大数目。这些连接将通过请求共享。

1[label ~/myproject/config/dev.exs]
2config :myproject, Myproject.Repo,
3  adapter: Ecto.Adapters.MySQL,
4  username: "root",
5  password: "password",
6  database: "myproject_dev",
7  hostname: "localhost",
8  pool_size: 10

保存并关闭dev.exs

接下来,配置测试环境,打开测试环境配置文件 test.exs

1[environment local]
2nano config/test.exs

在本教程中,我们将在开发数据库旁边的本地数据库服务器上托管测试数据库,因此,测试数据库的配置几乎相同。

然而,而不是池尺寸,我们将为池值指定Ecto.Adapters.SQL.Sandbox。这将以沙盒模式运行测试,也就是说,在测试过程中与测试数据库进行的任何交易都将被回滚,这意味着单元测试可以以随机顺序运行,因为数据库在每个测试后被重置到初始状态。

我们将使用myproject_test作为数据库名称。

将以下配置添加到 test.exs 文件中:

1[label ~/myproject/config/test.exs]
2config :myproject, Myproject.Repo,
3  adapter: Ecto.Adapters.MySQL,
4  username: "root",
5  password: "password",
6  database: "myproject_test",
7  hostname: "localhost",
8  pool: Ecto.Adapters.SQL.Sandbox

保存并关闭test.exs

最后,要配置生产中的应用程序的凭据,请打开您的生产秘密文件,‘prod.secret.exs’。

1[environment local]
2nano config/prod.secret.exs

将此代码添加到 prod.secret.exs 文件中. 请注意,我们在这里使用用户名 myproject 和密码 password. 我们将很快在生产数据库服务器上创建此用户,使用这里指定的密码。

1[label ~/myproject/config/prod.secret.exs]
2config :myproject, Myproject.Repo,
3  adapter: Ecto.Adapters.MySQL,
4  username: "myapp",
5  password: "password",
6  database: "myproject_prod",
7  hostname: "localhost",
8  pool_size: 10

保存您的更改并关闭文件。

由于安全原因,Git 不会跟踪此文件,因此您必须将其手动传输到服务器上。 有关此过程的更多信息,请参阅前提第 3 步 关于部署 Phoenix 应用程序的教程

1[environment local]
2scp ~/myproject/config/prod.secret.exs sammy@your_server_ip:/home/sammy/app_config/prod.secret.exs

然后调用ecto.create混合任务来创建开发数据库. 请注意,您不需要创建测试数据库,因为当您运行测试时,Phoenix 会为您这样做。

1[environment local]
2mix ecto.create

您将看到以下输出显示 Ecto 已成功创建数据库:

1[environment local]
2[secondary_label Output]
3...
4The database for Myproject.Repo has been created

如果您看不到此输出,请确保您的配置详细信息正确,并且MySQL正在运行,如果您的应用程序由于任何错误而无法编译,ECTO也会拒绝创建数据库。

现在您已经设置了连接到数据库的项目,甚至使用 Ecto 在开发机器中创建数据库,您可以继续在服务器上修改数据库。

第4步:创建生产数据库

通过ecto.create混合任务,您在您的开发机器上创建了一个空的数据库,现在,您将为您的生产服务器做同样的事情。不幸的是,没有任何混合任务或 edeliver 命令来帮助我们实现这一点,所以您将手动登录到服务器并使用 MySQL 控制台创建一个空的数据库,使用 SQL 命令。

通过SSH连接到服务器。

1[environment local]
2ssh sammy@your_server_ip

现在使用您配置的 root 用户和密码访问 MySQL 控制台。

1mysql -u root -p

一旦登录,创建生产数据库:

1CREATE DATABASE myproject_prod;

您将看到以下输出,告知您创建了数据库:

1[secondary_label Output]
2Query OK, 1 row affected (0.00 sec)

接下来,使用用户名 myproject 和您在上一个步骤中指定的密码创建应用程序的用户:

1CREATE USER 'myproject'@'localhost' IDENTIFIED BY 'password';

然后给 myproject 用户访问您创建的数据库:

1GRANT ALL PRIVILEGES ON myproject_prod.* to 'myproject'@'localhost';

最后,应用许可变更:

1FLUSH PRIVILEGES;

通过键入exit来退出MySQL控制台;通过再次键入exit来终止SSH连接。

从现在开始,您很少需要触摸生产数据库,因为您将从本地机器执行几乎所有操作,例如创建和更改表。

随着生产数据库的准备,您可以将应用程序重新部署到服务器。

步骤5:将项目部署到服务器

在此步骤中,您将用新配置的应用程序和其新的 Ecto 存储库代替没有连接到数据库的运行应用程序。

打开「mix.exs」并增加应用程序版本. 版本号使您更容易追踪版本,并在必要时返回以前的版本。

1[environment local]
2nano mix.exs

将版本字段增加到适当的值。

 1[label ~/myproject/mix.exs]
 2  def project do
 3    [
 4      app: :myproject,
 5      version: "0.0.3",
 6      elixir: "~> 1.4",
 7      elixirc_paths: elixirc_paths(Mix.env),
 8      compilers: [:phoenix, :gettext] ++ Mix.compilers,
 9      start_permanent: Mix.env == :prod,
10      deps: deps()
11    ]
12  end

为了使用 edeliver 进行数据库迁移, edeliver 必须是您项目中启动的最后一个应用程序。

1[label ~/myproject/mix.exs]
2  def application do
3    [
4      mod: {Myproject.Application, []},
5      extra_applications: [:logger, :runtime_tools]
6    ]
7  end

deliver添加到extra_applications列表的末尾:

1[label ~/myproject/mix.exs]
2  def application do
3    [
4      mod: {Myproject.Application, []},
5      extra_applications: [:logger, :runtime_tools, :edeliver]
6    ]
7  end

保存并关闭mix.exs

启动应用程序以确保一切正常工作,并且没有编译错误:

1[environment local]
2mix phx.server

请访问 http://localhost:4000/addresses以确保应用程序仍然工作. 如果它没有启动,或者您看到编译错误,请查看本教程中的步骤,并在继续前解决它们。

如果一切按照预期工作,请在终端中两次按CTRL+C,以停止服务器。

你必须每次对你的项目做出更改,因为 edeliver 使用 Git 将代码从最新的 commit 推到构建服务器,以便采取进一步的行动。

1[environment local]
2git add .
3git commit -m "Configured application with database"

最后,使用 edeliver 来更新生产服务器上的应用程序. 以下命令将构建和部署您项目的最新版本,然后升级在生产机器上运行的应用程序,无需停机时间。

1[environment local]
2mix edeliver upgrade production

您将看到以下输出:

 1[environment local]
 2[secondary_label Output]
 3EDELIVER MYPROJECT WITH UPGRADE COMMAND
 4
 5-----> Upgrading to revision 2512398 from branch master
 6-----> Detecting release versions on production hosts
 7-----> Deploying upgrades to 1 online hosts
 8-----> Checking whether installed version 0.0.2 is in release store
 9-----> Building the upgrade from version 0.0.2
10-----> Authorizing hosts
11-----> Validating * version 0.0.2 is in local release store
12-----> Ensuring hosts are ready to accept git pushes
13-----> Pushing new commits with git to: sammy@example.com
14-----> Resetting remote hosts to 2512398838c2dcc43de3ccd869779dded4fd5b6b
15-----> Cleaning generated files from last build
16-----> Checking out 2512398838c2dcc43de3ccd869779dded4fd5b6b
17-----> Fetching / Updating dependencies
18-----> Compiling sources
19-----> Checking version of new release
20-----> Uploading archive of release 0.0.2 from local release store
21-----> Extracting archive myproject_0.0.2.tar.gz
22-----> Removing old releases which were included in upgrade package
23-----> Generating release
24-----> Removing built release 0.0.2 from remote release directory
25-----> Copying release 0.0.3 to local release store
26-----> Copying myproject.tar.gz to release store
27-----> Upgrading production hosts to version 0.0.3
28-----> Authorizing hosts
29-----> Uploading archive of release 0.0.3 from local release store
30-----> Upgrading release to 0.0.3
31
32UPGRADE DONE!

尽管升级已成功完成,但在重新启动应用程序之前,您将无法运行与数据库相关的 edeliver 任务。

警告:下列命令将导致您的应用程序暂时离线。

1[environment local]
2mix edeliver restart production

你会看到这个输出:

 1[environment local]
 2[secondary_label Output]
 3EDELIVER MYPROJECT WITH RESTART COMMAND
 4
 5-----> restarting production servers
 6
 7production node:
 8
 9  user    : sammy
10  host    : example.com
11  path    : /home/sammy/app_release
12  response: ok
13
14RESTART DONE!

edeliver告诉我们,它已经成功重新启动了生产服务器。

若要确保您的应用程序已升级,请运行以下 edeliver 命令以获取目前正在生产中的应用程序版本。

1[environment local]
2mix edeliver version production
 1[environment local]
 2[secondary_label Output]
 3EDELIVER MYPROJECT WITH VERSION COMMAND
 4
 5-----> getting release versions from production servers
 6
 7production node:
 8
 9  user    : sammy
10  host    : example.com
11  path    : /home/sammy/app_release
12  response: 0.0.3
13
14VERSION DONE!

输出告诉我们,生产服务器正在运行应用程序版本0.0.3

您还可以访问您的应用程序在 https://example.com 以确保它正在运行. 该应用程序不应该有任何可观察的变化,因为我们没有触摸应用程序代码本身。

如果升級成功,但無法更新應用程式,請確定您已執行了您的代碼,並且錯過了您的應用程式版本。如果升級命令失敗,edeliver 將發出在伺服器上執行的 bash 代碼,當錯誤發生時,以及錯誤訊息本身。

现在,您已将数据库支持添加到您的应用程序中,并部署到生产中,您现在已经准备好添加一些使用MySQL的功能。

步骤 6 — 创建地址簿

为了展示如何部署数据库更改,让我们在我们的应用程序中构建一个简单的地址簿并部署到生产中。

<$>[警告] 警告: 此地址簿将被公开获取,任何人都可以访问和编辑它. 要么在完成本教程后取消功能,要么添加一个身份验证系统,如 Guardian以限制访问。

代替从头开始编写地址簿的代码,我们会使用 Phoenix 生成器来创建地址簿。Phoenix 生成器是为简单的 CRUD (创建,阅读,更新,删除)功能生成代码的实用工具。这为您可能想要构建的许多应用程序功能提供了良好的起点。

地址簿还需要数据库中的表格来存储条目. 要将这个表格添加到数据库中,您可以构建并执行一个SQL查询,但我们会使用Ecto的迁移特性来修改数据库. 这种做法有一些优点。 首先,它是独立的数据库;无论您正在使用 PostgreSQL 、 MySQL 或其他数据库,这些命令都是一样的。 接下来, 迁移文件提供了一种方便的方法来跟踪您的数据库计划如何随着时间的变化 。 最后,如果需要的话,您也可以将您开发机器上最新的迁移情况卷回.

幸运的是,您不必从头开始写一个迁移文件,因为凤凰发电机将为您制作一个,除非另有说明。

若要使用生成器,请指定背景、实体的单一名称、实体的多重名称以及所有其它字段及其相应类型。

例如,如果您打算保持在您的网站上登录的用户列表和用户登录时的会话日志,那么将用户和会话置于一个单一的会话模块中,名为帐户

请注意,根据惯例,Phoenix假定实体的多重名称是该资源的数据库表的名称。

让我们用生成器创建地址簿 为了使地址簿简单,我们将为每个记录包括三个字段:姓名、电子邮件和ZIP代码. 我们将每条条目称为地址,多个条目称为地址,而地址簿应居住的背景称为地址簿

运行此命令来生成地址簿:

1[environment local]
2mix phx.gen.html AddressBook Address addresses name:string email:string zip_code:integer
 1[environment local]
 2[secondary_label Output]
 3* creating lib/myproject_web/controllers/address_controller.ex
 4...
 5* creating priv/repo/migrations/20180318032834_create_address.exs
 6
 7Add the resource to your browser scope in web/router.ex:
 8
 9    resources "/addresses", AddressController
10
11Remember to update your repository by running migrations:
12
13    $ mix ecto.migrate

Phoenix告诉我们,它自动生成了模板文件、测试文件、模型、控制器和迁移文件,并指示我们将资源添加到路由器文件并更新存储库。

您可以遵循输出中所看到的指示,但这样做会将应用程序代码升级和数据库迁移组合到一个版本中,这可能会导致应用程序的某些部分在应用程序部署到生产服务器时到生产数据库迁移时在生产中失败。

若要防止停机时间和错误,请在两个步骤中部署更改:

  1. 添加数据库迁移文件以对数据库进行必要的更改,而不对应用程序代码进行更改. 创建版本,升级生产服务器并迁移生产数据库。

如果我们不采取这种方法,地址簿的代码将尝试引用我们尚未创建的地址表,我们的应用程序将崩溃。

在我们迁移生产数据库之前,让我们看看迁移文件. 它位于 priv/repo/migrations/20180501040548_create_addresses.exs,尽管文件名将根据您创建时具有不同的数据印章。

1[environment local]
2nano priv/repo/migrations/*_create_addresses.exs

Phoenix 生成的迁移文件是一个 Elixir 模块,有一个名为更改的函数。

 1[label ~/myproject/priv/repo/migrations/20180501040548_create_addresses.exs]
 2defmodule Myproject.Repo.Migrations.CreateAddresses do
 3  use Ecto.Migration
 4
 5  def change do
 6    create table(:addresses) do
 7      add :name, :string
 8      add :email, :string
 9      add :zip_code, :integer
10
11      timestamps()
12    end
13
14  end
15end

在此函数中,Phoenix 生成器已经编写了代码,以创建)函数,为您添加了两个字段:inserted_atupdated_at`. 在这些字段中存储的值在输入或更新数据时自动更新。

关闭文件而不做任何更改;生成的代码是你所需要的。

要只部署迁移文件而不包括应用程序代码,我们将利用 edeliver 使用 Git 将我们的项目传输到构建服务器。

但是,在您可以这样做之前,请在mix.exs 中增加应用程序版本。Edeliver 使用版本号为准备热升级,因此您需要为每个更新增加版本号。

打开mix.exs

1[environment local]
2nano mix.exs

将应用程序版本增加到适当的值。

1[label ~/myproject/mix.exs]
2  def project do
3    [
4      app: :myproject,
5      version: "0.0.4",
6      ...

保存并关闭文件。

现在,使用Git来阶段mix.exs文件和迁移文件。

1[environment local]
2git add mix.exs priv/repo/migrations/*_create_addresses.exs

接下來,執行階段檔案。

1[environment local]
2git commit -m "Adding addresses table to the database"

与此同时,用 edeliver 升级您的生产应用程序。

1[environment local]
2mix edeliver upgrade production

升级完成后,执行以下 edeliver 命令来迁移生产数据库。

1[environment local]
2mix edeliver migrate production

输出显示迁移成功运行,并显示迁移文件的时刻标记:

 1[secondary_label Output]
 2[environment local]
 3EDELIVER MYPROJECT WITH MIGRATE COMMAND
 4
 5-----> migrateing production servers
 6
 7production node:
 8
 9  user    : sammy
10  host    : example.com
11  path    : /home/sammy/app_release
12  response: [20180501040548]
13
14MIGRATE DONE!

生产数据库现在有一个名为地址的空表。

如果没有运行过迁移,则响应字段会显示[]。如果是这样的情况,请确保您在重新升级之前使用了 Git 代码。如果问题仍然存在,请通过键入mix edeliver 重新启动生产来重新启动生产应用程序,然后重新运行数据库迁移任务。

有了地址表,我们可以继续遵循Phoenix在生成地址簿时发出的指示,并创建一个新版本。

首先,打开lib/myproject_web/router.ex文件:

1[environment local]
2nano lib/myproject_web/router.ex

查找以下代码块:

1[label ~/myproject/lib/myproject_web/router.ex]
2  scope "/", MyprojectWeb do
3    pipe_through :browser 
4
5    get "/", PageController, :index
6  end

插入地址资源的路线:

1[label ~/myproject/lib/myproject_web/router.ex]
2  scope "/", MyprojectWeb do
3    pipe_through :browser 
4
5    get "/", PageController, :index
6    resources "/addresses", AddressController
7  end

保存并关闭router.ex

接下来,请 Ecto 对本地数据库进行更改。

1[environment local]
2mix ecto.migrate

输出显示,迁移文件中的函数被召唤,成功创建了表地址

1[environment local]
2[secondary_label Output]
3...
4[info] == Running Myproject.Repo.Migrations.CreateAddresses.change/0 forward
5[info] create table addresses
6[info] == Migrated in 0.0s

现在启动本地开发服务器来测试您的新功能:

1[environment local]
2mix phx.server

点击您的浏览器在 http://localhost:4000/addresses看到新的功能在行动。

当您确定事物在本地工作时,请返回终端并按两次CTRL+C来终止服务器。

现在工作了,您可以将更改部署到生产中. 打开「mix.exs」以更新应用程序版本。

1[environment local]
2nano mix.exs

将版本字段增加到适当的值。

 1[label ~/myproject/mix.exs]
 2  def project do
 3    [
 4      app: :myproject,
 5      version: "0.0.5",
 6      elixir: "~> 1.4",
 7      elixirc_paths: elixirc_paths(Mix.env),
 8      compilers: [:phoenix, :gettext] ++ Mix.compilers,
 9      start_permanent: Mix.env == :prod,
10      deps: deps()
11    ]
12  end

保存并关闭mix.exs

用 Git 承诺你的更改,这一次,阶段所有文件。

1[environment local]
2git add .
3git commit -m "Added application code for address book"

用 edeliver 升级生产应用程序。

1[environment local]
2mix edeliver upgrade production

更新完成后,您可以访问新功能在https://example.com/addresses

有了它,您已经成功地升级了生产应用程序和数据库。

结论

在本文中,您将您的Phoenix应用程序配置为使用MySQL数据库,并使用edeliver和Ecto迁移来对生产数据库进行更改. 使用此方法,您无需触摸生产数据库,您想要对生产数据库进行任何更改都是通过Ecto迁移文件进行的。

要了解更多关于 Ecto 迁移和如何执行复杂的数据库操作,请参阅 官方 Ecto 迁移文件

Published At
Categories with 技术
comments powered by Disqus