I’m trying to deploy an app that uses Liveview uploads to save to both a local /uploads folder as well a S3 bucket. I guess I just wanted to test how both work! Anyway, the upload to S3 is working in production but I’m getting 404 on images after attempting to upload locally. I am deploying with Releases and when I build with images uploaded in dev, they are available in the local /upload folder. But I soon as I try to upload a new image while running the build I get a 404. Any ideas? What am I missing?
In the context of the local dev environment this works great, since the application is running from the project’s root folder. In prod, however, your application is running from within _build/prod/rel/..., thus why the file isn’t copied where you intended to when you pass a relative path.
Now, the uploads directory is pretty much a config concern, meaning I would personally prefer to have it in a config file rather than in a module’s function or a module’s attribute. For prod, pass the absolute path to it.
As already mentioned the priv directory is not always in the same place relative to the cwd. Use Application.app_dir(:my_app, "priv/static/uploads") instead, which will work in any environment.
I just followed the instructions above, specifically replacing "priv/static/uploads" with Application.app_dir(:my_app, "priv/static/uploads"), and I still receive the error:
** (File.CopyError) could not copy from "/tmp/plug-1618/live_view_upload-1618951129-355143682828838-1" to "/home/runner/work/MyApp/MyApp/_build/test/lib/my_app/priv/static/uploads/ebeab0e5-115e-4ace-a6a7-776877c325f4.png": no such file or directory
I am running the code via GitHub Actions Elixir CI.
Yes. The functionality is working fine in development. But then I wrote a unit test for the function, and it passes in my local test environment, but when I push the commit through CI (Github Actions), that test fails due to the aforementioned File.CopyError.
Still the error seems to suggest at least some part in the path of /home/runner/work/MyApp/MyApp/_build/test/lib/my_app/priv/static/uploads/ebeab0e5-115e-4ace-a6a7-776877c325f4.png does not exist. You might have mantually created the uploads directory in development, but in CI it’s not present.
Not sure why it’s not there… When I check _build/test/ on my local machine, lib/my_app/priv/static/uploads is there alright, and I know I didn’t create that manually. If it’s missing, how can I ensure the folder is being created in the build?
In the :dev and :test environments, the priv dir is a symlink to the /priv dir at the root of your app.
/priv/static/ is included in the .gitignore for a Phoenix app by default, so if I had to guess your priv directory likely exists in prod, but the sub-directories do not.
Somewhere in your production build you can run mkdir -p /path/to/my/app/priv/static/uploads to ensure the directory exists.
PS– With the latest release of LiveView we updated the Uploads guides to use :code.priv_dir(:my_app) when building the path (though I probably would have used Application.app_dir if I had thought about it at the time).