Fl4m3Ph03n1x

Fl4m3Ph03n1x

How to add extra files to umbrella release?

Background

I have an umbrella project with several apps inside. I want to create a special release that will have additional files inside, like JSON files, configuration, images etc.

I know that in a normal Phoenix project everything inside the priv folder will be in the release under "#{child-app-name}-#{child-app-version}/priv".

Problem

The issue here is that some of my configuration files depend on these assets. So in my config/prod.exs I have tried several ways to get the path dynamically, bu nothing works. The following examples all fail:

config :my_app,
  products: "application-data\\lib\\web_interface-#{Application.spec(:web_interface, :vsn) |> to_string()}\\priv\\persistence\\products.json" 

config :my_app,
  products: "application-data\\lib\\web_interface-#{WebInterface.Mixfile.project()[:version]}\\priv\\persistence\\products.json"

config :my_app,
  products:  "application-data\\lib\\web_interface-#{Application.get_application(:web_interface)}\\priv\\persistence\\products.json"

The one that works is as follows:

products: "application-data\\lib\\web_interface-2.2.0\\priv\\persistence\\products.json",

You can see the issue here is that the version number will change from release to release, and I don’t want to change my prod.exs every time a new release is made.

My solution would be to move the assets I depend on to the root level, so my configuation can access them via "application-data\\assets\\products.json or something similar.

Questions

Is this possible to achieve, given that I am building a tar in my release?

Marked As Solved

LostKobrakai

LostKobrakai

That’s the way to go yes.

Also Liked

LostKobrakai

LostKobrakai

You should be using Application.app_dir(:app_name, "priv/dir/…") in your code to reference files in priv/ folder. You can use configuration for the second parameter if needed.

entone

entone

Additionally you can use the :code.priv_dir/1 function

christhekeele

christhekeele

FWIW these days I register these release-resiliant path concerns in my application’s compile-time config.exs. I find it to be more reliable and easier to reason about if I do it myself:

# config/config.exs
import Config

root_dir = Path.expand("../..", __DIR__)
priv_dir = Path.expand(Path.join(project_root, "priv"))
assets_dir = Path.expand(Path.join(project_root, "assets"))
static_dir = Path.expand(Path.join(priv_dir, "static"))
static_assets_dir = Path.expand(Path.join(static_dir, "assets"))

config :project, :root_dir, root_dir
config :project, :priv_dir, priv_dir
config :project, :assets_dir, assets_dir
config :project, :static_dir, static_dir
config :project, :static_assets_dir, static_assets_dir

# Use variables above to configure things like `:esbuild` in this file

# Use `Application.compile_env!(:project, :static_assets_dir)`
# to configure things like `Plug.Static`

This works well for umbrella apps, since the each have their own config :app_name space.

For often-referenced paths, I’ll even add a shortcut in my project’s main entrypoint module:

# lib/project/application.ex
defmodule Project.Application do
  def app_name, do: :project
  def root_dir, do: Application.compile_env!(app_name(), :root_dir)
  def static_dir, do: Path.relative_to(Application.compile_env!(app_name(), :static_dir), root_dir())
end

Then, for example, configuring Plug.Static can look like:

# lib/project_web/endpoint.ex
plug Plug.Static,
  at: "/",
  from: {Project.Application.name(), Project.Application.static_dir()}

Last Post!

christhekeele

christhekeele

I’ll admit the project I took this from has a whole lot of going on in the priv dir, in many different umbrellas, so at some point it became worth abstracting further; I don’t think I’d recommend it for the standard standalone phoenix web app.

Where Next?

Popular in Questions Top

ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New

Other popular topics Top

baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 44139 214
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement