6

I am using monger to fetch and save some data in MongoDb from my Clojure simple app. I have strong Ruby on Rails background so I am familiar with database settings per environment (development, test, production). I want to have something similar in Clojure. How can I add the environment to my code? I want to do it in Clojure-way, code as data, without any yaml files. I am using Leiningen if it changes something.

3 Answers 3

11

You can use Leiningen profiles feature.

In your project.clj define your profiles (most cases you need dev and prod)

:profiles {:dev {:resource-paths ["resource-dev"]} :prod {:resource-paths ["resource-prod"]}} 

Now create 2 directories resource-dev and resource-prod and create config.clj file in both of them which will have define a map to store configuration. Something like:

(ns myapp.config) (def config {:database "dev"}) 

Then in your app code you can use below snippet to load the config file (only once) and access the config map:

(use 'clojure.java.io) (def config (delay (load-file (.getFile (resource "config.clj"))))) (defn get-config [] @(force config)) 

Now you can use get-config function to access the config map.

Sign up to request clarification or add additional context in comments.

5 Comments

How does the app know which environment is running to load the correct settings?
You run the app with a specific profile : lein with-profile dev run
And when you deploy to somewhere like Heroku and you can't use lein with-profile (I think, but I have 5 days of after hours Clojure under my belt...). Also, can you set defaults such as run uses "dev" and your tests use "test" unless specified elsewhere?
John Doe - You can use Heroku and lein with-profile via your Procfile, e.g. web: lein with-profile production trampoline run -m horus.core
I'm a little new to clojure, but the above didn't work until I removed the @. What exactly was that deref-future (?) supposed to do there?
5

Have a look at clj-boilerplate, a sample web app I created.

There's info in the README about how it understands environments out of the box and an example environment file can be seen here - but it looks something like this:

(def config (let [env (or (System/getenv "ENVIRONMENT") "development")] ((keyword env) {:development {:database-url "postgres://lborges:@localhost/clj-boilerplate"} :test {:database-url "postgres://lborges:@localhost/clj-boilerplate-test" :production {:database-url (System/getenv "DATABASE_URL")}}))) 

I have since evolved this approach but this should get you started.

Hope this helps.

Comments

0

Have a look at using Confijulate (plug for a personal project!):

https://github.com/bbbates/confijulate

It allows you to define environment specific configuration maps, and specify which one to use via JVM system properties.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.