13
votes

Users of my app should be able to upload files such as images. Where, in what folder, should I save those files? I'm not that familiar with deploying Elixir/Phoenix applications, but I want not to include those files into the output, packed file(s) that are generated when I'm deploying my application. In other words, I don't want to somehow statically embed uploaded images and files into my application. So where should I store them?

2

2 Answers

9
votes

First of all there are two different options:

  1. You can store your uploads locally
  2. You can store them on external services, such as Amazon S3

Choosing the right option heavily depends on your business logic, number of users and requests and your deploying strategy (for example Heroku does not allow to store uploaded files on their dynos).

Locally

So, the way store files locally is described in this article. The short answer is:

# lib/my_app/endpoint.ex

plug Plug.Static,
  at: "/uploads", from: Path.expand("./uploads"), gzip: false 

Amazon

When dealing with Amazon S3, you would still use arc and the basic setup will remain the same as in the article above, but things are just slightly different and requires to reconfigure your application for a little bit:

Add {:ex_aws, "~> 0.4"}, to deps. And add to the config:

config :arc,
  bucket: "your-bucket",
  virtual_host: true

config :ex_aws,
  access_key_id: System.get_env("AWS_ACCESS_KEY_ID"),
  secret_access_key: System.get_env("AWS_SECRET_ACCESS_KEY"),
  s3: [
    scheme: "https://",
    host: "your-region.amazonaws.com",
    region: "your-region"
  ]

That's basically it. See full installation instructions.

P.S. Quite strange that official docs don't cover this topic, I guess it could be improved.

7
votes

Add this to app/lib/app/endpoint.ex

plug Plug.Static,
  at: "files/", from: "/var/www/app/files/", gzip: false

and store the uploaded files at /var/www/app/files/

The files will be served at http://localhost:PORT/files/

You can learn more at https://hexdocs.pm/plug/Plug.Static.html

Also, using something like nginx to serve the files in production environment may be a better option depending on your requirements.