The Twelve-Factor App, Part 2: Dependencies & Config


Summary

This episode continues the discussion of the Twelve-Factor App methodology, focusing on factors 2 and 3: dependencies and configuration.

Factor 2 emphasizes explicitly declaring and isolating dependencies through manifest files like gem files, package.json, bower.json, or Composer files. The host explains that any third-party libraries or frameworks your application relies on should be listed in a manifest file rather than bundled directly into your source code. This approach allows you to easily install dependencies on any machine, keeps your repository size small by excluding third-party code, and simplifies updating dependencies by changing version numbers in the manifest.

Examples of package managers mentioned include Ruby’s Bundler (gem files), Node’s npm (package.json), Bower, and PHP’s Composer. The host stresses the importance of using .gitignore to exclude dependency folders like node_modules from version control, preventing unnecessary bloat in your repository.

Factor 3 focuses on storing configuration in the environment rather than in source code. Configuration includes sensitive information like API keys, passwords, and personal data that should not be committed to version control. The host advises that your code should be deployable to any environment (development, testing, staging, production) without exposing credentials. Environment variables are the recommended approach, with tools like Heroku providing interfaces to set them securely.

The episode includes a sponsor segment for Harvest, a time-tracking tool for developers that integrates with project management platforms like Trello, GitHub, and Jira. The host encourages listeners to leave reviews on iTunes to help the podcast grow.


Recommendations

Tools

  • Harvest — A time-tracking tool for developers that integrates with Trello, GitHub, and Jira. It allows starting timers directly from issues and can generate invoices from billable hours.

Topic Timeline

  • 00:00:00Introduction to Twelve-Factor App factors 2 and 3 — Jonathan Cottrell introduces the episode, which will cover factor 2 (dependencies) and factor 3 (config) of the Twelve-Factor App methodology. He clarifies that while the methodology originated from Heroku, it can be applied to any platform. The focus is on explicitly declaring and isolating dependencies, and storing configuration variables in the environment rather than source code.
  • 00:01:19Factor 2: Explicitly declaring and isolating dependencies — The host explains the importance of using manifest files (like gem files, package.json, bower.json) to declare dependencies. This prevents bringing dependencies directly into source code and avoids monkey patching. He notes that most codebases rely on third-party libraries, especially in backend and increasingly frontend development. Manifest files ensure that any machine running the application can install the necessary dependencies, making deployments reliable.
  • 00:03:22How manifest files work and their benefits — Jonathan describes how manifest files specify what an application needs to run, using examples like adding the Devise gem to a Rails gemfile. He explains that manifest files allow you to install dependencies on any new machine or deployment endpoint. Benefits include keeping repositories small by excluding third-party code, easier sharing with teammates, and simpler dependency updates by changing version numbers in the manifest file.
  • 00:06:41Using .gitignore for dependency folders — The host emphasizes the importance of ignoring dependency folders (like node_modules) in version control using .gitignore. This prevents large amounts of third-party code from bloating the repository. He mentions this is particularly relevant for frontend developers using Node.js, where node_modules are installed in the same directory as package.json.
  • 00:09:57Factor 3: Storing config in the environment — Jonathan discusses factor 3: storing configuration in environment variables rather than source code. The key test is being able to push code to an open-source platform without exposing credentials like API keys or passwords. Configuration should be environment-specific (development, testing, staging, production) and read from environment variables, which is more secure than storing them in flat files. Heroku is cited as an example for setting environment variables via command line.

Episode Info

  • Podcast: Developer Tea
  • Author: Jonathan Cutrell
  • Category: Technology Business Careers Society & Culture
  • Published: 2015-08-19T07:00:00Z
  • Duration: 00:13:29

References


Podcast Info


Transcript

[00:00:00] Hey, everyone, and welcome to developer T. My name is Jonathan Cottrell. And today we’re going to continue our discussion on the 12 factor app. Number two is dependencies. And number three is config. Number two is referring to explicitly declaring and isolating the dependencies of your application. And number three is referring to storing the configuration variables of your application’s deployment in the environment.

[00:00:30] Rather than in the actual source code. So we’re going to dive right into number two, which is dependencies. But before we do that, I want to go ahead and make the disclaimer that 12 factor app is something that came out of the people at Heroku. Now, Heroku is not officially sponsoring this episode or any episodes of developer T currently. So we are not, we’re not trying to, you know, push Heroku as a platform.

[00:00:58] In fact, the 12 factor application can be actually implemented on any given platform. Heroku just happens to support this idea. And there are some good ideas in the 12 factor app in this kind of methodology in each and every one of these 12 factors.

[00:01:19] Number two is dependencies. And I want to jump straight in and go ahead and get started. Explicitly declare and isolate dependencies.

[00:01:28] This is incredibly important, because it keeps you from bringing in dependencies into your source code. And it also prevents you from trying to monkey patch or overwrite those dependencies.

[00:01:41] This is a very useful concept that has been used over and over successfully in many, many applications. I can’t overstate this gem files and package.json, bower.json, whatever.

[00:01:58] your given manifest file is, those files are incredibly important and you should be doing

[00:02:05] this, isolating your dependencies. And what does this exactly mean for people who are

[00:02:10] relatively unfamiliar? Well, basically any given code base, like we talked about in the last

[00:02:16] episode of Developer Tea, any given code base usually relies on something third party. There

[00:02:22] are very few code bases that are actually built from the ground up with no external dependencies.

[00:02:29] This is especially true if you’re working on backend applications, but it’s also true more

[00:02:34] and more for frontend applications. This is exactly why things like Bower came along. Of

[00:02:40] course, Node is taking care of this with the NPM, just the built-in package manager for the most

[00:02:47] part now. But we also have things like Gulp and Grunt and all of the packages,

[00:02:52] that are necessary to use from NPM for frontend. And we’re specifically talking about web

[00:03:01] development at the moment, but typically there are going to be package managers throughout pretty

[00:03:07] much every language. It doesn’t matter if it’s web development oriented or if it’s system oriented.

[00:03:15] And typically each and every one of those package managers has a way of creating what’s called a

[00:03:21] manifest file. And that’s what we’re going to be talking about today. So let’s get started.

[00:03:22] What a manifest file does is it allows you to determine what things your app needs to run.

[00:03:31] For example, if you are creating a Rails application and you need to allow users to sign

[00:03:37] in, but you don’t want to hand roll all of the things that are necessary for a user to sign in,

[00:03:43] you can add the devise gem to your gem file and simply run bundle install after you’ve added it

[00:03:51] to your gem file. And that’s it. So let’s get started.

[00:03:52] Even Rails itself is added to the gem file because you need to have Rails in order to

[00:03:59] create a Rails application. If you’re using PHP, you may want to check out something called

[00:04:05] Composer, which is a PHP package manager. So taking a bit of a step back, the basic idea is

[00:04:13] that if you have third party code, if there are libraries or perhaps frameworks that you depend on

[00:04:20] for your application to run, you can add them to your gem file. And that’s it. So let’s get started.

[00:04:22] If you have third party code, then that code should be managed through something called a

[00:04:27] manifest file. And when you are starting your application on a new machine, when you actually

[00:04:32] deploy your application to a new endpoint, then you ensure that that endpoint actually has run

[00:04:41] that manifest file. Perhaps the most important benefit of doing it this way is that you can take

[00:04:47] your code to any machine and run that manifest file.

[00:04:52] And be sure that your code will work if that manifest file has run properly. In other words,

[00:05:00] if you declare all of the things that your application relies on, and then you install all

[00:05:06] of the things that your application relies on, then it is a very high likelihood that the system

[00:05:13] that you are running your application on is ready to run your application properly. An added benefit

[00:05:20] to this is that you aren’t going to be committing a large amount of code that you aren’t even

[00:05:26] changing. Specifically, you won’t be adding all of the third party code to your repository, which

[00:05:33] would make your repository unnecessarily large. Instead, you allow all of that code to live on the

[00:05:40] remote hosting servers that that code base is actually relying on to distribute whatever their

[00:05:47] production versions of their code base are. So if you have third party code, you can add all of that

[00:05:50] code to your repository and then you can run your application and then you can run your application

[00:05:50] on the remote hosting servers that that code base are. And your manifest file simply references those

[00:05:54] endpoints. This makes the overall size of your code base much smaller, which makes it much easier

[00:06:01] to share with your teammates. And it allows you to update those external dependencies much easier.

[00:06:08] You simply change the version number in whatever that manifest file is. A great example of this

[00:06:15] is the package.json file that node applications use.

[00:06:19] You can simply use the semantic versioning number, change the version of the third party tool, and run

[00:06:28] the install for that manifest file once again. And you’ll have the newest version of that tool

[00:06:35] available to you. Of course, to execute this, you’ll want to take a look at the git ignore

[00:06:41] documentation. This will allow you to ignore the folders where that third party code is being

[00:06:47] installed. If it is being installed, you’ll want to take a look at the git ignore documentation.

[00:06:49] This is particularly relevant for front end developers and those of you who are using node

[00:06:57] because wherever your package.json file actually is living is where your node modules will be

[00:07:04] brought in. So the package.json file and the node modules folder are going to be in the same

[00:07:10] directory. You’re going to want to make sure that you ignore the node underscore modules folder in

[00:07:16] whatever your version control system actually is. So you’re going to want to make sure that you

[00:07:19] actually is. I’m assuming you will be using git. And so you’ll want to check out the git ignore

[00:07:25] documentation. We’ll include that in the show notes as well. I’m going to take a quick sponsor break

[00:07:30] and then I’m going to come back and talk about number three, the third factor in the 12 factor

[00:07:34] app, which is the configuration, storing your configuration in your environment. We’ll be right

[00:07:40] back. Thanks so much to today’s sponsor, Harvest. Do you know where all your time is going? Do you

[00:07:48] know how much time you’re going to spend on your project? Do you know how much time you’re going to

[00:07:49] spend on each feature or tweak or bug fix for every client that you work for? You probably don’t if

[00:07:56] you aren’t tracking your time. Harvest is a tool that helps you track your time. It’s built for

[00:08:01] developers. It takes the pain out of time tracking for you because with their official Chrome browser

[00:08:07] extension, you can start a timer directly from the issues that you have already in Trello or GitHub

[00:08:14] or Jira. Now, not only will you understand how much time you’re spending on client work, but you’ll

[00:08:19] be able to turn your billable hours into an invoice from Harvest in minutes. Harvest integrates with

[00:08:25] PayPal and Stripe to make it easy to get paid. They also have iOS applications so you can take

[00:08:30] your timers on the go. So you can create a free 30-day trial at getharvest.com. Now, after your

[00:08:38] trial, you can also use the developer T code, T-Time, that’s T-E-A-T-I-M-E, to save 50% off your

[00:08:46] first month. Of course, the link and the code will be in the show notes.

[00:08:49] Thanks so much again to Harvest, getharvest.com.

[00:08:55] Thank you so much for listening to Developer Tea today. Before we jump into number three,

[00:09:00] the configuration being stored in the environment, I wanted to ask you if you will take just a few

[00:09:06] minutes to leave a review in iTunes. This is an incredibly important part of the show’s survival.

[00:09:14] We need people to know about the show and iTunes algorithms, you guys are all smart

[00:09:19] enough to know this. iTunes has a lot of algorithms that determine how shows are displayed to people

[00:09:26] who are looking for them. And one of the most important things for the show to be able to grow

[00:09:31] and for the show to be able to continue on is if you leave a review. The reviews and the ratings

[00:09:37] are incredibly important to that algorithm. So if you don’t mind, please take just a few minutes.

[00:09:44] The link will be in the show notes. You can go directly to leave a review for

[00:09:49] Developer Tea.

[00:09:49] That would be such a big help. So let’s jump into number three, storing the config in the

[00:09:57] environment. Now the basic test for this is you should be able to push your code to an open source

[00:10:06] environment and not worry about any of your application specific credentials being shared.

[00:10:14] So API keys, passwords, any kind of personal information,

[00:10:19] that you have stored in your source code, that should be moved out of your source code

[00:10:24] and into the environment. And the reason for that is because there should be an infinite number

[00:10:30] of endpoints that your application is actually launched on. This means that your development

[00:10:36] environment, your testing environment, your staging environment, your live environment,

[00:10:42] and someone else’s environment, all of them could have the same exact code base,

[00:10:49] and read environment variables. In other words, variables that are set specifically as files or as session

[00:10:58] variables on the environment, the execution environment on the server that you’re using.

[00:11:04] That is where the information needs to be held. It’s the most secure in that location and is much

[00:11:10] less likely to be accidentally shared by sharing your code base, by publishing it on something like

[00:11:17] GitHub. It’s also much less likely to be shared on a server. So if you’re using a server, you’re

[00:11:19] much less likely that someone would be able to read the environment than to be able to read a given

[00:11:26] file on your server. So perform that test. Perform the test of looking to find any kind of sensitive

[00:11:34] information or personally identifiable information in your code. But not only sensitive information,

[00:11:40] but code that would disallow you from immediately launching your application on another machine

[00:11:48] with needed information. So if you’re using a server, you’re not going to be able to find any

[00:11:49] configuration variables. That configuration should not be in a flat file. It should be at the very

[00:11:57] least, it should be in the flat file dot env if you’re using something to read that file. But even

[00:12:04] more secure would be if it was in the environment variables of whatever the execution environment is

[00:12:11] that you’re using. For example, we’ll refer to Heroku. Heroku allows you to set these specifically

[00:12:17] using their command line. So if you’re using a server, you’re not going to be able to find any

[00:12:19] interface tool. So always keep your code in that safest state where you can always share it and

[00:12:26] nobody will be able to see your personally identifiable information, your API keys, your

[00:12:33] passwords, even email addresses. These are the kinds of things that you want to store in your

[00:12:38] configuration. And that configuration should not be in the code base. It should be specifically

[00:12:44] stored in the environment. Thanks again for listening to today’s episode of

[00:12:49] Developer Tea. And thank you to Harvest. If you are like me and you have a difficult time tracking

[00:12:56] your time, Harvest makes that just a little bit easier. You can click a little timer from your

[00:13:01] Trello board or from a GitHub issue. Harvest knows how to track that issue and gives you a detailed

[00:13:08] report. It integrates with all your payment systems. Go check it out, getharvest.com and

[00:13:13] make sure you use the coupon teatime for 50% off your first month. Thanks again to Harvest.

[00:13:19] And thank you for listening to today’s episode. And until next time, enjoy your tea.