用Dokku部署Phoenix应用程序的方法

492 阅读4分钟

Dokku是我在VPS上部署网络应用的首选方法。 它可以让你建立自己的Heroku风格的平台即服务来轻松部署应用。 一旦设置好,你需要做的就是将你的代码git push 到你的dokku主机上。

本教程将指导你部署一个Elixir + Phoenix + Ecto应用,以及将其连接到Postgres数据库。 我们将使用一个博客应用作为例子。

设置服务器

对于我的业余项目,我使用5美元/月的Digital Ocean服务器,有1GB内存和25GB SSD存储。 我在上面安装了Ubuntu 18.04。(我试过20.04,但在上面安装dokku时遇到了麻烦。

虽然1GB的内存足以运行一个Elixir应用程序,但我在用这么多内存让node编译前端依赖时遇到了麻烦。 为了解决这个问题,设置了一个1GB的交换文件。

cd /var
touch swap.img
chmod 600 swap.img
dd if=/dev/zero of=/var/swap.img bs=1024k count=1000
安装dokku

现在是安装dokku的时候了。使用ssh root@your.ip.address,SSH进入服务器,运行以下命令。(你可以在dokku网站上找到最新版本的命令)。

wget https://raw.githubusercontent.com/dokku/dokku/v0.21.3/bootstrap.sh
sudo DOKKU_TAG=v0.21.3 bash bootstrap.sh
网络安装程序

一旦dokku安装完毕,你可以通过在浏览器中进入你的服务器的IP地址来找到网络安装程序。 在这里你可以设置以下内容。

  • 设置你的主机名
  • 启用 "应用程序的用户虚拟命名 "选项

这可以让你在你的主机名的子域上访问应用程序。例如,如果你的主机是example.com ,你可以创建一个名为blog的应用程序,并在blog.example.com 。这只是为了方便--你以后总是可以设置一个自定义域。

现在也是将blog.example.com 域名指向你的dokku服务器IP地址的好时机。

创建应用程序

在本教程中,我们要创建一个博客应用程序,我们将很不自然地把它称为blog 。 SSH进入dokku主机并创建该应用程序。

dokku apps:create blog

在这之后,我们需要设置一些环境变量。对于SECRET_KEY_BASE 这个变量,你可以通过运行mix phx.gen.secret ,从你的phoenix应用本地生成一个值。

dokku config:set blog LC_ALL=en_US.utf8
dokku config:set blog MIX_ENV=prod
dokku config:set blog SECRET_KEY_BASE=some_secret_key
Postgres设置

我们还将使用postgres作为数据库,所以我们需要安装postgres插件。

sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres

现在我们将创建一个名为blog 的数据库,并将其链接到blog 应用程序。

dokku postgres:create blog
dokku postgres:link blog blog

这将设置数据库,并在我们应用的docker容器中导出一个DATABASE_URL 环境变量。Phoenix默认配置为寻找这个环境变量,所以在我们的应用中没有什么需要改变的。

设置git远程

现在dokku主机已经准备好了,让我们在本地进行设置。 我们将首先创建一个名为dokku 的git远程,它将指向dokku服务器。

git remote add dokku dokku@blog.example.com:blog

一旦设置好了,你就可以运行git push dokku master 进行部署。然而,现在的部署会失败,因为我们还没有配置我们的repo来在部署时设置Elixir。

构建包

我们需要创建一个包含以下内容的.buildpacks 文件,并提交到 repo。

https://github.com/HashNuke/heroku-buildpack-elixir.git
https://github.com/gjaldon/heroku-buildpack-phoenix-static.git

elixir_buildpack.config 中设置Elixir和Erlang的版本。

erlang_version=23.0.2
elixir_version=1.10.0

phoenix_static_buildpack.config 中设置用于编译前端资产的node版本。

node_version=14.4.0
将所有东西放在一起

现在我们把一切都设置好了,让我们来部署我们的应用程序。 用git push dokku master ,把本地的repo推送到dokku远程。 你应该看到部署日志作为输出的一部分。

现在转到服务器的IP地址,或者适当的子域(本例中为blog.example.com )。应用程序应该在这个URL上运行。

运行迁移

虽然我们已经部署了应用程序,但仍有一个问题。 只要你点击一个需要访问数据库的URL,你就会得到一个500错误。 这是因为我们还没有运行Ecto迁移。

在我们配置dokku运行迁移作为部署过程的一部分之前,我们还需要创建数据库。 要做到这一点,在dokku服务器上运行这个。

dokku run mix ecto.create

接下来,我们需要配置dokku,使其在部署时运行待定的ecto迁移。 在 repo的根目录下创建一个app.json ,并提交。这将定义部署后的命令。

{
  "scripts": {
    "dokku": {
      "postdeploy": "mix ecto.migrate"
    }
  }
}

再次推送代码到dokku远程,迁移将在部署结束时运行。

设置域

由于我们通过网页安装程序设置主机名的方式,你会看到应用在你的主机上的blog子域上运行。但你可能想把你的应用托管在其他的域上。 运行以下命令为你的应用配置一个自定义域。

dokku domains:add blog <your-fancy-domain>
SSL

现在我们的应用程序已经启动并运行,让我们最后为我们的域名设置SSL。 Letsencrypt使为你的网站启用SSL变得非常容易。 Dokku有一个Letsencrypt插件,为你的域名启用SSL并在过期时自动更新。 在dokku服务器上运行以下命令。

dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
dokku config:set --no-restart blog DOKKU_LETSENCRYPT_EMAIL=you@example.com
dokku letsencrypt blog
dokku letsencrypt:auto-renew blog

链接