CircleCI Elixir setup- 06/03/2019
The builds can be configured in a couple of different ways. The first one is to create a stand-alone job, which can be one of several types but in this case, we are using
There is a setup guide on the Circle CI website and there are other tutorials too which helped setting everything up.
CircleCI 2 configuration is based solely on the circleci YAML file (.circleci/config.yml). This is good as your CI pipeline will be treated as code and you won’t run into the problem where the person who setup the Jenkins instance two years ago and knows how it works has left the company. Jenkins configuration can of course also be treated as code but with many of the cloud CI providers there is no other option.
CircleCI uses Docker images to make it easier to run your own code as well as services the application depends on. For Phoenix applications, Postgresql is the most often used database and adding it in the CircleCI config file is easy. One only needs to specify the Docker image to use and any environment variables that are required for the operation of the service. CircleCI uses Docker to run the image and the service with possibly extra configuration that has been provided.
In this example, we use the Alpine Linux based Postgres 10 image. The environment variables define the values that can be used when connecting to the DB later on. Alpine Linux is a lightweight Docker image perfect for running services without too many dependencies and keeping the Docker images small for quick downloads.
- image: circleci/postgres:10-alpine environment: POSTGRES_USER: postgres POSTGRES_DB: app_test POSTGRES_PASSWORD: app_pw
yarn and handled by
Webpack. If the front-end needs to be tested in the same box, having a browser available in the Docker image makes things easier as one doesn’t need to be installed separately. CircleCI has made an image available that suits these needs perfectly, i.e.
elixir:node-browsers. It’s pulled in in the next config section shown below:
- image: circleci/elixir:1.8.1-node-browsers environment: MIX_ENV: test POSTGRES_USER: postgres POSTGRES_DB: app_test POSTGRES_PASSWORD: app_pw
When the application runs, it needs to connect to the DB and it can do just by with the help of the DB name, user and password configured above. The keys/values under the
environment key are set as part of the application environment and the application can pull in these values by defining the test configuration (config/test.exs) in the following way:
username: System.get_env("POSTGRES_USER") || "<local fallback>", password: System.get_env("POSTGRES_PASSWORD") || "<local fallback>", database: System.get_env("POSTGRES_DB") || "<local fallback>",
The local fallback values are options and are used when the environment variable is not set. I typically use static values during development on the local machine.
The full configuration is available in this gist.
CircleCI supports caching to make it possible to reuse specific directories from a build. Anything to do with
npm can be quite slow and being able to cache the assets is going to significantly speed up the builds. The configuration shown in the gist above has caching configured for both npm packages and Elixir dependencies. Much of the caching config is based on this blog post by Joe Ellis.
When adding a project to CircleCI, the UI suggests to create and push the config file to the repo and start building. The beauty of having a Yaml based CI configuration is that it’s easy as copying a file to get started.