部署 Elixir 应用程序前段时间很复杂,但现在我们拥有如此多的工具来促进我们的工作,这些工具可以非常简单地免费设置生产环境。

Render 是一个平台即服务,它为我们的服务器提供主机、DDoS 保护、在 git 上自动部署以及我们无需使用信用卡即可使用的更多功能!他们也支持 Docker,所以我们将使用它。

这里的目标是创建一个简单的 LiveView 应用程序,对其进行更改并使用 Docker 映像将其部署在 Render 上。

所以让我们开始吧!

[路](https://res.cloudinary.com/practicaldev/image/fetch/s--12SOT-nR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to -uploads.s3.amazonaws.com/uploads/articles/517q6sue5u3y7d83m8t9.jpg)

在本地创建应用并在docker上运行

我们的应用程序将被称为 Render Deploy,它没有任何功能,只是为了演示部署。

要创建 LiveView 应用程序,请运行以下命令:

mix phx.new render_deploy --live --no-ecto

  • - - live:这表明新项目是 LiveView 应用程序。

  • - - no-ecto:表示我们不想要ecto,所以它不会有Repo。

现在,在 config/dev.exs 上,第 12 行将127, 0, 0, 1更改为0, 0, 0, 0以允许从 docker 访问。

[dev.exs 配置](https://res.cloudinary.com/practicaldev/image/fetch/s--z4JJFfph--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/l1aa6bch1ykwkn1rvhh5.png)

我们必须在目录根目录上创建./Dockerfile才能在本地运行:

FROM hexpm/elixir:1.13.0-erlang-23.3.4.10-alpine-3.14.3 AS base

WORKDIR /render_deploy

RUN mix do local.hex --force, local.rebar --force

RUN apk add npm inotify-tools

进入全屏模式 退出全屏模式

  • 这是一个 docker 多阶段构建,它使文件更具可读性并创建更小的图像,您可以在此处阅读更多。

  • FROM hexpm/elixir:1.13.0-erlang-23.3.4.10-alpine-3.14.3 AS base:这里我们拉取的是基于alpine的elixir镜像,是一个较小的镜像。

  • WORKDIR /render_deploy:这将是我们的工作目录,在容器内。

  • RUN mix do local.hex --force, local.rebar --force:安装预编译的十六进制和钢筋。

  • RUN apk add npm inotify-tools:实时重新加载工具

我们可以运行 docker build 和 docker run,但我更喜欢使用 docker-compose 来管理容器,所以让我们在目录根目录上创建一个新的./docker-compose.yml

version: "3.8"

services:
  app:
    build:
      context: .
      target: base
    container_name: render_deploy_web
    command: mix phx.server
    restart: unless-stopped
    ports:
      - 4000:4000
    volumes:
      - .:/render_deploy

进入全屏模式 退出全屏模式

  • 通过多阶段构建,我们可以在创建容器时设置特定目标,在本例中为target: base

创建文件后,我们可以运行这些命令来安装依赖项,创建容器并在本地运行服务器。

docker-compose run --rm app mix deps.get

docker-compose up

如果我们可以访问localhost:4000我们将看到这个页面:

[凤凰主屏](https://res.cloudinary.com/practicaldev/image/fetch/s--QJQbY349--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to -uploads.s3.amazonaws.com/uploads/articles/swmgk3mt5hombmpx8qqn.png)

让我们改变它以使其独一无二。

lib/render_deploy_web/templates/page/index.html.heex第 2 行更改

<h1><%= gettext "Welcome to %{name}!", name: "Phoenix" %></h1>
to
<h1><%= gettext "Welcome to %{name}!", name: "Render deploy" %></h1>

进入全屏模式 退出全屏模式

[更改主屏幕](https://res.cloudinary.com/practicaldev/image/fetch/s---nMyzlCi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/vw1qv56m9ibq5zvuzb16.png)

部署前调整代码

我们将使用混合版本,这是一种将我们的应用程序打包成可执行二进制文件并使用它来部署应用程序的方法。

为此,我们必须将以下代码添加到./Dockerfile文件的末尾:

# -----------------
# BUILD
# -----------------
FROM base AS build

RUN apk add curl bash git

ARG MIX_ENV=prod
ENV MIX_ENV=$MIX_ENV
COPY . ./

# install application
RUN mix do deps.get, compile

# -----------------
# RELEASE
# -----------------
FROM build AS release

# digests and compresses static files
RUN mix assets.deploy

# generate release executable
RUN mix release

# -----------------
# PRODUCTION
# -----------------
FROM alpine:3.14.3

WORKDIR /render_deploy

ARG MIX_ENV=prod

# install dependencies
RUN apk add ncurses-libs curl

COPY --from=release /render_deploy/_build/$MIX_ENV/rel/render_deploy ./

# start application
CMD ["bin/render_deploy", "start"]

进入全屏模式 退出全屏模式

  • 关于代码的重要事项:

  • ARG MIX_ENV=prod:我们将混合环境设置为 prod。

  • RUN mix assets.deploy:缩小esbuild并压缩静态文件。

  • COPY --from=release /render_deploy/_build/$MIX_ENV/rel/render_deploy ./:将之前的构建阶段复制到当前阶段。

  • CMD ["bin/render_deploy", "start"]:它将启动应用程序。

现在,在部署之前,我们必须调整我们的config/runtime.exs,以便 Render 将生产 URL:

import Config

if System.get_env("PHX_SERVER") && System.get_env("RELEASE_NAME") do
  config :render_deploy, RenderDeployWeb.Endpoint, server: true
end

if config_env() == :prod do
  secret_key_base =
    System.get_env("SECRET_KEY_BASE") ||
      raise """
      environment variable SECRET_KEY_BASE is missing.
      You can generate one by calling: mix phx.gen.secret
      """

  port = String.to_integer(System.get_env("PORT") || "4000")

  config :render_deploy, RenderDeployWeb.Endpoint,
    url: [host: System.get_env("RENDER_EXTERNAL_HOSTNAME") || "localhost", port: 80],
    http: [
      ip: {0, 0, 0, 0, 0, 0, 0, 0},
      port: port
    ],
    secret_key_base: secret_key_base

  config :render_deploy, RenderDeployWeb.Endpoint, server: true
end

进入全屏模式 退出全屏模式

准备部署

好的,我们已经用 docker 完成了我们的开发设置,我们已经准备好使用 render.com 在生产环境中部署了

首先,我们需要使用 Github 上的代码创建一个存储库。

现在让我们访问render.com并创建项目,如果您没有帐户,请创建它然后单击 New, Web Service。

[render create new account](https://res.cloudinary.com/practicaldev/image/fetch/s--oG3L5PSO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/egm3ziilo3ebph1d4xwi.png)

选择您的存储库:

[选择存储库](https://res.cloudinary.com/practicaldev/image/fetch/s--ve5YFD35--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/0irhs08dpm397nnlxkgf.png)

选择一个名称,选择 Docker 作为环境运行时和免费计划。

现在我们必须设置密钥,为此,运行以下命令生成密钥:

docker-compose run --rm app mix phx.gen.secret

[选择名称和环境](https://res.cloudinary.com/practicaldev/image/fetch/s--5vTpR7Ry--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/75zf8lsdhikdafpy96nn.png)

在此之后,向下滚动页面并单击“高级”,然后将 SECRET_KEY_BASE 与之前生成的秘密一起放入。

现在我们只需单击“创建 Web 服务”并等待 Render 将我们的应用程序部署到生产环境。

[放置密钥基础环境](https://res.cloudinary.com/practicaldev/image/fetch/s--Mp52UvAc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev -to-uploads.s3.amazonaws.com/uploads/articles/ct4kpb4sobv6s9hd88eg.png)

[点击创建新服务](https://res.cloudinary.com/practicaldev/image/fetch/s--AXS5yJf9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev -to-uploads.s3.amazonaws.com/uploads/articles/y0j4i48ybnh2tvkmt2e0.png)

部署完成后,您将看到“实时”标签,现在只需单击 URL 并检查我们在云上运行的新 LiveView 应用程序🎉

[部署完成](https://res.cloudinary.com/practicaldev/image/fetch/s--bSgcy_aI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/3kpb9mwp19airi1bom64.png)

[云端应用程序 url](https://res.cloudinary.com/practicaldev/image/fetch/s--1yTGS-J9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https:// dev-to-uploads.s3.amazonaws.com/uploads/articles/sl91m4uuh2d4jchuazrb.png)

Render 对免费计划有一些限制,应用程序会在 15 分钟不活动后自动关闭,在此之后的新请求可能需要 30 秒才能再次启动,免费计划允许每月运行 750 小时您帐户中的所有免费网络服务,您可以在此处查看所有限制。

即使有这些限制,它也是一个很好的平台,可以提供我们的服务并练习生产部署。

您可以在此处查看源代码:https://github.com/Lgdev07/render_deploy以及我们刚刚在此处构建的应用程序:https://render-example-71rp.onrender.com/

感谢所有读过这里的人,如果你们有什么要补充的,请发表评论。

Logo

CI/CD社区为您提供最前沿的新闻资讯和知识内容

更多推荐