I’m looking to deploy a Phoenix API to AWS. I don’t need any fancy features, I just need to be able to select a specific node type (high compute), and ideally it could be easy to deploy nodes.
There are thousands of guides I’m finding, and the 3 i’ve tried were all broken.
Is there a really good guide (in terms of security, scalability, configuration, etc), which I can just fully commit to going through?
It works great so far, the only part I’m confused on is where I define my environment variables so that REPLACE_OS_VARS from distillery can replace them. I’m assuming its not when i package the release, but after.
Hmm weird. I encountered like 3 or 4 places that I fixed easily enough but it didn’t give me confidence in the guide. ultimately I stopped though because I didnt want to depend on amazon blackbox services which Ive had experience with before. Granted, my current method deals with Google blackbox services but I trust those more for some reason.
If you look at that link you will see REPLACE_OS_VARS in the docker image, so I basically do this (all the environment variables at this point look like "${THIS_FORMAT}":
I can see in their docker image they have REPLACE_OS_VARS I’m just wondering where they fit in AFTER release but before docker build? Can you explain what you mean by pre-configure hook?
Also as a side question. One thing I found really strange was that I could mix release with your standard "${VAR_HERE}"… and then when i would RUN the release with REPLACE_OS_VARS=true ... foreground it would work! This part I dont understand, how does the app know AT RUN TIME to replace the variables? Is that some code distilierry injects into my app to make it know to do that at run time rather than at compile time?
Damn well this looks super confusing. I’ll have to get docker running start to finish first then ill figure out how to do that.
How might I do that with this current strategy I’m doing, can you give me an examle of a single variable and where I put it so I don’t have to read all that (for now)
You’d choose a config provider, copy it into the release, and that’s it, I think.
Somewhere in rel/config.exs
environment :prod do
set config_providers: [
{Mix.Releases.Config.Providers.Elixir, ["${RELEASE_ROOT_DIR}/etc/config.exs"]}
]
set overlays: [
{:copy, "rel/config/config.exs", "etc/config.exs"}
]
end
In rel/config/config.exs
use Mix.Config
config :app, db_path: System.get_env("DB_PATH")
I’m not sure if distillery scripts use it for replacing ${RELEASE_ROOT_DIR} in its config.
The only use-case that I have for REPLACE_OS_VARS is setting the node name of the app to the ip address of the machine which is read at startup.
In rel/config.exs
environment :prod do
# ...
set(vm_args: "rel/vm.args")
set(pre_configure_hooks: "rel/hooks/pre_configure")
# ...
end
in rel/hooks/pre_configure/export_host_ipv4
#!/usr/bin/env bash
export HOST_IPV4
export REPLACE_OS_VARS=true
HOST_IPV4=$(
# just as an example, might not work actually
ifconfig \
| sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p' \
| grep '^10\.' # only interested in private network
)
I would personally recommend going with Docker for deployments on VPS systems. This helps you not becoming dependent on an individual provider and makes it easier to create repeatable deployments.
Check out this guide on Getting Started with Elixir and Docker I’ve created and let me know if you find it helpful!