2016-09-18 5 views
0

Wenn ein neues Setup mit Docker Compose läuft, wir diesen Fehler auf Kompilation sehen:Übersetzungsfehler auf Datei lib/phoenix/token.ex: Phoenix.Socket .__ struct __/0 ist nicht definiert

== 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" 

Ich bin nicht sicher warum. Ein Blick in die /deps/phoenix/lib/phoenix/token.ex und /socket.ex gibt keinen Hinweis darauf, warum dies passieren könnte.

Dies ist mit Elixir 1.3.2 und Phoenix 1.2.0.

+1

Sie erwähnen, dass Sie die Phoenix-Anwendung in Docker ausführen. Verwenden Sie zufällig den gleichen Anwendungsordner, den Sie bei der Entwicklung über ein Docker-Mount verwenden (wie in 'docker -v" $ PWD ":/app ...')? Wenn dies der Fall ist, verwendet Phoenix möglicherweise die vorgefertigten Artefakte aus dem Ordner "./Build", die auf einer anderen Plattform kompiliert wurden. – potz

+0

@ PotiguarFaga wir verwenden Docker Compose, so dass unser 'docker-compose.yml' denselben Anwendungsordner verwendet. Es ist möglich, dass Sie Recht haben, dass der Endbenutzer sowohl auf seinem Host-Computer normal kompiliert als auch versucht, über Docker zu verwenden. –

Antwort

0

Da Sie bestätigt haben, dass Ihr docker-compose.yml den Anwendungsordner innerhalb des Docker-Containers bereitstellt, werde ich ein wenig weiter ausführen, wie ich einige Kompilierungsprobleme gelöst habe, die ich in einem ähnlichen Szenario hatte. Dies bezieht sich nicht auf den spezifischen Fehler, über den Sie nachfragen, aber es könnte als Anleitung dienen, um eine adäquatere Antwort auf Ihr Problem zu finden.

Ich entwickle auf einem Mac OS/X und benutze ein Docker Debian-basiertes Image, um meine Phoenix Framework Projekte zu erstellen. Ich mounte den Anwendungsordner innerhalb des Containers über docker -v "$PWD":/app -w /app potz/elixir-build mix phoenix.server (potz/elixir-build ist nur ein benutzerdefiniertes Bild, das ich mit einigen Sachen vorinstalliert verwende). Dies stellt ein Problem dar, denn wenn Phoenix innerhalb des Containers läuft, sieht es das Verzeichnis _build mit vorkompilierten Artefakten und versucht es zu benutzen, aber das wirft natürlich alle Arten komischer Kompilierungsfehlermeldungen aus, da sie auf einer anderen Plattform (OS/X). Außerdem werden Abhängigkeiten im Ordner ./deps gespeichert, und diese wurden auch auf OS/X vorkompiliert.

Meine Lösung für dieses Problem besteht darin, Docker anzuweisen, verschiedene Ordner sowohl für die Build-Artefakte als auch für die Abhängigkeiten zu verwenden. Dadurch werden die beiden Umgebungen effektiv getrennt, während die gleichen Anwendungsquelldateien verwendet werden. Um das zu tun, dass ich die build_path und deps_path Einstellungen in mix.exs erlauben müssen von Umgebungsvariablen außer Kraft gesetzt werden:

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 

Dann, wenn auf Docker laufen biete ich diese beiden Werte als Umgebungsvariablen, wie zB:

# /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 

Natürlich habe ich ein benutzerdefiniertes Shell-Skript, um zu vermeiden, sich ständig an diese riesige Befehlszeile zu erinnern, aber ich schätze, Sie können sich an Ihr Docker-Setup anpassen. Sie müssen nur sicherstellen, dass diese Ordner zuerst im Container erstellt werden, oder Sie müssen sich daran erinnern, zwei zusätzliche Volumes auf diesen Pfaden bereitzustellen, was auch immer sinnvoller ist.

Ich hoffe, das hilft.