In a Plug.Static, what does the atom :namefotheapp resolve to?

Hello all,

I am very new to Elixir and currently (having a great time) refactoring one of my app’s simpler back-end to Phoenix.

For context: my app is dockerized. Inside the container, the architecture is simply:
/app/ |
| – lib/
| – priv/
| – test/
| – uploads/

And my app is called, well, “app” (a mistake in hindsight, it’s very annoying to look at the architecture of my folders).

After failing few days prior, today I tried and succeeded to serve images from uploads/.
I tried what the Plug docs suggested :

#lib/app_web/endpoint.ex
plug(Plug.Static,
  at: "/uploads",
  from: {:app, "uploads/"}  
)

When that didn’t work and after a couple hours, I just put in the full path of the uploads folder as it is in my docker, and it works :

#lib/app_web/endpoint.ex
  plug(Plug.Static,
    at: "/uploads",
    from: "/app/uploads"
  )

I would rather not hard code it, in case I move the server around.

Here are my questions :

  • From that plug, what dos {:app, "uploads/"} resolve to ? I have learned that an atom is a variable whose name is also its value. As such, I thought it would be “app/uploads/”, starting from /
  • In the future, how can I print/ debug or search such things for myself ? What is the proper term to use, instead of “the :nameofmyapp atom” (if there even is such a term)

Thank you for your time,

The :from atom is the fs directory where files are served from. If it is a tuple, it will use the working directory of the application name, in this case :app.

https://hexdocs.pm/plug/Plug.Static.html

For your second question, you usually can find the documentation by searching the plug name and the atom option that you are not familiar with.

Atoms are not variables, the are considered constant values and are used as identifier keys in data structures.

I suggest that you read through the Elixir guide, as your foundation is shaky and you’d be going in circles (as exhibited above) as you don’t quite understand what you’re looking at when you’re trying to debug something.

https://hexdocs.pm/elixir/introduction.html

Thank you for correcting me on atoms. I come from JS so I’m used to constants falling under the “variable” umbrella.
I’ll do some reading on how those are defined outside of that to make sure I use the right terms.

Your reply seems to validate that indicating :from as a tuple should be correct so I will investigate in on that further, see what logic I’m not getting (and keep reading the guide !)

Thanks again for taking the time to reply, have a great day

Hello and welcome!

I would make sure to read the directory structure docs as well. While uploads should really be stored in cloud/volume storage, one place you don’t want to be storing them is in the root of the project. In spite of its potentially somewhat misleading name, /priv is where we store additional resources for our projects (see some discussion here around the name). For example, when you compile /assets, the output is copied into /priv. This is because when you build a release, the directory structure ends up looking much different. You are able to reliably find your priv dir with :code.priv_dir(:my_app) (or :app in your case).

As you can see from the Plug.Static docs linked above, giving an app’s name as an atom to :from will default to serving static assets from priv/static. All you have to do is create priv/static/uploads then, in MyAppWeb.Endpoint there is a function call static_assets that returns a list. Add uploads to that list and you should be good to go.

1 Like

Hello and thank you !

Thanks for explaining this, I didn’t give it a second look because of the folder name indeed.

While I’ll go the service/cloud route later on, I like to keep it simple for now while I’m learning the fundamentals (no need to add another layer of complexity). I appreciate the feedback and the suggestion, I’ll go implement that right now :slight_smile:

1 Like

For sure! I just wanted to cover the bases just in case.

1 Like