使用 Docker 和 Docker-compose 构建 Elixir + Phoenix 的开发环境 先决条件 创建 Phoenix 应用程序 Docker 和 Docker-compose 启动它 结论

2025-06-08

使用 Docker 和 Docker-compose 的 Elixir + Phoenix 开发环境

先决条件

创建 Phoenix 应用程序

Docker 和 Docker-compose

点燃它

结论

您现在可以观看此文章的视频:
视频链接 已过时

编辑于 2021.11.27:由于 Phoenix 1.6.0 版本删除了 Webpack、Npm 等并移至 Esbuild,因此文章现已相应更新。

编辑 2021.12.25:更改在 Docker 环境中工作的端点 ip。

我关注 Elixir、Phoenix 和 Docker 已经两年了。一开始只是做一些小型的 demo 和实验。当时,将 Elixir 和 Phoenix 配置到 Docker 环境非常麻烦,尤其是运行时配置。现在至少有 20 种不同的方法和教程教你如何为 Docker 和 Docker-compose 配置 Elixir 和 Phoenix。虽然这些教程都挺实用的,但有些要么过时,要么太复杂。

今天有空了,再次深入研究了这个问题,用Docker和Docker-compose为Elixir+Phoenix配置了合适的热加载本地开发环境。

先决条件

在本文中,我不会介绍如何安装这些工具,但下面列出了所需的工具。

  • Docker
  • Docker-compose
  • Elixir(我用的是最新的 1.10.4)
  • Phoenix框架(我使用最新的1.5.4)

创建 Phoenix 应用程序

安装完所有内容后,您可以通过执行以下命令来生成新的 Phoenix 项目:

$ mix phx.new app_name
Enter fullscreen mode Exit fullscreen mode

传递此命令时需要使用一些参数,但此命令已涵盖我们需要的所有内容(Ecto、webpack 等)。更多信息请参阅phx.new 文档

德普斯

在项目引导期间,mix将执行命令deps.get & deps.compile来获取和编译所需的依赖项

这很成问题,因为我们想在容器中运行程序/Web 服务器,而不是在裸机系统上。为了运行 Elixir 应用程序,需要在与发布二进制文件相同的系统架构上进行编译。目前,可以安全地deps从项目结构中移除该文件夹。

现在让我们深入为新创建的应用程序设置 Docker 配置!

Docker 和 Docker-compose

在本节中我们将创建以下文件:

  • Dockerfile
  • docker-compose.yml
  • .env

Dockerfile用于构建包含我们的应用程序、依赖项和所需工具的 Docker 镜像。

docker-compose.yml- yaml-markup 文件来定义我们的服务、卷等。

.env- 保存应用程序的环境变量。

Dockerfile

下面您可以看到我们的 Dockerfile 的内容。

FROM bitwalker/alpine-elixir-phoenix:latest

WORKDIR /app

COPY mix.exs .
COPY mix.lock .

CMD mix deps.get && mix phx.server
Enter fullscreen mode Exit fullscreen mode

第一行定义了用于构建镜像的基础镜像。如你所见,它bitwalker/alpine-elixir-phoenix包含了 Elixir、Phoenix 以及其他应用程序所需的工具。

在接下来的几行中,我们定义工作目录,复制文件并创建一个新目录。

CMD行代码会在我们启动容器时执行。有两个命令分别用于获取依赖项和启动服务器。

docker-compose.yml

version: '3.6'
services:
  db:
    environment:
      PGDATA: /var/lib/postgresql/data/pgdata
      POSTGRES_PASSWORD: postgres
      POSTGRES_USER: postgres
      POSTGRES_HOST_AUTH_METHOD: trust
    image: 'postgres:11-alpine'
    restart: always
    volumes:
      - 'pgdata:/var/lib/postgresql/data'
  web:
    build: .
    depends_on:
      - db
    environment:
      MIX_ENV: dev
    env_file:
      - .env
    ports:
      - '4000:4000'
    volumes:
      - .:/app
volumes:
  pgdata:
Enter fullscreen mode Exit fullscreen mode

这里我们定义了我们的docker-compose脚本版本,需要创建的服务和卷。

如您所见,有两个服务(容器)正在被创建,db其中web.db是我们的数据库容器,由 -container 使用web。在镜像属性中,我们定义了镜像,即postgres:11-alpine。您可以使用较新的版本,例如 PostgreSQL 12。这实际上取决于您将在生产环境中使用哪个版本。我建议在所有环境中使用相同的版本,以最大限度地减少与基础设施相关的问题。

更多关于属性的解释可以在docker-compose 文档中找到

.env

DATABASE_URL=postgres://postgres:postgres@db:5432/myapp_dev
Enter fullscreen mode Exit fullscreen mode

目前,我们的数据库 URL 环境变量只有这个。之后,随着应用程序规模的扩大,您将需要将应用程序环境变量存储在这个文件中。

点燃它

首先我们需要构建我们的 Docker 镜像:

$ docker-compose build
Enter fullscreen mode Exit fullscreen mode

如果你所有操作都正确,镜像应该可以相对快速地构建。现在镜像已经准备好了,但首先我们需要配置应用程序,以便使用环境变量作为数据库 URL,所以让我们来做这件事。

导航到config/dev.exs并打开它。将数据库的内容从以下内容更改:

# Configure your database
config :myapp, Myapp.Repo,
  username: "postgres",
  password: "postgres",
  database: "myapp_dev",
  hostname: "localhost",
  show_sensitive_data_on_connection_error: true,
  pool_size: 10
Enter fullscreen mode Exit fullscreen mode

对此:

# Configure your database
config :myapp, Myapp.Repo,
  url: System.get_env("DATABASE_URL"),
  show_sensitive_data_on_connection_error: true,
  pool_size: 10
Enter fullscreen mode Exit fullscreen mode

注意:将端点 IP 更改为 0.0.0.0!

如您所见,我们正在从容器环境中获取用于数据库连接的数据库 URL。

现在我们应该准备好启动应用程序了:

$ docker-compose up
Enter fullscreen mode Exit fullscreen mode

它检查 deps,编译 deps 和源文件,但是等一下......

[error] Postgrex.Protocol (#PID<0.3932.0>) failed to connect: ** (Postgrex.Error) FATAL 3D000 (invalid_catalog_name) database "myapp_dev" does not exist
Enter fullscreen mode Exit fullscreen mode

我们没有数据库可以连接!让我们来解决这个问题:

$ docker-compose run web mix ecto.create
Enter fullscreen mode Exit fullscreen mode

运行完之后,你应该会看到一行令人欣喜的消息,告诉你 YourApp.Repo 的数据库已经创建好了!太棒了!

请注意,由于容器内有可用的 mix 工具,您可以在容器内执行任何 mix 命令。您可以运行迁移、种子、销毁数据库并重新设置以进行全新启动等等。

现在执行:

$ docker-compose up
Enter fullscreen mode Exit fullscreen mode

应用程序应该启动时就连接到数据库,并准备好进行开发!localhost:4000现在,如果您对源文件进行更改,更改将更新到服务器,因此无需手动重启容器!

结论

这是一个相当简单的设置,只需支持/配置最少的文件。

我会在后续文章中介绍如何将 Elixir 应用程序部署到 AWS。其中将包括为生产环境配置应用程序、Terraform 基础设施以及一些 CI 技巧。

感谢阅读,希望你喜欢!🙂

鏂囩珷鏉ユ簮锛�https://dev.to/hlappa/development-environment-for-elixir-phoenix-with-docker-and-docker-compose-2g17
PREV
可视化 React 状态流和组件层次结构功能包括:
NEXT
编写简洁高效的 JavaScript:每个开发人员都应该知道的 10 个最佳实践