Deployex
The ideal project to supervise your Elixir/Erlang/Gleam application
Install / Use
/learn @thiagoesteves/DeployexREADME
DeployEx
Who supervises the supervisor (of your application)?
DeployEx is a lightweight tool designed for managing deployments for Beam applications (Elixir, Gleam and Erlang) without relying on additional deployment tools like Docker or Kubernetes. Its primary goal is to utilize the release package for executing full deployments or hot-upgrades, depending on the package's content, while leveraging OTP distribution for monitoring and data extraction.
DeployEx acts as a central deployment runner, gathering crucial deployment data such as the current version and release package contents. The content of the release package enables it to run for a full deployment or a hot-upgrade. Meanwhile, on the development front, your CI/CD pipeline takes charge of crafting and updating packages for the target release. This integration ensures that DeployEx is always equipped with the latest packages, ready to facilitate deployments.
To learn more about DeployEx and the advantages of removing containerized abstractions from your deployment process, check out the talk Bring back the power of Beam deployments with DeployEx at CODE BEAM America 2025.

Upon deployment, the following dashboard becomes available, providing easy access to logs, the terminal, process observability, and much more for both DeployEx and the monitored applications.

🔉 Features
- Monitors multiple Beam application nodes (Elixir/Erlang/Gleam) and automatically restarts them if they crash for any reason.
- Includes a backoff delay restart mechanism to prevent excessive restarts.
- Performs full deployments based solely on the release files generated by:
mix releasefor Elixir.gleam exportfor Gleam.rebar3 as prod tarfor Erlang.
- Supports hot code reloading for:
- Elixir application (and libraries) using the [Jellyfish][jyf] library.
- Elixir umbrella applications (and libraries) using the [Jellyfish][jyf] library.
- Erlang application using the rebar3_appup_plugin plugin.
- DeployEx (and libraries) itself (Isn't that awesome?)
- Supports the following cloud providers (with terraform files):
- Amazon Web Services (AWS)
- Google Cloud Platform (GCP)
- Supports local environments for non-cloud deployments
- Provides rollback functionality if a monitored app version remains unstable for 10 minutes (time configurable).
- Rolled-back monitored app versions are ghosted, preventing their redeployment.
- Ensures all nodes remain connected to the OTP distribution, including DeployEx itself.
- Supports OTP distribution with mutual TLS (mTLS) for secure monitoring of apps and DeployEx.
- Provides the ability to run pre-commands prior deployments for Database migrations or any other eval command.
- Provides a friendly UI that only authenticated users can access.
- Allows setting a previously configured version in the UI, enabling DeployEx to enforce deployment of a specific version.
- Supports individual application restarts via the UI, including DeployEx itself.
- Provides easy access to the application shell:
- IEx shell for monitored Elixir apps and DeployEx.
- Erlang shell for monitored Gleam/Erlang apps.
- Provides monitoring and restart mechanisms for host memory thresholds and beam statistics of monitored applications, including port, atom, and process metrics.
- Supports access to live log files (stdout and stderr) for both monitored apps and DeployEx.
- Supports observability for all connected applications via [Observer Web][owb].
- Supports safe tracing for all connected applications.
- Provides visualization of Host System memory and CPU usage.
- Provides easy access to the host shell (tmux).
- Provides script to be used with ubuntu/debian hosts to install/update and hotupgrade DeployEx.
- Provides status information per node:
- OTP connectivity
- Version history
- Last deployment status
- Number of crash restarts
- Number of forced restarts
- And much more ...
[!NOTE] All examples and deployments in this project use NGINX as a reverse proxy and load balancer. However, DeployEx does not depend on NGINX; it is used here purely for convenience.
🚀 New Monitoring Feature!
Your application is now better protected from crashes caused by excessive memory usage, port/atom exhaustion, or too many processes.
🧠 Curious why monitoring memory is essential?
Check out this must-watch video:
▶️ Battling Memory Leaks: Tales from the Trenches at WhatsApp
⚠️ What is coming next?
📁 Getting Started
Since OTP distribution is heavily used between the DeployEx and Monitored Applications, users must ensure that both applications are running the same OTP Major version to prevent compatibility issues and system malfunctions. DeployEx releases will contain binaries for the following OTP versions:
| DeployEx version | <img src="https://img.shields.io/badge/OTP-27-green.svg"/> | <img src="https://img.shields.io/badge/OTP-28-green.svg"/> | | ------------------------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | | 0.9.0 :soon: | 27.3.4.6 | 28.3 | | 0.8.0 | 27.3.4.3 | 28.1.1 | | 0.7.3 | 27.3.4.3 | 28.1.1 [1] | | 0.7.2 | 27.3.4.3 | 28.1 [1] | | 0.7.1 | 27.3.4.3 | 28.1 [1] | | 0.7.0 | 27.3.4.3 | 28.1 [1] | | 0.6.1 | 27.3.4.2 | 28.0.2 [1] | | 0.6.0 | 27.3.4.2 | 28.0.2 [1] |
- [1] - Binaries for
OTP-28are compiled with Elixir 1.18.4-otp-27
Running the application
You can kickstart the setup with the following commands, the default number of replicas is 3:
mix deps.get
iex --sname deployex --cookie cookie -S mix phx.server
Erlang/OTP 28 [erts-16.1.1] [source] [64-bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit]
[info] Initializing HotUpgrade server
[info] Initializing Engine Server for myphoenixapp
[info] Initializing ConfigWatcher for YAML configuration
[info] Initializing Watchdog Server
[info] Running DeployexWeb.Endpoint with Bandit 1.8.0 at 127.0.0.1:5001 (http)
[info] Access DeployexWeb.Endpoint at http://localhost:5001
Interactive Elixir (1.19.3) - press Ctrl+C to exit (type h() ENTER for help)
[watch] build finished, watching for changes...
Rebuilding...
Done in 993ms.
[error] Error downloading release version for myphoenixapp, reason: {:error, :enoent}
[warning] No versions set yet for myphoenixapp
Now you can visit localhost:5001 from your browser and enter the credentials for the admin user, username: admin password: deployex. You should expect the following dashboard:

[!NOTE] The error message in the CLI is due to no monitored app is available to be deployed. If you want to proceed for a local test, follow the steps at Running DeployEx and Monitored app locally. Also, it is important to note that the distribution will be required so this is the reason to add
-sname deployexin the command
How DeployEx handles monitored application Version/Release
The DeployEx app expects a current.json file to be available, which contains version, hash information and any pre-command. This file is mandatory for full deployment and hot upgrades.
Version file (current.json)
Expected location in the release folder:
# production path
./{bucket}/versions/{monitored_app}/{env}/current.json
# local test path
/tmp/deployex/bucket/versions/{monitored_app}/{env}/current.json
Expected JSON format for current.json:
{
"version": "1.0.0",
"pre_commands": ["eval MyApp.Migrator.create", "eval MyApp.Migrator.migrate"], // optional field
"hash": "local"
}
Once the file is captured, the deployme
