_Tác giả được chọn Code.org để nhận khoản đóng góp $ 300 như một phần của Viết cho DOnations chương trình._

Giới thiệu

Trong hướng dẫn Làm thế nào để tự động hóa Elixir Phoenix Deployment với Distillery và edeliver, bạn đã tạo một ứng dụng Phoenix mà không có cơ sở dữ liệu và triển khai nó đến một máy chủ sản xuất với edeliver. Hầu hết các ứng dụng trong thế giới thực đòi hỏi một cơ sở dữ liệu đòi hỏi một số sửa đổi cho quá trình triển khai.

Bạn có thể sử dụng edeliver để đẩy các thay đổi ứng dụng và cơ sở dữ liệu vào máy chủ sản xuất cùng một lúc để bạn có thể quản lý các thay đổi cơ sở dữ liệu trong quá trình triển khai.

Trong hướng dẫn này, bạn sẽ cấu hình ứng dụng Phoenix hiện có của mình để kết nối với cơ sở dữ liệu MySQL bằng cách sử dụng Phoenix-Ecto và Mariaex. Ecto là một trình bao bọc cơ sở dữ liệu được sử dụng rộng rãi cho các ứng dụng Phoenix. Mariaex là một trình điều khiển cơ sở dữ liệu tích hợp với Ecto và nói chuyện với cơ sở dữ liệu MySQL và MariaDB.

Bạn cũng sẽ tạo một sổ địa chỉ đơn giản trên máy phát triển của mình, sử dụng cơ sở dữ liệu và sử dụng trình chỉnh sửa để triển khai các thay đổi cho máy chủ sản xuất của bạn. Người dùng trang web của bạn sẽ có thể tạo, đọc, cập nhật và xóa các mục nhập trong sổ địa chỉ này.

Điều kiện tiên quyết

Để hoàn thành hướng dẫn này, bạn sẽ cần:

  • Ứng dụng Phoenix đã hoàn thành từ hướng dẫn Làm thế nào để tự động hóa Elixir Phoenix Deployment với Distillery và edeliver. Ứng dụng này sẽ chạy phía sau Nginx bằng cách sử dụng chứng chỉ Let's Encrypt và được triển khai với trình chỉnh sửa.
  • MySQL được cài đặt trên máy chủ của bạn bằng cách theo dõi Làm thế nào để cài đặt MySQL trên Ubuntu 16.04.
  • MySQL được cài đặt trên máy phát triển cục bộ của bạn để kiểm tra cơ sở dữ liệu trước khi bạn triển khai.

Bước 1 - Thêm Mariaex và Ecto vào ứng dụng của bạn

Thông thường, các ứng dụng Phoenix không trực tiếp thiết lập các kết nối tới cơ sở dữ liệu và thực thi các truy vấn SQL. Thay vào đó, một điều khiển cơ sở dữ liệu được sử dụng để kết nối với cơ sở dữ liệu mong muốn và trình bao bọc cơ sở dữ liệu sau đó được sử dụng để truy vấn cơ sở dữ liệu.

Trình điều khiển cơ sở dữ liệu là một ứng dụng Elixir quản lý các nhiệm vụ trần tục khi sử dụng cơ sở dữ liệu như thiết lập kết nối, đóng kết nối và thực thi truy vấn. Trình bao bọc cơ sở dữ liệu là lớp trên cùng của trình điều khiển cơ sở dữ liệu cho phép các lập trình viên Elixir tạo truy vấn cơ sở dữ liệu bằng mã Elixir và cung cấp các tính năng bổ sung như thành phần truy vấn (chuỗi truy vấn).

Sự tách biệt này tạo ra một ứng dụng mô-đun. Trình bao bọc cơ sở dữ liệu và do đó mã ứng dụng tương tác với cơ sở dữ liệu, phần lớn là giống nhau bất kể cơ sở dữ liệu được sử dụng. Chỉ bằng cách thay đổi trình điều khiển cơ sở dữ liệu, các ứng dụng Phoenix có thể sử dụng một phần mềm cơ sở dữ liệu khác.

Vì bạn đã cung cấp --no-ecto gắn cờ khi tạo ứng dụng của bạn trong hướng dẫn trước, ứng dụng không cài đặt Ecto và Mariaex. Bạn sẽ thêm Ecto và Mariaex làm phụ thuộc vào dự án của bạn ngay bây giờ.

Chú thích: Các ứng dụng Phoenix sử dụng PostgreSQL theo mặc định. Để tạo một ứng dụng mới với cơ sở dữ liệu MySQL, hãy sử dụng lệnh mix phx.new --database mysql myproject.

Đầu tiên, chuyển sang thư mục chứa dự án Phoenix của bạn.

cd ~/myproject

Sau đó mở mix.exs tệp chứa danh sách phụ thuộc cho ứng dụng của bạn.

nano mix.exs

Tìm khối mã sau:

~/myproject/mix.exs

  defp deps do
    [
      {:phoenix, "~> 1.3.0"},
      {:phoenix_pubsub, "~> 1.0"},
      {:phoenix_html, "~> 2.10"},
      {:phoenix_live_reload, "~> 1.0", only: :dev},
      {:gettext, "~> 0.11"},
      {:cowboy, "~> 1.0"},
      {:edeliver, "~> 1.4.3"},
      {:distillery, "~> 1.4"}
    ]
  end

Thêm Mariaex và Phoenix-Ecto làm phụ thuộc:

~/myproject/mix.exs

  defp deps do
    [
      {:phoenix, "~> 1.3.0"},
      {:phoenix_pubsub, "~> 1.0"},
      {:phoenix_html, "~> 2.10"},
      {:phoenix_live_reload, "~> 1.0", only: :dev},
      {:gettext, "~> 0.11"},
      {:cowboy, "~> 1.0"},
      {:edeliver, "~> 1.4.3"},
      {:distillery, "~> 1.4"},
      {:phoenix_ecto, "~> 3.2"},
      {:mariaex, "~> 0.8.2"}
    ]
  end

Cảnh báo: Để tránh các vấn đề về cấu hình tiềm ẩn, hãy kiểm tra kỹ xem bạn đã thêm dấu phẩy (,) vào cuối dòng trước dấu phẩy mới chưa phoenix_ecto mục nhập.

Lưu và đóng mix.exs. Sau đó chạy lệnh sau để tải xuống các phụ thuộc bạn vừa thêm vào dự án.

mix deps.get

Bạn sẽ thấy đầu ra này khi các phụ thuộc của bạn được cài đặt:

OutputRunning dependency resolution...
...
* Getting phoenix_ecto (Hex package)
  Checking package (https://repo.hex.pm/tarballs/phoenix_ecto-3.3.0.tar)
  Fetched package
* Getting mariaex (Hex package)
  Checking package (https://repo.hex.pm/tarballs/mariaex-0.8.3.tar)
  Fetched package
...

Đầu ra cho thấy Mix đã kiểm tra tính tương thích giữa các gói và nhận các gói cùng với các gói phụ thuộc của chúng từ kho lưu trữ Hex. Nếu lệnh này không thành công, hãy đảm bảo rằng bạn đã cài đặt Hex và đã sửa đổi mix.exs đúng.

Với Ecto và Mariaex tại chỗ, bạn có thể thiết lập kho lưu trữ Ecto.

Bước 2 - Thiết lập một kho lưu trữ Ecto trong ứng dụng của bạn

Các ứng dụng Phoenix truy cập cơ sở dữ liệu thông qua một trình bao bọc cơ sở dữ liệu có tên là Ecto. Trình bao bọc cơ sở dữ liệu được thực hiện dưới dạng một mô-đun Elixir trong dự án của bạn. Bạn có thể nhập mô-đun này bất cứ khi nào bạn cần tương tác với cơ sở dữ liệu và sử dụng các chức năng mà mô đun cung cấp. Cơ sở dữ liệu được bao bọc được gọi là kho.

Mô-đun kho này phải bao gồm Ecto.Repo macro để cấp quyền truy cập vào các hàm truy vấn được xác định bởi Ecto. Ngoài ra, nó phải chứa mã để khởi tạo các tùy chọn được chuyển đến bộ điều hợp cơ sở dữ liệu trong một hàm có tên init.

Nếu bạn không sử dụng --no-ecto khi tạo dự án Phoenix, Phoenix sẽ tự động tạo mô-đun này cho bạn. Nhưng kể từ khi bạn đã làm, bạn sẽ phải tạo ra nó cho mình.

Hãy tạo mô-đun trong một tệp có tên repo.ex bên trong lib/myproject danh mục. Đầu tiên tạo tệp:

nano lib/myproject/repo.ex

Thêm mã sau vào tệp để xác định kho lưu trữ:

~/myproject/lib/myproject/repo.ex

defmodule Myproject.Repo do
  use Ecto.Repo, otp_app: :myproject

  @doc """
  Dynamically loads the repository url from the
  DATABASE_URL environment variable.
  """
  def init(_, opts) do
    {:ok, Keyword.put(opts, :url, System.get_env("DATABASE_URL"))}
  end
end

Theo mặc định, các dự án Phoenix xác định init chức năng sao cho nếu biến môi trường DATABASE_URL tồn tại, sau đó Ecto sẽ sử dụng cấu hình trong biến môi trường để kết nối với cơ sở dữ liệu thay vì sử dụng thông tin đăng nhập trong các tệp cấu hình Phoenix (như chúng tôi làm trong hướng dẫn này sau).

Lưu và đóng repo.ex.

Các dự án Phoenix sử dụng các quy trình Elixir nhẹ để đồng thời và chịu lỗi. Giám sát viên quản lý các quy trình này và khởi động lại chúng, nếu chúng bị lỗi. Giám sát viên cũng có thể giám sát các giám sát viên khác và cấu trúc này được gọi là cây giám sát.

Các Myproject.Repo mô-đun bạn vừa thêm thực hiện một người giám sát quản lý các quy trình kết nối với cơ sở dữ liệu. Để bắt đầu người giám sát này, bạn phải thêm nó vào cây giám sát của dự án.

Mở application.ex tập tin trong lib/myproject thư mục.

nano lib/myproject/application.ex

Tìm khối mã sau đây xác định cây giám sát:

~/myproject/lib/myproject/application.ex

...
    children = [
      # Start the endpoint when the application starts
      supervisor(MyprojectWeb.Endpoint, []),
      ...
    ]
...

Bạn có thể thấy rằng điểm cuối ứng dụng, MyprojectWeb.Endpoint, đang được bắt đầu như một người giám sát. Thêm vào Myproject.Repo vào danh sách này:

~/myproject/lib/myproject/myproject.ex

    children = [
      # Start the Ecto repository
      supervisor(Myproject.Repo, []),
      # Start the endpoint when the application starts
      supervisor(MyprojectWeb.Endpoint, []),
      ...
    ]

Nếu bạn bỏ qua bước này, Ecto sẽ không tạo ra các quy trình để tương tác với cơ sở dữ liệu và bất kỳ nỗ lực nào để tương tác với cơ sở dữ liệu sẽ khiến ứng dụng gặp sự cố.

Lưu và đóng application.ex trước khi tiếp tục.

Cuối cùng, chỉ định kho lưu trữ Ecto trong cấu hình ứng dụng để bạn có thể sử dụng các tác vụ Trộn như ecto.createecto.migrate để tạo và quản lý cơ sở dữ liệu của bạn.

Mở tệp cấu hình tại config/config.exs.

nano config/config.exs

Tìm dòng sau ở cuối tệp:

~/myproject/config/config.exs

import_config "#{Mix.env}.exs"

Dòng này cho phép các tệp cấu hình dành riêng cho môi trường, chẳng hạn như prod.exstest.exs, để ghi đè cài đặt trong config.exs Nếu cần. Thêm mã sau ở trên dòng đó để cấu hình kho lưu trữ Ecto:

~/myproject/config/config.exs

...

config :myproject,
  ecto_repos: [Myproject.Repo]
...

Lưu các thay đổi và đóng file.

Bây giờ bạn đã cấu hình Ecto, hãy chuyển sang thêm thông tin đăng nhập cơ sở dữ liệu của bạn vào ứng dụng.

Bước 3 - Cấu hình ứng dụng của bạn với thông tin đăng nhập MySQL

Có ba tình huống trong đó ứng dụng của bạn sẽ kết nối với cơ sở dữ liệu: trong quá trình phát triển, trong quá trình thử nghiệm và trong quá trình sản xuất.

Tương ứng, Phoenix cung cấp ba tệp cấu hình dành riêng cho môi trường có chứa thông tin đăng nhập có liên quan đến môi trường mà ứng dụng đang chạy. Các tệp này nằm trong config thư mục trong thư mục gốc của dự án. Bạn sẽ sửa đổi ba tệp này trong bước này.

Đầu tiên, hãy cấu hình môi trường phát triển. Mở dev.exs.

nano config/dev.exs

Thêm các dòng sau để cấu hình bộ điều hợp cơ sở dữ liệu Ecto.Adapters.MySQL vì chúng tôi đang sử dụng MySQL.

~/myproject/config/dev.exs

config :myproject, Myproject.Repo,
  adapter: Ecto.Adapters.MySQL

Tiếp theo, chỉ định tên cơ sở dữ liệu mong muốn trong cùng một khối mã.

~/myproject/config/dev.exs

config :myproject, Myproject.Repo,
  adapter: Ecto.Adapters.MySQL,
  database: "myproject_dev"

Ở đây, chúng tôi xác định tên cơ sở dữ liệu phát triển myproject_dev. Đây là một quy ước đặt tên ứng dụng Phoenix sử dụng cho cơ sở dữ liệu. Theo quy ước này, cơ sở dữ liệu sản xuất sẽ được gọi là myproject_prod và cơ sở dữ liệu thử nghiệm myproject_test. Thay vào đó, bạn có thể sử dụng lược đồ đặt tên của riêng mình.

Bây giờ, hãy cung cấp tên máy chủ, tên người dùng và mật khẩu cho máy chủ cơ sở dữ liệu phát triển của bạn.

~/myproject/config/dev.exs

config :myproject, Myproject.Repo,
  adapter: Ecto.Adapters.MySQL,
  database: "myproject_dev",
  username: "root",
  password: "password",
  hostname: "localhost"

Cuối cùng, đặt kích thước hồ bơi thành một số thích hợp. Kích thước nhóm là số lượng kết nối tối đa tới cơ sở dữ liệu mà ứng dụng có thể có. Các kết nối này sẽ được chia sẻ qua các yêu cầu. Kích thước tối ưu tùy thuộc vào phần cứng của bạn nhưng bạn có thể sử dụng 10 để bắt đầu.

~/myproject/config/dev.exs

config :myproject, Myproject.Repo,
  adapter: Ecto.Adapters.MySQL,
  username: "root",
  password: "password",
  database: "myproject_dev",
  hostname: "localhost",
  pool_size: 10

Lưu và đóng dev.exs.

Tiếp theo, cấu hình môi trường thử nghiệm của bạn. Mở tệp cấu hình môi trường thử nghiệm test.exs.

nano config/test.exs

Trong hướng dẫn này, chúng tôi sẽ lưu trữ cơ sở dữ liệu thử nghiệm trên máy chủ cơ sở dữ liệu cục bộ cùng với cơ sở dữ liệu phát triển. Như vậy, các cấu hình cho cơ sở dữ liệu thử nghiệm gần như giống nhau.

Thay vì kích thước hồ bơi, tuy nhiên, chúng tôi chỉ định Ecto.Adapters.SQL.Sandbox cho giá trị hồ bơi. Thao tác này sẽ chạy thử nghiệm ở chế độ hộp cát. Nghĩa là, mọi giao dịch được thực hiện với cơ sở dữ liệu thử nghiệm trong khi kiểm tra sẽ được khôi phục. Và điều này có nghĩa là các xét nghiệm đơn vị có thể được chạy theo thứ tự ngẫu nhiên khi cơ sở dữ liệu được đặt lại về trạng thái ban đầu sau mỗi lần kiểm tra.

Và chúng tôi sẽ sử dụng myproject_test làm tên cơ sở dữ liệu.

Thêm cấu hình sau vào test.exs tập tin:

~/myproject/config/test.exs

config :myproject, Myproject.Repo,
  adapter: Ecto.Adapters.MySQL,
  username: "root",
  password: "password",
  database: "myproject_test",
  hostname: "localhost",
  pool: Ecto.Adapters.SQL.Sandbox

Lưu và đóng test.exs.

Cuối cùng, để định cấu hình thông tin đăng nhập cho ứng dụng của bạn trong sản xuất, hãy mở tệp bí mật sản xuất của bạn, prod.secret.exs.

nano config/prod.secret.exs

Thêm mã này vào prod.secret.exs tập tin. Lưu ý rằng chúng tôi đang sử dụng tên người dùng dự án của tôi ở đây với mật khẩu password. . Chúng tôi sẽ sớm tạo người dùng này trên máy chủ cơ sở dữ liệu sản xuất, sử dụng mật khẩu được chỉ định tại đây. Bạn sẽ muốn sử dụng một mật khẩu an toàn hơn ở đây.

~/myproject/config/prod.secret.exs

config :myproject, Myproject.Repo,
  adapter: Ecto.Adapters.MySQL,
  username: "myapp",
  password: "password",
  database: "myproject_prod",
  hostname: "localhost",
  pool_size: 10

Lưu các thay đổi và đóng file.

Tệp này không được Git theo dõi vì lý do bảo mật, vì vậy bạn phải chuyển thủ công tệp đó sang máy chủ. Để biết thêm thông tin về quy trình này, hãy tham khảo bước 3 của điều kiện tiên quyết hướng dẫn triển khai ứng dụng Phoenix.

scp ~/myproject/config/prod.secret.exs sammy@your_server_ip:/home/sammy/app_config/prod.secret.exs

Sau đó gọi ecto.create Trộn nhiệm vụ để tạo cơ sở dữ liệu phát triển. Lưu ý rằng bạn không phải tạo cơ sở dữ liệu thử nghiệm vì Phoenix sẽ làm điều đó cho bạn khi bạn chạy thử nghiệm của mình.

mix ecto.create

Bạn sẽ thấy kết quả đầu ra dưới đây cho thấy Ecto đã tạo thành công cơ sở dữ liệu:

Output...
The database for Myproject.Repo has been created

Nếu bạn không thấy kết quả này, hãy đảm bảo rằng các chi tiết cấu hình của bạn là chính xác và MySQL đang chạy. Ecto cũng sẽ từ chối tạo cơ sở dữ liệu nếu ứng dụng của bạn không biên dịch được do bất kỳ lỗi nào.

Bây giờ bạn đã thiết lập dự án để kết nối với một cơ sở dữ liệu và thậm chí sử dụng Ecto để tạo một cơ sở dữ liệu trong máy phát triển, bạn có thể tiến hành sửa đổi cơ sở dữ liệu trên máy chủ.

Bước 4 - Thiết lập cơ sở dữ liệu sản xuất

Với ecto.create Trộn nhiệm vụ, bạn đã tạo một cơ sở dữ liệu trống trên máy phát triển của mình. Bây giờ, bạn sẽ làm tương tự cho máy chủ sản xuất của bạn. Thật không may, không có bất kỳ lệnh Mix hoặc lệnh edeliver nào để giúp chúng ta đạt được điều này, vì vậy bạn sẽ đăng nhập vào máy chủ theo cách thủ công và tạo một cơ sở dữ liệu rỗng với các lệnh SQL bằng cách sử dụng bàn điều khiển MySQL.

Kết nối với máy chủ thông qua SSH.

ssh sammy@your_server_ip

Bây giờ truy cập vào giao diện điều khiển MySQL bằng cách sử dụng nguồn gốc người dùng và mật khẩu bạn đã định cấu hình.

mysql -u root -p

Sau khi đăng nhập, tạo cơ sở dữ liệu sản xuất:

CREATE DATABASE myproject_prod;

Bạn sẽ thấy đầu ra sau, cho bạn biết cơ sở dữ liệu đã được tạo:

OutputQuery OK, 1 row affected (0.00 sec)

Tiếp theo, tạo người dùng cho ứng dụng, sử dụng tên người dùng dự án của tôi và mật khẩu bạn đã chỉ định ở bước trước:

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

Sau đó cung cấp cho dự án của tôi người dùng truy cập vào cơ sở dữ liệu bạn đã tạo:

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

Cuối cùng, áp dụng các thay đổi quyền:

FLUSH PRIVILEGES;

Thoát khỏi bàn điều khiển MySQL bằng cách gõ exit. Chấm dứt kết nối SSH bằng cách gõ exit lần nữa.

Từ bây giờ, bạn hiếm khi phải chạm vào cơ sở dữ liệu sản xuất, vì bạn sẽ thực hiện gần như tất cả các hoạt động như tạo và thay đổi bảng từ máy cục bộ của bạn.

Với cơ sở dữ liệu sản xuất đã sẵn sàng, bạn có thể triển khai lại ứng dụng của mình đến máy chủ.

Bước 5 - Triển khai dự án tới máy chủ

Trong bước này, bạn sẽ thay thế ứng dụng đang chạy mà không có kết nối đến cơ sở dữ liệu với ứng dụng được cấu hình mới của bạn và kho lưu trữ Ecto mới của nó. Bước này sẽ cho phép bạn đảm bảo rằng ứng dụng được cấu hình đúng và nó vẫn chạy như mong đợi.

Mở mix.exs và tăng phiên bản ứng dụng. Số phiên bản giúp dễ dàng theo dõi các bản phát hành và quay lại các phiên bản trước nếu cần. Nó cũng được sử dụng bởi edeliver để nâng cấp ứng dụng của bạn mà không có thời gian chết.

nano mix.exs

Tăng trường phiên bản lên một giá trị thích hợp.

~/myproject/mix.exs

  def project do
    [
      app: :myproject,
      version: "0.0.3",
      elixir: "~> 1.4",
      elixirc_paths: elixirc_paths(Mix.env),
      compilers: [:phoenix, :gettext] ++ Mix.compilers,
      start_permanent: Mix.env == :prod,
      deps: deps()
    ]
  end

Để sử dụng trình chuyển đổi để thực hiện di chuyển cơ sở dữ liệu, trình chỉnh sửa phải là ứng dụng cuối cùng để bắt đầu trong dự án của bạn. Tìm khối mã sau:

~/myproject/mix.exs

  def application do
    [
      mod: {Myproject.Application, []},
      extra_applications: [:logger, :runtime_tools]
    ]
  end

Thêm vào edeliver đến cuối của extra_applications danh sách:

~/myproject/mix.exs

  def application do
    [
      mod: {Myproject.Application, []},
      extra_applications: [:logger, :runtime_tools, :edeliver]
    ]
  end

Lưu và đóng mix.exs.

Khởi chạy ứng dụng để đảm bảo mọi thứ hoạt động và không có lỗi biên dịch:

mix phx.server

Chuyến thăm http: // localhost: 4000 / địa chỉ để đảm bảo ứng dụng vẫn hoạt động. Nếu nó không bắt đầu hoặc bạn thấy lỗi biên dịch, hãy xem lại các bước trong hướng dẫn này và giải quyết chúng trước khi tiếp tục.

Nếu mọi thứ đang hoạt động như mong đợi, hãy nhấn CTRL+C hai lần trong thiết bị đầu cuối của bạn để dừng máy chủ.

Sau đó, cam kết thay đổi với Git. Bạn phải làm điều này mỗi khi bạn thực hiện thay đổi cho dự án của mình vì edeliver sử dụng Git để đẩy mã từ cam kết mới nhất đến máy chủ xây dựng để thực hiện thêm hành động.

git add .

git commit -m "Configured application with database"

Cuối cùng, sử dụng edeliver để cập nhật ứng dụng trên máy chủ sản xuất. Lệnh sau sẽ xây dựng và triển khai phiên bản mới nhất của dự án của bạn trước khi nâng cấp ứng dụng đang chạy trên máy sản xuất mà không có thời gian chết.

mix edeliver upgrade production

Bạn sẽ thấy kết quả sau:

OutputEDELIVER MYPROJECT WITH UPGRADE COMMAND

-----> Upgrading to revision 2512398 from branch master
-----> Detecting release versions on production hosts
-----> Deploying upgrades to 1 online hosts
-----> Checking whether installed version 0.0.2 is in release store
-----> Building the upgrade from version 0.0.2
-----> Authorizing hosts
-----> Validating * version 0.0.2 is in local release store
-----> Ensuring hosts are ready to accept git pushes
-----> Pushing new commits with git to: sammy@example.com
-----> Resetting remote hosts to 2512398838c2dcc43de3ccd869779dded4fd5b6b
-----> Cleaning generated files from last build
-----> Checking out 2512398838c2dcc43de3ccd869779dded4fd5b6b
-----> Fetching / Updating dependencies
-----> Compiling sources
-----> Checking version of new release
-----> Uploading archive of release 0.0.2 from local release store
-----> Extracting archive myproject_0.0.2.tar.gz
-----> Removing old releases which were included in upgrade package
-----> Generating release
-----> Removing built release 0.0.2 from remote release directory
-----> Copying release 0.0.3 to local release store
-----> Copying myproject.tar.gz to release store
-----> Upgrading production hosts to version 0.0.3
-----> Authorizing hosts
-----> Uploading archive of release 0.0.3 from local release store
-----> Upgrading release to 0.0.3

UPGRADE DONE!

Mặc dù việc nâng cấp đã hoàn tất thành công, bạn sẽ không thể chạy các tác vụ tạo liên quan đến cơ sở dữ liệu cho đến khi bạn khởi động lại ứng dụng.

Cảnh báo: Lệnh sau sẽ khiến ứng dụng của bạn chuyển sang ngoại tuyến trong một thời gian ngắn.

mix edeliver restart production

Bạn sẽ thấy kết quả này:

OutputEDELIVER MYPROJECT WITH RESTART COMMAND

-----> restarting production servers

production node:

  user    : sammy
  host    : example.com
  path    : /home/sammy/app_release
  response: ok

RESTART DONE!

edeliver cho chúng ta biết rằng nó đã khởi động lại thành công máy chủ sản xuất.

Để đảm bảo rằng ứng dụng của bạn đã được nâng cấp, hãy chạy lệnh edeliver sau để truy xuất phiên bản của ứng dụng hiện đang chạy trên sản xuất.

mix edeliver version production

OutputEDELIVER MYPROJECT WITH VERSION COMMAND

-----> getting release versions from production servers

production node:

  user    : sammy
  host    : example.com
  path    : /home/sammy/app_release
  response: 0.0.3

VERSION DONE!

Đầu ra cho chúng ta biết rằng máy chủ sản xuất đang chạy phiên bản ứng dụng 0.0.3.

Bạn cũng có thể truy cập ứng dụng của mình tại https://example.com để đảm bảo rằng nó đang chạy. Không nên có bất kỳ thay đổi quan sát nào đối với ứng dụng vì chúng tôi không tự chạm vào mã ứng dụng.

Nếu nâng cấp thành công nhưng không cập nhật được ứng dụng, hãy đảm bảo rằng bạn đã cam kết mã của mình và đã cập nhật phiên bản ứng dụng của bạn. Nếu lệnh nâng cấp không thành công, trình edeliver sẽ xuất ra mã bash mà nó đang thực thi trên máy chủ khi lỗi xảy ra và bản thân thông báo lỗi. Bạn có thể sử dụng những manh mối này để khắc phục sự cố của mình.

Bây giờ bạn đã thêm hỗ trợ cơ sở dữ liệu vào ứng dụng của mình và triển khai nó vào sản xuất, bây giờ bạn đã sẵn sàng để thêm một số tính năng sử dụng MySQL.

Bước 6 - Tạo sổ địa chỉ

Để chứng minh làm thế nào để triển khai các thay đổi cơ sở dữ liệu, hãy xây dựng một sổ địa chỉ đơn giản vào ứng dụng của chúng ta và triển khai nó vào sản xuất.

Cảnh báo: Sổ địa chỉ này sẽ có thể truy cập công khai và bất kỳ ai sẽ có thể truy cập và chỉnh sửa nó. Hãy gỡ bỏ tính năng sau khi hoàn thành hướng dẫn này hoặc thêm một hệ thống xác thực như Người giám hộ để hạn chế quyền truy cập.

Thay vì viết mã cho sổ địa chỉ từ đầu, chúng tôi sẽ sử dụng Máy phát điện Phoenix để tạo sổ địa chỉ. Máy phát Phoenix là các tiện ích tạo mã cho một tính năng CRUD (Tạo, Đọc, Cập nhật, Xóa) đơn giản. Điều này cung cấp một điểm khởi đầu tốt cho nhiều tính năng ứng dụng mà bạn có thể muốn xây dựng.

Sổ địa chỉ cũng sẽ yêu cầu một bảng trong cơ sở dữ liệu để lưu trữ các mục nhập. Để thêm bảng này vào cơ sở dữ liệu, bạn có thể xây dựng và thực thi truy vấn SQL, nhưng chúng tôi sẽ sử dụng tính năng di chuyển của Ecto để sửa đổi cơ sở dữ liệu thay thế. Cách tiếp cận này có một vài ưu điểm. Thứ nhất, đó là cơ sở dữ liệu độc lập; các lệnh giống nhau cho dù bạn đang sử dụng PostgreSQL, MySQL hay một số cơ sở dữ liệu khác. Tiếp theo, các tệp di chuyển cung cấp một cách thuận tiện để theo dõi cách lược đồ cơ sở dữ liệu của bạn đã thay đổi theo thời gian như thế nào. Cuối cùng, bạn cũng có thể cuộn lại các lần di chuyển mới nhất trên máy phát triển của mình nếu cần.

Rất may, bạn không phải viết một tệp di chuyển từ đầu vì máy phát Phoenix sẽ tạo một tệp cho bạn trừ khi được chỉ định khác.

Để sử dụng trình tạo, chỉ định ngữ cảnh, tên số ít của thực thể, tên số nhiều của thực thể và tất cả các trường khác có các loại tương ứng của chúng.

Các bối cảnh là một mô-đun sẽ chứa các hàm cho các tài nguyên có liên quan. Ví dụ: nếu bạn đang có kế hoạch duy trì danh sách người dùng đã đăng ký trên trang web của mình và nhật ký phiên khi người dùng đăng nhập, bạn nên đặt người dùng và phiên trong một mô-đun ngữ cảnh có tên "Tài khoản".

Lưu ý rằng theo quy ước, Phoenix giả định tên số nhiều của thực thể là tên của bảng cơ sở dữ liệu cho tài nguyên đó.

Hãy tạo sổ địa chỉ với trình tạo. Để giữ sổ địa chỉ đơn giản, chúng tôi sẽ chỉ bao gồm ba trường cho mỗi bản ghi - tên, email và mã ZIP. Chúng tôi sẽ đề cập đến từng mục như một Address, nhiều mục như addresses và ngữ cảnh trong đó sổ địa chỉ nên cư trú AddressBook.

Chạy lệnh này để tạo sổ địa chỉ:

mix phx.gen.html AddressBook Address addresses name:string email:string zip_code:integer

Output* creating lib/myproject_web/controllers/address_controller.ex
...
* creating priv/repo/migrations/20180318032834_create_address.exs

Add the resource to your browser scope in web/router.ex:

    resources "/addresses", AddressController

Remember to update your repository by running migrations:

    $ mix ecto.migrate

Phoenix cho chúng ta biết rằng nó tự động tạo ra các tệp mẫu, tệp thử nghiệm, mô hình, bộ điều khiển và tệp di chuyển. Nó cũng chỉ thị cho chúng ta thêm tài nguyên vào tệp bộ định tuyến và cập nhật kho lưu trữ.

Bạn có thể làm theo các hướng dẫn bạn thấy trong đầu ra, nhưng bằng cách làm như vậy, bạn sẽ gói nâng cấp mã ứng dụng và di chuyển cơ sở dữ liệu trong một bản phát hành duy nhất. Điều này có thể khiến các phần nhất định của ứng dụng thất bại trong quá trình sản xuất kể từ khi ứng dụng được triển khai đến máy chủ sản xuất vào thời điểm cơ sở dữ liệu sản xuất được di chuyển. Trong khoảng thời gian này, mã ứng dụng có thể tham chiếu các bảng hoặc cột không tồn tại trong cơ sở dữ liệu.

Để ngăn chặn thời gian chết và lỗi, triển khai các thay đổi theo hai bước:

  1. Thêm tệp di chuyển cơ sở dữ liệu với các thay đổi cần thiết đối với cơ sở dữ liệu mà không thực hiện các thay đổi đối với mã ứng dụng. Tạo bản phát hành, nâng cấp máy chủ sản xuất và di chuyển cơ sở dữ liệu sản xuất.
  2. Thực hiện thay đổi đối với mã ứng dụng, sau đó tạo và triển khai bản phát hành khác.

Nếu chúng tôi không thực hiện phương pháp này, mã cho sổ địa chỉ sẽ cố gắng tham chiếu bảng địa chỉ mà chúng tôi chưa tạo và ứng dụng của chúng tôi sẽ bị lỗi.

Trước khi chúng tôi di chuyển cơ sở dữ liệu sản xuất, hãy xem tệp di chuyển. Nó nằm ở priv/repo/migrations/20180501040548_create_addresses.exs, mặc dù tên tệp sẽ có một dấu thời gian khác dựa trên thời điểm bạn tạo nó. Mở tệp trong trình chỉnh sửa của bạn:

nano priv/repo/migrations/*_create_addresses.exs

Tệp di chuyển do Phoenix tạo ra là một mô-đun Elixir với một hàm duy nhất được gọi là change. Khi bạn thực hiện di chuyển sau này, chức năng này sẽ được gọi.

~/myproject/priv/repo/migrations/20180501040548_create_addresses.exs

defmodule Myproject.Repo.Migrations.CreateAddresses do
  use Ecto.Migration

  def change do
    create table(:addresses) do
      add :name, :string
      add :email, :string
      add :zip_code, :integer

      timestamps()
    end

  end
end

Trong chức năng này, máy phát Phoenix đã viết mã để tạo ra addresses bảng cùng với các trường bạn đã cung cấp. Ngoài ra, bộ tạo cũng bao gồm timestamps() chức năng bổ sung thêm hai trường cho bạn: inserted_atupdated_at. Các giá trị được lưu trữ trong các trường này được cập nhật tự động khi bạn chèn hoặc cập nhật dữ liệu.

Đóng tệp mà không thực hiện bất kỳ thay đổi nào; mã được tạo ra là tất cả những gì bạn cần.

Để triển khai chỉ tệp di chuyển mà không bao gồm mã ứng dụng, chúng tôi sẽ sử dụng thực tế là trình chỉnh sửa sử dụng Git để chuyển dự án của chúng tôi đến máy chủ xây dựng. Cụ thể, chúng tôi sẽ chỉ thực hiện giai đoạn và cam kết tệp di chuyển trong khi vẫn để lại các tệp còn lại chưa được xử lý.

Nhưng trước khi bạn có thể làm điều đó, hãy tăng phiên bản ứng dụng mix.exs. Edeliver sử dụng số phiên bản để chuẩn bị cho việc nâng cấp nóng, vì vậy bạn cần tăng số phiên bản cho mỗi lần cập nhật.

Mở ra mix.exs.

nano mix.exs

Tăng phiên bản ứng dụng của bạn lên một giá trị phù hợp.

~/myproject/mix.exs

  def project do
    [
      app: :myproject,
      version: "0.0.4",
      ...

Lưu và đóng tập tin.

Bây giờ, hãy sử dụng Git để sắp xếp cả hai mix.exs tệp và tệp di chuyển.

git add mix.exs priv/repo/migrations/*_create_addresses.exs

Tiếp theo, cam kết các tệp được dàn dựng.

git commit -m "Adding addresses table to the database"

Cùng với đó, hãy nâng cấp ứng dụng sản xuất của bạn với trình phân phối.

mix edeliver upgrade production

Sau khi nâng cấp hoàn tất, thực hiện lệnh edeliver sau đây để di chuyển cơ sở dữ liệu sản xuất.

mix edeliver migrate production

Đầu ra cho thấy rằng quá trình di chuyển đã được chạy thành công và hiển thị dấu thời gian của tệp di chuyển:

OutputEDELIVER MYPROJECT WITH MIGRATE COMMAND

-----> migrateing production servers

production node:

  user    : sammy
  host    : example.com
  path    : /home/sammy/app_release
  response: [20180501040548]

MIGRATE DONE!

Cơ sở dữ liệu sản xuất giờ đây có một bảng trống có tên addresses.

Các response trường sẽ hiển thị [] nếu không có di chuyển nào được chạy. Nếu đúng như vậy, hãy đảm bảo rằng bạn đã cam kết mã của mình bằng cách sử dụng Git trước khi nâng cấp lại. Nếu sự cố vẫn tiếp diễn, hãy khởi động lại ứng dụng sản xuất bằng cách nhập mix edeliver restart productionvà chạy lại tác vụ di chuyển cơ sở dữ liệu.

Với addresses bảng tại chỗ, chúng tôi có thể tiến hành theo các hướng dẫn do Phoenix ban hành khi chúng tôi tạo sổ địa chỉ và tạo bản phát hành mới.

Đầu tiên, mở tập tin lib/myproject_web/router.ex tập tin:

nano lib/myproject_web/router.ex

Tìm khối mã sau:

~/myproject/lib/myproject_web/router.ex

  scope "/", MyprojectWeb do
    pipe_through :browser 

    get "/", PageController, :index
  end

Chèn tuyến đường cho addresses nguồn:

~/myproject/lib/myproject_web/router.ex

  scope "/", MyprojectWeb do
    pipe_through :browser 

    get "/", PageController, :index
    resources "/addresses", AddressController
  end

Lưu và đóng router.ex.

Tiếp theo, yêu cầu Ecto thực hiện các thay đổi đối với cơ sở dữ liệu cục bộ.

mix ecto.migrate

Đầu ra cho thấy hàm trong tệp di chuyển đã được gọi, đã tạo thành công bảng addresses.

Output...
[info] == Running Myproject.Repo.Migrations.CreateAddresses.change/0 forward
[info] create table addresses
[info] == Migrated in 0.0s

Bây giờ hãy khởi động máy chủ phát triển cục bộ để kiểm tra tính năng mới của bạn:

mix phx.server

Trỏ trình duyệt của bạn tại http: // localhost: 4000 / địa chỉ để xem tính năng mới đang hoạt động.

Khi bạn hài lòng rằng mọi thứ đang hoạt động tại địa phương, hãy quay lại thiết bị đầu cuối của bạn và nhấn CTRL+C hai lần để chấm dứt máy chủ.

Bây giờ mọi thứ đang hoạt động, bạn có thể triển khai các thay đổi cho sản xuất. Mở mix.exs để cập nhật phiên bản ứng dụng.

nano mix.exs

Tăng trường phiên bản lên một giá trị thích hợp.

~/myproject/mix.exs

  def project do
    [
      app: :myproject,
      version: "0.0.5",
      elixir: "~> 1.4",
      elixirc_paths: elixirc_paths(Mix.env),
      compilers: [:phoenix, :gettext] ++ Mix.compilers,
      start_permanent: Mix.env == :prod,
      deps: deps()
    ]
  end

Lưu và đóng mix.exs.

Cam kết thay đổi của bạn với Git. Lần này, sắp xếp tất cả các tệp.

git add .
git commit -m "Added application code for address book"

Nâng cấp các ứng dụng sản xuất với edeliver.

mix edeliver upgrade production

Khi cập nhật hoàn tất, bạn có thể truy cập tính năng mới tại https://example.com/addresses.

Với điều đó, bạn đã nâng cấp thành công ứng dụng sản xuất và cơ sở dữ liệu.

Phần kết luận

Trong bài viết này, bạn đã định cấu hình ứng dụng Phoenix của mình để sử dụng cơ sở dữ liệu MySQL và đã sử dụng quá trình di chuyển edeliver và Ecto để thay đổi cơ sở dữ liệu sản xuất. Với phương pháp này, bạn không cần phải chạm vào cơ sở dữ liệu sản xuất và bất kỳ thay đổi nào bạn muốn thực hiện cho cơ sở dữ liệu sản xuất đều được thực hiện thông qua các tệp di chuyển Ecto. Điều này giúp dễ dàng khôi phục các thay đổi và theo dõi các thay đổi đối với cơ sở dữ liệu theo thời gian.

Để tìm hiểu thêm về di chuyển Ecto và cách thực hiện các thao tác cơ sở dữ liệu phức tạp, hãy tham khảo tài liệu di trú Ecto chính thức.