All Projects → keathley → Vapor

keathley / Vapor

Licence: mit
Runtime configuration system for Elixir

Programming Languages

elixir
2628 projects

Projects that are alternatives of or similar to Vapor

Chezmoi
Manage your dotfiles across multiple diverse machines, securely.
Stars: ✭ 5,590 (+1107.34%)
Mutual labels:  configuration
Centraldogma
Highly-available version-controlled service configuration repository based on Git, ZooKeeper and HTTP/2
Stars: ✭ 378 (-18.36%)
Mutual labels:  configuration
Anyway config
Configuration library for Ruby gems and applications
Stars: ✭ 409 (-11.66%)
Mutual labels:  configuration
Config
⚙ Config.Net - the easiest configuration framework for .NET developers
Stars: ✭ 349 (-24.62%)
Mutual labels:  configuration
Icingaweb2 Module Director
The Director aims to be your new favourite Icinga config deployment tool. Director is designed for those who want to automate their configuration deployment and those who want to grant their “point & click” users easy access to the configuration.
Stars: ✭ 359 (-22.46%)
Mutual labels:  configuration
Conform
Easy, powerful, and extendable configuration tooling for releases.
Stars: ✭ 384 (-17.06%)
Mutual labels:  configuration
Config
The Config component helps you find, load, combine, autofill and validate configuration values of any kind, whatever their source may be (YAML, XML, INI files, or for instance a database).
Stars: ✭ 3,671 (+692.87%)
Mutual labels:  configuration
Spacemacs
A community-driven Emacs distribution - The best editor is neither Emacs nor Vim, it's Emacs *and* Vim!
Stars: ✭ 21,906 (+4631.32%)
Mutual labels:  configuration
Nickel
Cheap configuration language
Stars: ✭ 367 (-20.73%)
Mutual labels:  configuration
Agileconfig
基于.NET Core开发的轻量级分布式配置中心 / .NET Core light configuration server
Stars: ✭ 403 (-12.96%)
Mutual labels:  configuration
Craco
Create React App Configuration Override, an easy and comprehensible configuration layer for create-react-app
Stars: ✭ 5,285 (+1041.47%)
Mutual labels:  configuration
Isopod
An expressive DSL and framework for Kubernetes configuration without YAML
Stars: ✭ 358 (-22.68%)
Mutual labels:  configuration
Augeas
A configuration editing tool and API
Stars: ✭ 384 (-17.06%)
Mutual labels:  configuration
Confita
Load configuration in cascade from multiple backends into a struct
Stars: ✭ 344 (-25.7%)
Mutual labels:  configuration
Emacs4developers
A document to help developers to use Emacs as a developer
Stars: ✭ 430 (-7.13%)
Mutual labels:  configuration
V2ray Step By Step
This repo is a fork of ToutyRater/v2ray-guide, we aim to provide a new step-by-step guide of v2ray
Stars: ✭ 341 (-26.35%)
Mutual labels:  configuration
Confy
🛋 Zero-boilerplate configuration management in Rust
Stars: ✭ 379 (-18.14%)
Mutual labels:  configuration
Koanf
Light weight, extensible configuration management library for Go. Built in support for JSON, TOML, YAML, env, command line, file, S3 etc. Alternative to viper.
Stars: ✭ 450 (-2.81%)
Mutual labels:  configuration
Neovim Init.vim
🏮 The perfect Neovim configuration for productive people who wants to level up their Vim experience with a clean, minimal-looking aesthetic, as well as a highly extensible, easily customizable set of popular tools and shortcuts to boost productivity. 🏮
Stars: ✭ 440 (-4.97%)
Mutual labels:  configuration
Wechat Mini Program Wiki
Anyone can make a Wechat mini-program with the first and only English Wiki made to decrypt the Mini-program framework.
Stars: ✭ 388 (-16.2%)
Mutual labels:  configuration

Vapor

Loads dynamic configuration at runtime.

Why Vapor?

Dynamically configuring elixir apps can be hard. There are major differences between configuring applications with mix and configuring applications in a release. Vapor wants to make all of that easy by providing an alternative to mix config for runtime configs. Specifically Vapor can:

  • Find and load configuration from files (JSON, YAML, TOML).
  • Read configuration from environment variables.
  • .env file support for easy local development.

Example

defmodule VaporExample.Application do
  use Application
  alias Vapor.Provider.{File, Env}

  def start(_type, _args) do
    providers = [
      %Env{bindings: [db_url: "DB_URL", db_name: "DB_NAME", port: "PORT"]},
      %File{path: "config.toml", bindings: [kafka_brokers: "kafka.brokers"]},
    ]

    # If values could not be found we raise an exception and halt the boot
    # process
    config = Vapor.load!(providers)

    children = [
       {VaporExampleWeb.Endpoint, port: config.port},
       {VaporExample.Repo, [db_url: config.db_url, db_name: config.db_name]},
       {VaporExample.Kafka, brokers: config.kafka_brokers},
    ]

    opts = [strategy: :one_for_one, name: VaporExample.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

Precedence

Vapor merges the configuration based on the order that the providers are specified.

providers = [
  %Dotenv{},
  %File{path: "$HOME/.vapor/config.json", bindings: []},
  %Env{bindings: []},
]

Env will have the highest precedence, followed by File, and finally Dotenv.

Reading config files

Config files can be read from a number of different file types including JSON, TOML, and YAML. Vapor determines which file format to use based on the file extension.

Options on bindings

Bindings for %Env{} and %File{} providers support a number of options:

  • :map - Allows you to pass a "translation" function with the binding.
  • :default - If the value is not found then the default value will be returned instead. Defaults always skip the translations.
  • :required - Marks the binding a required or not required (defaults to true). If required values are missing, and there is no default present, then the provider will return an exception. If the binding is marked required: false, then the provider returns the key with a nil value.
providers = [
  %Env{
    bindings: [
      {:db_name, "DB_NAME"},
      {:db_port, "DB_PORT", default: 4369, map: &String.to_integer/1},
    ]
  }
]

Adding configuration plans to modules

Vapor provides a Vapor.Plan behaviour. This allows modules to describe a provider or set of providers.

defmodule VaporExample.Kafka do
  @behaviour Vapor.Plan

  @impl Vapor.Plan
  def config_plan do
    %Vapor.Provider.Env{
      bindings: [
        {:brokers, "KAFKA_BROKERS"},
        {:group_id, "KAFKA_CONSUMER_GROUP_ID"},
      ]
    }
  end
end

config = Vapor.load!(VaporExample.Kafka)

Planner DSL

While using the structs directly is a perfectly reasonable option, it can often be verbose. Vapor provides a DSL for specifying configuration plans using less lines of code.

defmodule VaporExample.Config do
  use Vapor.Planner

  dotenv()

  config :db, env([
    {:url, "DB_URL"},
    {:name, "DB_NAME"},
    {:pool_size, "DB_POOL_SIZE", default: 10, map: &String.to_integer/1},
  ])

  config :web, env([
    {:port, "PORT", map: &String.to_integer/1},
  ])

  config :kafka, VaporExample.Kafka
end

defmodule VaporExample.Application do
  use Application

  def start(_type, _args) do
    config = Vapor.load!(VaporExample.Config)

    children = [
       {VaporExampleWeb.Endpoint, config.web},
       {VaporExample.Repo, config.db},
       {VaporExample.Kafka, config.kafka},
    ]

    opts = [strategy: :one_for_one, name: VaporExample.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

Custom Providers

There are several built in providers

  • Environment
  • .env files
  • JSON
  • YAML
  • TOML

If you need to create a new provider you can do so with the included Vapor.Provider protocol.

defmodule MyApp.DatabaseProvider do
  defstruct [id: nil]

  defimpl Vapor.Provider do
    def load(db_provider) do
    end
  end
end

Why does this exist?

While its possible to use Elixir's release configuration for some use cases, release configuration has some issues:

  • If configuration ends up in Application config then its still functioning as a global and is shared across all of your running applications.
  • Limited ability to recover from failures while fetching config from external providers.
  • Its difficult to layer configuration from different sources.

Vapor is designed to solve these problems.

Installing

Add vapor to your mix dependencies:

def deps do
  [
    {:vapor, "~> 0.10"},
  ]
end

Resources from the community

Configuring your Elixir Application at Runtime with Vapor

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].