Docker Cloud (formerly Tutum) help to deploy containers image on node clusters. Nodes can be provisioned directly from the service (Digital Ocean, Azure, AWS, Packet.net, and IBM SoftLayer). Additionally is possible to use the function Bring your own node (BYON) to add any linux server connected to the internet as node and deploy on it.
I’m using this service to manage a stack (a set of images described by a file similar to docker-compose.yml) composed of a static webiste served by nginx, two api server built with elixir, nginx-proxy (for reverse proxing) and jrcs/letsencrypt-nginx-proxy-companion (create/renewal of Let’s Encrypt certificates automatically). Dcoker cloud provide with an interface to start/stop containers and scale up the same image to multiple nodes.
BYON requires some manual intervention, installing an agent and usually open a port (2375) in to the server firewall to let docker cloud communicate with the agent - additional ports are required to allow network overlay.
Scaleway is a cloud provider still in beta that offer the smaller server (VC1S - 2 x86 64bit Cores, 2GB memory - 50GB SSD Disk - 200Mbit/s badnwidth) for the price of 2.99 €/month. You can request an invite to the beta at https://www.scaleway.com/invite/
To open the port requested by the agent to communicate with docker cloud you need to go to security, pick one of the security group and open the necessary port as shown below. A security group is a set of firewall rules that could be applied to multiple servers.
I set up an ubuntu image (14.04) on the server run the command shown in the BYON pop-up on the server, the agent download and install docker and a few service images. After the installation complete it should connect to the Docker Cloud server and update the pop-up with a success message. Taking some times to connect I checked the log of the agent
/var/log/dockercloud/agent.log and saw the following error.
To solve this issue is possible is necessary to create some loopback devices, once done the agent start docker and notify Docker Cloud that is ready. Once done is possible to start containers on the newly provided node.
I’m building a bot for Telegram, once make a build with exrm I found myself some problem configuring the telegram api key using environment variables. I decided to share what I found because my google foo was not helpful at all.
config.exs is where the configuration of elixir project are added. The file is interpreted when a project is ran with
ies -S mix or
The values are retrieved during the lifetime of the application with the functions(get_env/3, fetch_env/2, fetch_env!/2) available in the module Application. To include values from the environment where the project is running System.get_env/1 is used.
Surprisingly (if you did not have an erlang background as me) when you make a release of your project with exrm the
config.exs file is executed at build time and the environment variables are crystallized in the build output.
The output from exrm contains a file named
sys.config that is the output of executing the
config.exs file and is defined as erlang terms. Once released editing this file is the only way to dynamically configure the application once built.
conform is a library from the same author of exrm and is been made to ease the configuration of elixir application. The library validate a property like file (
configuration/your_app.conf) against a configuration schema (
configuration/your_app.schema.exs) and generate the
sys.config file. The schema file contains descriptions, defaults, and types of the parameters. A property file is a lot easier and common to configure than a file containing erlang terms, additionaly conform add flexibility and more control over configurations.
A couple of task are made available to transition to a conform based configuration.
sys.config is generated at the start of the application, and using the plugin
exrm_conform at the start of a packaged application. This behaviour allow to load configuration parameter from environment variables defined when the application is started.
mix conform.new you will find a
yourapp.schema.exs in your
conf folder, this file has 3 main sections: mapping, transforms, and validators. The mapping section is where the parameters are defined and where you can set up defaults, descriptions, and type. The transform section allow to add transformation function to change or derive a configured parameter. In the end the validators sections allow to reject invalid configuration errors and stop the application.
At first I tried to add the reading from the environment variable to the default of the parameters, but this lend to an uncommon situation where a static parameter (the one in
yourapp.conf) will override a parameter derived from an environment variable.
Eventually I found that adding a function to transforms is probably a better way to do it.
In this case we are loading with the conform API the the configured value and return it only if the environment variable is empty. Generating the parameter in this way disallow to have a default in the mapping sections but a workaround would be to chain
|| to add a default value. I think that this approach is not bad for api key and similar values that you don’t want to checkin with your code (even if are keys of development environments).