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

介绍

在本教程中,您将使用Phoenix-Ecto和Mariaex配置现有的Phoenix应用程序连接到MySQL数据库。Ecto是Phoenix应用程序广泛使用的数据库包装器。Mariaex是一个数据库驱动程序,它与Ecto集成并与MySQL和MariaDB数据库进行数据传输。

您还将在开发计算机上创建一个简单的通讯簿,该通讯簿使用数据库并使用edeliver将更改部署到生产服务器。您网站的用户将能够在此通讯录中创建,阅读,更新和删除条目。

准备

要完成本教程,您需要:

  • 完成部署的Phoenix 应用程序。
  • 安装MySQL,详见腾讯云+社区的如何在Ubuntu上安装MySQL的教程。
  • 在部署之前,先测试数据库。

第一步 - 将Mariaex和Ecto添加到您的应用程序中

通常,Phoenix应用程序不直接建立与数据库的连接并执行SQL查询。而是使用数据库驱动程序连接到所需的数据库,然后使用数据库包装器查询数据库。

数据库驱动程序是一个Elixir应用程序,负责处理使用数据库的普通任务,例如建立连接,关闭连接和执行查询。数据库包装器是数据库驱动程序之上的一个层,允许Elixir程序员使用Elixir代码创建数据库查询,并提供其他功能,如查询组合。

这种分离使模块化应用成为可能。无论使用何种数据库,数据库包装器以及与数据库交互的应用程序代码都大致相同。只需更改数据库驱动程序,Phoenix应用程序就可以使用不同的数据库软件。

应用程序既没有安装Ecto也没有安装Mariaex,您现在将Ecto和Mariaex添加为项目的依赖项。

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

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

$ cd ~/myproject

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

$ nano mix.exs

找到以下代码块:

~/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

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

~/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

警告:为避免潜在的配置问题,请仔细检查是否在新phoenix_ecto条目前面的行末尾添加了逗号(,)。

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

$ mix deps.get

您将在安装依赖项时看到此输出:

Running 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
...

输出显示Mix检查了包之间的兼容性,并从Hex存储库中获取了包及其依赖项。如果此命令失败,请确保已安装Hex并正确修改了mix.exs

使用Ecto和Mariaex,您可以设置Ecto存储库。

第二步 - 在应用程序中设置Ecto存储库

Phoenix应用程序通过名为Ecto的数据库包装器访问数据库。数据库包装器以项目中的Elixir模块的形式实现。

无论何时需要与数据库交互并使用模块提供的功能,都可以导入此模块。

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

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

$ nano lib/myproject/repo.ex

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

~/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

默认情况下,Phoenix项目定义init函数,这样如果环境变量DATABASE_URL存在,那么Ecto将使用环境变量中的配置连接到数据库,而不是使用Phoenix配置文件中的凭据。保存并关闭repo.ex

Phoenix项目使用轻量级Elixir进程实现并发和容错。如果他们崩溃,Supervisors会管理这些流程并重新启动它们。Supervisors还可以监督其他supervisors,这种结构称为监督树。

您刚添加的Myproject.Repo模块实现了一个管理程序,用于管理连接到数据库的进程。

要启动此Supervisors,必须将其添加到项目的监督树中。

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

$ nano lib/myproject/application.ex

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

~/myproject/lib/myproject/application.ex

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

您可以看到应用程序端点MyprojectWeb.Endpoint正在作为supervisors启动。添加Myproject.Repo到此列表:

~/myproject/lib/myproject/myproject.ex

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

如果跳过此步骤,Ecto将不会创建与数据库交互的进程,并且任何与数据库交互的尝试都将导致应用程序崩溃。

保存并关闭,application.ex然后继续。

最后,指定Ecto存储库的应用程序配置,以便可以使用Mix任务,如ecto.createecto.migrate创建和管理数据库。

config/config.exs中打开配置文件。

$ nano config/config.exs

在文件末尾找到以下行:

~/myproject/config/config.exs

import_config "#{Mix.env}.exs"

此行允许特定环境的配置文件(如prod.exstest.exs)在必要时覆盖config.exs中的设置。在该行上方添加以下代码以配置Ecto存储库:

~/myproject/config/config.exs

...

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

保存更改并关闭文件。

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

第三步 - 使用MySQL凭据配置应用程序

应用程序连接到数据库有三种情况:开发期间,测试期间和生产期间。

相应地,Phoenix提供了三个特定于环境的配置文件,其中包含与运行应用程序的环境相关的凭据。这些文件位于config项目根目录中的目录中。您将在此步骤中修改这三个文件。

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

$ nano config/dev.exs

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

~/myproject/config/dev.exs

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

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

~/myproject/config/dev.exs

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

在这里,我们定义开发数据库名称myproject_dev。这是Phoenix应用程序用于数据库的命名约定。遵循此约定,将调用生产数据库myproject_prod和测试数据库myproject_test。您可以使用自己的命名方案。

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

~/myproject/config/dev.exs

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

最后,将池大小设置为适当的数字。池大小是应用程序可以拥有的最大数据库连接数。这些连接将在请求之间共享。最佳尺寸取决于您的硬件,但您可以使用它10来启动。

~/myproject/config/dev.exs

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

保存并关闭dev.exs

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

$ nano config/test.exs

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

我们的pool value指定Ecto.Adapters.SQL.Sandbox而不是pool_size,这将以沙箱模式运行测试。也就是说,在测试期间使用测试数据库进行的任何事务都将被回滚。这意味着单元测试可以按随机顺序运行,因为数据库在每次测试后都会重置为初始状态。

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

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

~/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

保存并关闭test.exs。最后,要在生产环境中配置应用程序的凭据,请打开生产密钥文件prod.secret.exs

$ nano config/prod.secret.exs

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

~/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

保存更改并关闭文件。

出于安全原因,Git不会跟踪此文件,因此您必须手动将其传输到服务器。

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

然后调用ecto.create Mix任务来创建开发数据库。请注意,您不必创建测试数据库,因为Phoenix会在您运行测试时为您执行此操作。

$ mix ecto.create

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

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

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

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

第四步 - 设置生产数据库

使用ecto.createMix任务,您在开发计算机上创建了一个空数据库。现在,您将为生产服务器执行相同的操作。

遗憾的是,没有任何Mix任务或edeliver命令可以帮助我们实现这一目标,因此您将手动登录服务器并使用MySQL控制台使用SQL命令创建一个空数据库。

通过SSH连接到服务器。

$ ssh sammy@your_server_ip

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

$ mysql -u root -p

登录后,创建生产数据库:

mysql> CREATE DATABASE myproject_prod;

您将看到以下输出,让您知道数据库已创建:

Query OK, 1 row affected (0.00 sec)

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

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

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

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

最后,应用权限更改:

mysql> FLUSH PRIVILEGES;

输入exit退出MySQL控制台。 再次键入exit终止SSH连接。

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

现在,生产数据库已准备就绪,您可以将应用程序重新部署到服务器。

第五步 - 将项目部署到服务器

在此步骤中,您将使用新配置的应用程序及其新的Ecto存储库替换与数据库无连接的正在运行的应用程序。此步骤将允许您确保正确配置应用程序并且仍然按预期运行。

打开mix.exs并增加应用程序版本。版本号可以更轻松地跟踪版本并在必要时回滚到以前的版本。edeliver也可以使用它来升级您的应用程序而无需停机。

$ nano mix.exs

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

~/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

为了使用edeliver执行数据库迁移,edeliver必须是在项目中启动的最后一个应用程序。找到以下代码块:

~/myproject/mix.exs

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

添加edeliver到extra_applications列表的末尾:

~/myproject/mix.exs

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

保存并关闭mix.exs

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

$ mix phx.server

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

如果一切正常,请在终端中CTRL+C按两次以停止服务器。

然后,使用Git提交更改。每次更改项目时都必须执行此操作,因为edeliver使用Git将代码从最新提交推送到构建服务器以进行进一步操作。

$ git add .
$ git commit -m "Configured application with database"

最后,使用edeliver更新生产服务器上的应用程序。以下命令将在升级生产计算机上运行的应用程序之前构建和部署项目的最新版本,而无需停机。

$ mix edeliver upgrade production

您将看到以下输出:

EDELIVER 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!

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

警告:以下命令将导致应用程序短时间脱机。

$ mix edeliver restart production

你会看到这个输出:

EDELIVER MYPROJECT WITH RESTART COMMAND

-----> restarting production servers

production node:

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

RESTART DONE!

edeliver告诉我们它已成功重启生产服务器。

要确保已升级应用程序,请运行以下edeliver命令以检索当前正在生产的应用程序的版本。

$ mix edeliver version production
EDELIVER 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!

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

production node:

user : sammy

host : example.com

path : /home/sammy/app_release

response: 0.0.3

VERSION DONE!

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

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

如果升级成功但无法更新应用程序,请确保您已提交代码并提升了应用程序版本。如果升级命令失败,edeliver将在错误发生时输出它在服务器上执行的bash代码以及错误消息本身。您可以使用这些线索来解决您的问题。

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

第六步 - 创建地址簿

为了演示如何部署数据库更改,让我们在我们的应用程序中构建一个简单的通讯录并将其部署到生产环境中。

警告:此通讯录可以公开访问,任何人都可以访问和编辑它。在完成本教程后删除该功能,或者限制访问。

运行此命令以生成通讯簿:

$ mix phx.gen.html AddressBook Address addresses name:string email:string zip_code:integer
* 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告诉我们它会自动生成模板文件,测试文件,模型,控制器和迁移文件。它还指示我们将资源添加到路由器文件并更新存储库。

您可以按照在输出中看到的说明进行操作,但通过这样做,您将在单个版本中捆绑应用程序代码升级和数据库迁移。从应用程序部署到生产服务器到迁移生产数据库的时间,这可能导致应用程序的某些部分在生产中失败。在此间隔期间,应用程序代码可能引用数据库中不存在的表或列。

要防止停机和错误,请分两步部署更改:

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

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

在我们迁移生产数据库之前,让我们看一下迁移文件。它位于priv/repo/migrations/20180501040548_create_addresses.exs,尽管根据您创建文件名的时间,文件名将具有不同的日期戳。在编辑器中打开文件:

$ nano priv/repo/migrations/*_create_addresses.exs

Phoenix生成的迁移文件是Elixir模块,其中包含一个名为的函数change。稍后执行迁移时,将调用此函数。

~/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

在此函数中,Phoenix生成器已编写代码以创建addresses表以及您提供的字段。此外,该生成器还包括timestamps()为您添加两个字段的功能:inserted_at和updated_at。插入或更新数据时,存储在这些字段中的值会自动更新。

要仅部署迁移文件而不包含应用程序代码,我们将利用edeliver使用Git将项目转移到构建服务器的事实。具体来说,我们只是暂存和提交迁移文件,同时保留其余生成的文件。

在mix.exs中增加应用程序版本,打开mix.exs。

$ nano mix.exs

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

~/myproject/mix.exs

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

保存并关闭文件。

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

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

接下来,提交暂存文件。

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

然后,使用edeliver升级您的生产应用程序。

$ mix edeliver upgrade production

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

$ mix edeliver migrate production

输出显示迁移已成功运行,并显示迁移文件的时间戳:

EDELIVER MYPROJECT WITH MIGRATE COMMAND

-----> migrateing production servers

production node:

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

MIGRATE DONE!

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

如果没有运行迁移,该response字段将显示[]。如果是这种情况,请确保在再次升级之前使用Git提交了代码。如果问题仍然存在,请通过键入重新启动生产应用程序mix edeliver restart production,然后再次运行数据库迁移任务。

使用该addresses表后,我们可以在生成通讯簿并创建新版本时按照Phoenix发布的说明进行操作。

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

$ nano lib/myproject_web/router.ex

找到以下代码块:

~/myproject/lib/myproject_web/router.ex

  scope "/", MyprojectWeb do
    pipe_through :browser 

    get "/", PageController, :index
  end

插入addresses资源的路由:

~/myproject/lib/myproject_web/router.ex

 scope "/", MyprojectWeb do
    pipe_through :browser 

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

保存并关闭router.ex

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

$ mix ecto.migrate

输出显示已调用迁移文件中的函数,该函数已成功创建表addresses

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

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

$ mix phx.server

将浏览器指向http://localhost:4000/addresses以查看正在运行的新功能。

如果您对本地工作正常感到满意,请返回终端并按CTRL+C两次以终止服务器。

现在情况正常,您可以将更改部署到生产环境。打开mix.exs以更新应用程序版本。

$ nano mix.exs

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

~/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

保存并关闭mix.exs

使用Git提交您的更改。这一次,暂存所有文件。

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

使用edeliver升级生产应用程序。

$ mix edeliver upgrade production

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

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

结论

在本文中,您将Phoenix应用程序配置为使用MySQL数据库,并使用edeliver和Ecto迁移来更改生产数据库。您要对生产数据库所做的任何更改都是通过Ecto迁移文件完成的。这样可以更轻松地回滚更改并跟踪数据库随时间的更改。要了解有关Ecto迁移以及如何执行复杂数据库操作的更多信息,请参阅官方Ecto迁移文档


参考文献:《How to Deploy Elixir-Phoenix Applications with MySQL on Ubuntu 16.04》

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏用户2442861的专栏

每天一个linux命令(61):wget命令

http://www.cnblogs.com/peida/archive/2013/03/18/2965369.html

1172
来自专栏马洪彪

WCF IIS 部署错误处理

做Web接口,原来一直用Web Service的,但是.Net 3.5后,Web Service变成了WCF。代码的编写上,把WebMethod特性改成了Ope...

2887
来自专栏流星博客

在百度云BCH中WordPress实现伪静态和SSL

原文来自流星博客:https://www.liues.cn/lx-449.html

1634
来自专栏散尽浮华

[原创]CI持续集成系统环境--Gitlab+Gerrit+Jenkins完整对接

近年来,由于开源项目、社区的活跃热度大增,进而引来持续集成(CI)系统的诞生,也越发的听到更多的人在说协同开发、敏捷开发、迭代开发、持续集成和单元测试这些拉风的...

1.1K9
来自专栏云计算教程系列

如何在Ubuntu 16.04上使用Deployer自动部署Laravel应用程序

Laravel是一个开源的PHP Web框架,旨在使常见的Web开发任务(如身份验证,路由和缓存)变得更加容易。Deployer是一个开源的PHP部署工具,为许...

3111
来自专栏网络

CobaltStrike团体服务器部署并后台运行

大家好,我是你们的老朋友Alex。Cobaltstrike的部署安装很简单,但是在实际使用中出现了问题。我把团队服务器放在ECS上,出现了两个问题:1.客户端无...

2916
来自专栏DeveWork

记录一个在Mac OS X 中本地安装Ghost 的报错问题

新买的Macbook Air 升级了最新版的OS X 10.10 Yosemite,昨天在本地安装Ghost 的时候出现了问题,在这里做一个记录。 安装node...

2329
来自专栏运维小白

Linux基础(day50)

12.10 Nginx访问日志 Nginx访问日志目录概要 日志格式 vim /usr/local/nginx/conf/nginx.conf //搜索log_...

2079
来自专栏张戈的专栏

硬盘故障时如何强制关机:Input/output error

如果硬盘可能会出现锁死或坏道的故障,会造成 SHELL 命令的失效,包括 reboot,powoff,,shutdown,用正常的命令是没法完成重启的。 执行这...

2994
来自专栏Rovo89

修复Android ROM的Google网络定位

3222

扫码关注云+社区