artem

artem

Where do you host **small** or even tiny elixir projects?

I like creating small projects open to the whole world. Something in style of my_general_domain.com/great_mortgage_calc_in_live_view

These would never be very popular, they would always have tiny audience if any. If some of them by accident ever become popular, I’d deploy them on render.com or fly.io , but before it happens in many cases these aren’t even worth a domain.

If these were done in JS (even with some server side next.js/nuxt.js) I’d post endless amount of them on netlify.com or some competitor for free or very cheap.

What would be a place to host such projects when done in elixir? I don’t mind paying some $5-10 or even $20 a month for hosting, but not per-site.

Or how do you host your tiny hobby projects and exercises?

Marked As Solved

artem

artem

If anybody cares eventually I decided to install dokku on a cheap 2GB RAM machine. Had to mess with initial configuration a bit, unfortunately it doesn’t support modern elixir out of the box (as “herokuish” buildpacks do not know how to install recent ones), but I figured I can ask it to use gigalixir buildpacks which are probabaly supported by gigalixir folks. And figuring how to keep app logs permanent also took some time (dokku kind’a supports it, but without a clear guide).

Then deployment became pretty much “push to dokku”, I don’t even need to have git repo hosted anywhere - everything can be developed on my machine.

It still has some issues, e.g. machine once ran out of space because of lots of docker artifacts, so I had to google for proper docker cleaning commands.

Yet despite all these things, I really like ease of adding yet another app by few commands and git push. Feels good for the tiny projects which I do not really care about. Tons of them can now be hosted on a cheap machine easily.

Also Liked

D4no0

D4no0

The stack

I’ve personally deployed directly on VMs for years using docker-compose, that includes commercial products, some of them were pretty beefy. Not only this is painless after you have your sample configurations and a workflow, but you are never limited to one cloud provider/platform.

I used to run the following services by default:

  1. Nginx - running in reverse proxy mode that is also responsible for https traffic;
  2. Certbot - responsible for fetching and refreshing letsencrypt certificates;
  3. Postgres - in 95% of cases, having a self-managed postgres instance located on the same VM is better than alternatives, both in terms of reliability/resource usage/latency.

I’ve updated my setup recently and now I’m using nginx proxy manager instead of nginx+certbot, you lose the declarative approach, however it’s that much easier to get https up and running, for me this is always painful when deploying a brand new project.

The only caveat with this approach is that your project needs to be dockerized, I use mainly gitlab + custom runners to achieve this, however it’s clear that this setup is more involved out of the box because of docker, maybe it could be improved by injecting the release in the container instead of building immutable containers.

Deploying new versions

The setup I use to deploy new versions is pretty primitive, I basically have a git repo called my_project_infra, that contains the docker-compose.yml and all the additional configuration required to deploy that product + some shell scripts to make this work easier. I leverage on git to be able to revert to old configurations if something goes wrong, worked with this setup in production with great success.

I can do zero downtime deploys. The only big thing that this is missing is continuous delivery, which I want to do for all projects these days. I will definitely invest some time in the future to make this work independently of any cloud providers on the market.

Self-hosted vs VPS

Until recently, I was using hetzner (usually for dev envs + runners) and aws (for prod) VMs for deploy, until I recently finally configured my own server at home.

I want to say that having your own infrastructure makes things 100x times easier, especially if there is networking involved. I literally have now practically unlimited resources at the cost of 20$ I pay for the electricity (I have a beefy hp proliant server, so you might easily get away with 5$ for electricity if you have a more power-efficient system).

The home server is also times more reliable as I have it currently running in raid 1 + I plan on setting up a NAS for periodic backups/snapshots, this kind of reliability comes at a premium if you offload it to a cloud provider.

As for networking, as other mentioned above, if your provider blocks inbound connections, using cloudflare tunnels is the way to go, their free plan is very generous and it’s a turnkey solution that I’ve used reliably in the past. The only caveat is that you take some time to understand the security implications of passing unencrypted traffic through their systems.

derek-zhou

derek-zhou

If those small projects are all written by you, and you can ensure there is not library version conflict, you can run them all in the same Erlang release. There is main proxy, but something as simple as this will work, with liveview and all that.

defmodule MySuperProject.Plug do
  def init(options) do
    options
  end

  def call(%Plug.Conn{host: "app1.host.domain"} = conn, opts) do
    App1Web.Endpoint.call(conn, opts)
  end

  def call(%Plug.Conn{host: "app2.host.domain"} = conn, opts) do
    App2Web.Endpoint.call(conn, opts)
  end

  def call(conn, opts) do
    DefaultAppWeb.Endpoint.call(conn, opts)
  end
end

arcanemachine

arcanemachine

If you own a domain (e.g. artem.xyz) you can put a Phoenix site on each subdomain (e.g. project-1.artem.xyz, project-2.artem.xyz), or you can use a reverse proxy like nginx to put each project in a different path for a given origin (e.g. artem.xyz/project-a, artem.xyz/project-b).

I put my toy projects on a cheap VPS (Hetzner). It’s good practice to run something like that because it also teaches you the basics of DevOps. Sure, you can pay someone like Netlify or Render or fly.io to hide the difficult stuff away, but learning how to do it yourself is a great skill to have. And it’s really not that difficult once you understand what is going on.

So my setup for these toys is to create the server, then use Ansible to set up the server (create users, disable root access, install and configure services, etc.). Then I have a playbook that pulls my Git repo, builds a Docker image, then restarts the server with the new container.

First, you set things up manually, then automate them. There’s tons of great tutorials online that will show you how to set this stuff up.

10
Post #7

Last Post!

johns10davenport

johns10davenport

I’ve moved to hetzner and kamal.

Where Next?

Popular in Questions Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New

Other popular topics Top

grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 54260 488
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
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
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New

We're in Beta

About us Mission Statement