文件lib / phoenix / token.ex上的编译错误:Phoenix.Socket .__ struct __ / 0未定义

时间:2016-09-18 20:01:50

标签: elixir phoenix-framework

使用Docker Compose运行全新设置时,我们在编译时看到此错误:

== Compilation error on file lib/phoenix/token.ex ==
** (CompileError) lib/phoenix/token.ex:144: Phoenix.Socket.__struct__/0 is undefined, cannot expand struct Phoenix.Socket
   (stdlib) lists.erl:1354: :lists.mapfoldl/3
could not compile dependency :phoenix, "mix compile" failed. You can recompile this dependency with "mix deps.compile phoenix", update it with "mix deps.update phoenix" or clean it with "mix deps.clean phoenix"

我不确定为什么。查看/deps/phoenix/lib/phoenix/token.ex/socket.ex并未说明可能发生这种情况的原因。

这是Elixir 1.3.2和Phoenix 1.2.0。

1 个答案:

答案 0 :(得分:0)

由于您确认了docker-compose.yml在docker容器中安装了应用程序文件夹,我将进一步阐述如何解决我在类似场景中遇到的一些编译问题。这并不能解决您所询问的具体错误,但它可以作为找出问题的更恰当答案的指导。

我在Mac OS / X上开发并使用docker debian-based image来构建我的Phoenix Framework项目。我通过docker -v "$PWD":/app -w /app potz/elixir-build mix phoenix.server将应用程序文件夹挂载到容器中(potz/elixir-build只是我预先安装的一些自定义映像)。这提出了一个问题,因为当Phoenix在容器内部运行时,它会看到带有预编译工件的_build目录并尝试使用它,但当然这会抛出各种奇怪的编译错误消息,因为它们是在不同的平台(OS / X)。此外,依赖项保存在./deps文件夹中,并且还在OS / X上预编译。

我解决这个问题的方法是指示docker为构建工件和依赖项使用不同的文件夹,在仍然使用相同的应用程序源文件的同时有效地分离这两个环境。为此,我需要允许build_path中的deps_pathmix.exs设置被环境变量覆盖:

def project do
  [app: :my_app,
   version: "0.0.1",
   elixir: "~> 1.3",
   elixirc_paths: elixirc_paths(Mix.env),
   compilers: [:phoenix, :gettext] ++ Mix.compilers,
   build_embedded: Mix.env == :prod,
   build_path: System.get_env("BUILD_PATH") || "_build",  # Allows different path for builds
   deps_path: System.get_env("DEPS_PATH") || "deps",      # Allows different path for deps
   start_permanent: Mix.env == :prod,
   aliases: aliases(),
   deps: deps()]
end

然后在docker上运行时,我将这两个值作为环境变量提供,例如:

# /build and /deps can be folders inside the container,
# or mounted volumes, whatever makes sense to your specific setup
docker run -v "$PWD":/app -w /app -e BUILD_PATH=/build -e DEPS_PATH=/deps potz/elixir-build mix phoenix.server

当然我有一个自定义shell脚本,以避免一直记住这个巨大的命令行,但我猜你可以适应你的Docker组合设置。您只需要确保首先在容器中创建这些文件夹,或者记住在这些路径上安装两个额外的卷,无论哪种更有意义。

我希望这会有所帮助。