News for hackers. Stuff that matters.
Re:The Twelve-Factor App by vilunov on Thursday October 12, 2023 @10:59AM (#37858141)
I feel like each of this points can be reasonably disputed.

1. One app - one repo. There is nothing fundamentally wrong with multiple apps (as in separate pods/containers/processes) being developed in a single repo, as long as they are tightly coupled functionally, share the release cycle, but still need to be deployed separately to get advantages of separate processes and independent scaling. The first example that comes to mind is separation of public api and worker processes, e.g. ruby's sidekiq, python's celery or a generic kafka consumer.

2. > A twelve-factor app never relies on implicit existence of system-wide packages.

This is incredibly hard to achieve in practice if you're not running something nix, and even then there are leaks of dependencies on kernel syscall APIs. Every Rust app implicitly depends on a glibc (except musl ones), which is present in major Linux distros except slim ones such as Alpine. In fact, the whole Docker crutch IMO is needed specifically to alleviate this problem.

3. > The twelve-factor app stores config in environment variables

It seems to me much more brittle, as it forces you to store secrets in envs, which could be less secure, and to abandon structured file configs, which may enjoy type safety, IDE autocomplete and automatic parsing. With envs you are forced to implement parses for non-trivial and non-string config vars yourself. In fact, envs are often committed into repos as well in form of dot-env files, so the point about commit-safety is moot as well.

Re:The Twelve-Factor App by samus on Thursday October 12, 2023 @11:36AM (#37858683)
I agree with your view of the first rule and would gladly store multiple related apps in one repo. No rationale for why one repo should only containing one app is given, therefore that rule can be disregarded.

Dynamic or managed languages can often ignore most of the hassle with system packages.

Re:The Twelve-Factor App by twic on Thursday October 12, 2023 @11:03AM (#37858208)
> This is incredibly hard to achieve in practice if you're not running something nix, and even then there are leaks of dependencies on kernel syscall APIs.

You're misinterpreting that guideline. The text says (my emphasis):

> Most programming languages offer a packaging system for distributing support libraries, such as CPAN for Perl or Rubygems for Ruby. Libraries installed through a packaging system can be installed system-wide (known as “site packages”)

It's not saying not to depend on the operating system (of which glibc is part), it's saying not to require particular language package manager packages to be installed on the machine.

Agreed that the other ones you mention are silly, though. Especially the one about environment variables - that isn't actually reasoned advice, it was just the authors writing down what was most common in Ruby development at the time, on the assumption that that must be the best thing to do.

Re:The Twelve-Factor App by aniforprez on Thursday October 12, 2023 @11:16AM (#37858388)
In my experience, sourcing config from env variables seems like the best thing to do because you can completely ignore where the app is running in favor of injecting whatever you want in any environment of your choosing and your app no longer needs to care about that. The implication is that business logic must not include the content of your config or where it is sourced from. It must simply use the values in the config. This way my apps could give less of a fart if I run it as a container in kube, in nomad, in local on localhost, in a devcontainer, in a directory with vars loaded using direnv, in vercel/netlify and so on. This also allows incredible flexibility in how that config is sourced as long as you simply dump them into the env vars. Want to load secrets from a .env file on local? Sure. Want to load secrets from Vault on production? Run a simple script to load vault secrets onto the env and run your app.
Re:The Twelve-Factor App by dalyons on Thursday October 12, 2023 @12:28PM (#37859398)
yeah this is the actual point - it makes the code/app totally portable & decoupled from config. I find it significantly better than having to have the app code choose different config based on interrogating facts about its runtime (eg am i in prod? use this value. am i in test? use this)
Re:The Twelve-Factor App by twic on Thursday October 12, 2023 @05:54PM (#37863684)
Everything you both wrote is spot on - but there's nothing about it which means you have to use environment variables! All of those mechanisms could be used with any other means of delivering the config at the point of process invocation - a config file, command line arguments, YAML to standard input, whatever.

Personally, i would pick a config file over environment variables any day: easier to manually inspect and tweak, easier to give structure to, doesn't get implicitly passed down to subprocesses, can be secured with familiar file permissions, etc.

Re:The Twelve-Factor App by stackskipton on Thursday October 12, 2023 @09:11PM (#37865301)
Problem with config files is you are forced to process it properly in pipeline so it can be delivered during deploy AND depending on your runtime environment, you might have to redeploy to change things.

Environment variables exist on just about EVERY runtime, changed without requiring a pipeline run.

However, subprocess is interesting but I've never run into subprocess that is not sharing a config. Where I worked, if you have subprocess that can't see those configs, you create a new service.

Re:The Twelve-Factor App by twic on Friday October 13, 2023 @07:00AM (#37869201)
I'm not sure what you're saying about pipelines. Ultimately, every app process is started by some manager. It's just as easy for that manager to create a config file as it is to set environment variables.

If your point is that existing managers support setting environment variables but not creating config files, then sure. But that isn't a fundamental truth, it's just working with the tools you have.

Re:The Twelve-Factor App by aniforprez on Friday October 13, 2023 @10:01AM (#37870738)
Say you have a GitHub Action that pushes a container with your app and deploys to a Kubernetes cluster. Where is your config file going in this step? How do you inject that YAML/HCL/JSON file into the app to configure your app?

It just seems far easier to have your kube config inject the env variables from your kube file and that way you don't have to worry during deployment how to add that file and you don't check it into the source. This applies to basically any way you deploy your app, especially containerised ones. Unless you're running your app in an EC2 machine where you can go in and easily edit the file (not that you can't do it in a container), it just seems like extra steps. I've found the happy medium to be sourcing default configs from a file that can all be overridden through env variables

Re:The Twelve-Factor App by twic on Friday October 13, 2023 @10:25AM (#37870987)
Makes sense. But this is exactly what i was saying: the tooling you're using makes it easy to set environment variables, and doesn't make it easy to add config files, so in this case, environment variables are easier to use than config files.

But there's no fundamental reason for that to be the case. You could imagine a very nearby parallel universe where Kubernetes config files don't let you set environment variables, but do let you inject files. In this universe, you can see other deployment approaches that make config files easier (Puppet and suchlike). And if you're building something from scratch, you can make the choice.

Re:The Twelve-Factor App by aniforprez on Friday October 13, 2023 @11:05AM (#37871456)
Well... yeah but in the universe we live in, env variables are the most convenient, interoperable way of configuring apps and work on almost every platform. I guess I could work on a way to sit and dump config files into my apps but what's the point when env vars work well and are convenient to use right now?
Re:The Twelve-Factor App by jjice on Thursday October 12, 2023 @11:29AM (#37858591)
I heavily agree. I used to work on a LAMP stack where the deployment was just dumping the code into an EC2 instance. All is fine until there's a weird system dependency error that isn't documented because the AMI being used has just been hand built over the last three years. Have fun tracking down that specific PHP system dependency when AL2 goes EOL. I don't want to write code that doesn't have _documented_ dependencies on system packages. Even just a Dockerfile serves as solid documentation on what we're using.
Re:The Twelve-Factor App by vilunov on Thursday October 12, 2023 @11:11AM (#37858325)
Well, glibc could be considered part of the operating system, although this too is arguably not correct, because some technologies go out of the way to not depend on anything present in the system and be completely self-contained, e.g. fully statically linked Go binary with no Cgo usage.

Nevertheless, glibc is not the only system dependency which is often used by apps, another such example is JVM of a specific version, which is not tracked by any of the popular JVM build tools and package managers; and OpenSSL, which is too installed by the system package manager.

Dockerfiles exists to fix this by defining all the necessary installation steps as a sequence of instructions, but this is far from a proper package manager.

Re:The Twelve-Factor App by twic on Thursday October 12, 2023 @06:02PM (#37863756)
The libc is absolutely part of the operating system. Some people and tools go out of their way to avoid using it, but they are completely mistaken to do so. Go in particular has wasted a huge amount of effort on this absolutely pointless exercise.

And not just libc - on a typical unix, there are a small number of other libraries which constitute part of the operating system, like libm, libdl, and libpthread. They are part of the means by which the operating system delivers the POSIX environment.

You're right that the JVM is a dependency, and that there is very poor versioning support for it in production. Everywhere i've worked, we've come up with ad-hoc solutions for it, and none of them have been very good.

Re:The Twelve-Factor App by damianh on Thursday October 12, 2023 @11:04AM (#37858213)
"One app - one repo"

Where did you see that being expressed?

Re:The Twelve-Factor App by vilunov on Thursday October 12, 2023 @11:04AM (#37858218)
Re:The Twelve-Factor App by ulizzle on Thursday October 12, 2023 @03:40PM (#37862119)
It says there that a codebase can contain multiple repos. They don’t mean a monorepo when they say codebase
Re:The Twelve-Factor App by vilunov on Thursday October 12, 2023 @04:13PM (#37862594)
> A codebase is any single repo (in a centralized revision control system like Subversion), or any set of repos who share a root commit (in a decentralized revision control system like Git).

They do mean that a repo = a codebase. A remark about "set of repos" is just a technicality of distributed VCSs, meaning that each copy cloned from a single source (or from other copies) is a single repo.

Re:The Twelve-Factor App by brodouevencode on Thursday October 12, 2023 @11:47AM (#37858823)
> 1. One app - one repo.

There is a U-shaped utility to monorepos. Most projects fall in the middle somewhere, largely ones managed by independent engineering teams that have no centralized platform/devops/whatever-we-are-calling-it-these-days team.

Re:The Twelve-Factor App by kagakuninja on Thursday October 12, 2023 @01:59PM (#37860617)
They also say every server should be a separate process, which is debatable. When using languages that lack real threads (Ruby, Python, etc) you have no choice.
Re:The Twelve-Factor App by talent_deprived on Thursday October 12, 2023 @03:27PM (#37861911)
> There is nothing fundamentally wrong with multiple apps (as in separate pods/containers/processes) being developed in a single repo, as long as they are tightly coupled functionally, share the release cycle, but still need to be deployed separately to get advantages of separate processes and independent scaling.

We disagree on fundamentals then and I think more of the world agrees with me and with the 12 factors.

Re:The Twelve-Factor App by Aeolun on Thursday October 12, 2023 @09:04PM (#37865257)
Point 1 was written when it was standard practice to stick all of your organisations code in a single repository. The concept of splitting things (history, diffs, etc.) up per app was foreign to a lot of people.
Re:The Twelve-Factor App by lmm on Thursday October 12, 2023 @10:53PM (#37866020)
> There is nothing fundamentally wrong with multiple apps (as in separate pods/containers/processes) being developed in a single repo, as long as they are tightly coupled functionally, share the release cycle, but still need to be deployed separately to get advantages of separate processes and independent scaling.

If they're deployed separately, they don't share the release cycle. Sooner or later you'll end up with mismatched versions of them running (e.g. perhaps one piece fails to deploy). So you need to be prepared for that, so you want them in separate repos so you can easily test with different versions.

> This is incredibly hard to achieve in practice if you're not running something nix, and even then there are leaks of dependencies on kernel syscall APIs. Every Rust app implicitly depends on a glibc (except musl ones), which is present in major Linux distros except slim ones such as Alpine.

Most higher-level languages avoid depending on a specific glibc; as long as you have a working runtime for that language then your app will work with it. And sure in some cases you resort to docker or something. It can indeed be hard but that doesn't mean it's not worth doing.

Re:The Twelve-Factor App by vilunov on Friday October 13, 2023 @06:18AM (#37868955)
> If they're deployed separately, they don't share the release cycle. Sooner or later you'll end up with mismatched versions of them running (e.g. perhaps one piece fails to deploy). So you need to be prepared for that, so you want them in separate repos so you can easily test with different versions.

In that case I'll just rollback the first one. I see no reason to logically decouple two processes into two services when the separation is technically driven. They share the queues, the database, the domain, further division will just make things more complex with no obvious advantage.

Re:The Twelve-Factor App by lmm on Sunday October 15, 2023 @07:51AM (#37888985)
> In that case I'll just rollback the first one

At that point you're not deploying separately any more. They explicitly say you can have multiple processes and process types as part of the same app (see #8). The point is that "repo of its own" should align with "atomic unit of release/deployment".