使用 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
传递此命令时需要使用一些参数,但此命令已涵盖我们需要的所有内容(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
第一行定义了用于构建镜像的基础镜像。如你所见,它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:
这里我们定义了我们的docker-compose脚本版本,需要创建的服务和卷。
如您所见,有两个服务(容器)正在被创建,db
其中web
.db
是我们的数据库容器,由 -container 使用web
。在镜像属性中,我们定义了镜像,即postgres:11-alpine
。您可以使用较新的版本,例如 PostgreSQL 12。这实际上取决于您将在生产环境中使用哪个版本。我建议在所有环境中使用相同的版本,以最大限度地减少与基础设施相关的问题。
更多关于属性的解释可以在docker-compose 文档中找到
.env
DATABASE_URL=postgres://postgres:postgres@db:5432/myapp_dev
目前,我们的数据库 URL 环境变量只有这个。之后,随着应用程序规模的扩大,您将需要将应用程序环境变量存储在这个文件中。
点燃它
首先我们需要构建我们的 Docker 镜像:
$ docker-compose build
如果你所有操作都正确,镜像应该可以相对快速地构建。现在镜像已经准备好了,但首先我们需要配置应用程序,以便使用环境变量作为数据库 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
对此:
# Configure your database
config :myapp, Myapp.Repo,
url: System.get_env("DATABASE_URL"),
show_sensitive_data_on_connection_error: true,
pool_size: 10
注意:将端点 IP 更改为 0.0.0.0!
如您所见,我们正在从容器环境中获取用于数据库连接的数据库 URL。
现在我们应该准备好启动应用程序了:
$ docker-compose up
它检查 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
我们没有数据库可以连接!让我们来解决这个问题:
$ docker-compose run web mix ecto.create
运行完之后,你应该会看到一行令人欣喜的消息,告诉你 YourApp.Repo 的数据库已经创建好了!太棒了!
请注意,由于容器内有可用的 mix 工具,您可以在容器内执行任何 mix 命令。您可以运行迁移、种子、销毁数据库并重新设置以进行全新启动等等。
现在执行:
$ docker-compose up
应用程序应该启动时就连接到数据库,并准备好进行开发!localhost:4000
现在,如果您对源文件进行更改,更改将更新到服务器,因此无需手动重启容器!
结论
这是一个相当简单的设置,只需支持/配置最少的文件。
我会在后续文章中介绍如何将 Elixir 应用程序部署到 AWS。其中将包括为生产环境配置应用程序、Terraform 基础设施以及一些 CI 技巧。
感谢阅读,希望你喜欢!🙂
鏂囩珷鏉ユ簮锛�https://dev.to/hlappa/development-environment-for-elixir-phoenix-with-docker-and-docker-compose-2g17