by clemens (29.09.2022)

Multiple Phoenix Instances on Single Server Can Cause Crashes on Upload

I’ve recently encountered a problem with running multiple Phoenix application on a single server. On installation of a new application that was using Phoenix Live Uploads I was unable to upload files to the server, although everything was working in development locally.

The error logs where looking something like this:

Sep 29 11:29:17 shop plan[537623]: 11:29:17.522 [error] GenServer #PID<0.7472.0> terminating
Sep 29 11:29:17 shop plan[537623]: ** (WithClauseError) no with clause matching: {:too_many_attempts, "/tmp/plug-1664", 10}
Sep 29 11:29:17 shop plan[537623]:     (phoenix_live_view 0.17.11) lib/phoenix_live_view/upload_channel.ex:60: Phoenix.LiveView.UploadChannel.join/3
Sep 29 11:29:17 shop plan[537623]:     (phoenix 1.6.12) lib/phoenix/channel/server.ex:376: Phoenix.Channel.Server.channel_join/4
Sep 29 11:29:17 shop plan[537623]:     (phoenix 1.6.12) lib/phoenix/channel/server.ex:298: Phoenix.Channel.Server.handle_info/2
Sep 29 11:29:17 shop plan[537623]:     (stdlib 4.0.1) gen_server.erl:1120: :gen_server.try_dispatch/4
Sep 29 11:29:17 shop plan[537623]:     (stdlib 4.0.1) gen_server.erl:1197: :gen_server.handle_msg/6
Sep 29 11:29:17 shop plan[537623]:     (stdlib 4.0.1) proc_lib.erl:240: :proc_lib.init_p_do_apply/3

At first I thought the problem occured because of some sort of connection error because of the :too_many_attempts in the error messages, however a second look revealed that it was related to the local file system at /tmp/plug-1664.

Quickly checking that folder the problem was immediately apparent: The folder belonged to a different user! To clarify, if there are multiple Phoenix applications on one of may machines, I run each one with a different Linux user. So the problem was that the Plug.Upload module was creating a temporary folder for storing the uploads, and the name of that folder is simply plug-<PID>. However in my case another one of my other applications with user app-a had already created a folder with that name, so it belonged to app-a and thus the new application with user app-b could not write to that temporary folder…

app-b@server:$ ls -l /tmp
total 2620
drwxr-xr-x 2 app-a app-a   4096 Sep 22 13:41 plug-1663

Luckily the solution turned out to be easy, there is an environment variable PLUG_TMPDIR so that you can set a different tmp folder for each application, so in your startup config you can simply add a different tmp folder for each application:

PLUG_TMPDIR=/tmp/phoenix-application-app-a

Thanks to @damir for pointing out this solution!