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.

posilva

posilva

Kamal and Hetzner does the trick:

dtew

dtew

I have an old macbook pro (with a broken screen), plugged into the internet in the office, on which I run cloudflare tunnel for free. I run multiple phoenix apps which people access via a domain name, in the usual way. (In my case, these are not public sites … they are for our internal users). If you have a suitable macbook (or pc), then this is all quite simple (even for me → chatGPT is my friend) and free except for electricity. This has been running successfully - faultlessly one could say, for over 18 months.

(I also have cloudflared on my dev macbook for development - same idea).

Where Next?

Popular in Questions Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
pgiesin
This should be a simple problem but I just can’t seem to figure it out. I have a standalone Elixir app that won’t find the database. Dep...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
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
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
AstonJ
by Lance Halvorsen Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
460 27162 124
New

We're in Beta

About us Mission Statement