Hacker News new | past | comments | ask | show | jobs | submit login

Edit: I rewrote this as a blog post of my own, where I expand upon some of the suggestions, might be more readable: https://blog.kronis.dev/articles/how-boring-or-novel-should-...

Overall, I'm tempted to agree, whilst keeping in mind that you sometimes definitely need a little bit of novelty, which the author brings up at the end of the article as well. Here's a few bits of my personal experience, where some novelty helped greatly in these past few years.

Personally, I'd say that something like 12 Factor apps are a good and supposedly new approach (using mechanisms and approaches that have been around for a while) to let you look at software written in different languages pretty much the same from the outside. For example, you use environment variables for configuration, write lots to STDOUT, don't cripple your own horizontal scalability by always reaching for local storage (e.g. when S3 might be better suited) or local application memory (e.g. when Redis might be a good idea). It's nice to have those sorts of suggestions in one place and all of the sudden you escape XML or Tomcat setup hell, and can look at Python apps and Java apps similarly from the outside: https://12factor.net/

Similarly, adopting containers has been a good solution, both because it allows achieving what people historically didn't bother with when having the opportunity of using systemd, but also because all of the sudden your applications are like phone apps - that can be launched in a consistent format on any server that you need. And you get health checks, resource limits, automatic restarts, bind mounts, port mapping and internal DNS, all of which you will never build in environments where the DevOps knowledge or resources (time) are not there.

Note: Kubernetes might be too complex for some setups, as HN loves to point you, something like Nomad or even Docker Swarm also still exists and works: https://docs.docker.com/engine/swarm/ (just linking this in particular, because it's just a small step up from Docker Compose, the pinnacle of simplicity)

Speaking of which, infrastructure as code is great! Using something like Ansible is definitely a novel thing to do at first, but cutting off my team's write access to the servers and making them use GitOps with code review for the configuration changes has been a solid idea. No more wondering why some random configuration exists, or why it was changed N years ago, now you can just look at Git. No more fat fingering bad changes, and even if you did something like there's also code review. No more risks like Knight Capital of partial deploys and if something like that were to happen, you'd get a CI notification about what's wrong. Just describe what you need on the server and let those hundreds of actions execute every morning (or after every commit/merge) automatically, ensuring a mostly consistent state - and way more lazily than learning Nix/Guix: https://www.ansible.com/

Furthermore, adopting the "ingress pattern" where all of your apps are in some internal overlay network, but talk to the outside world through instances of Apache/Nginx/Caddy/Traefik is brilliant! No more wondering about how to set up SSL certificates in each of the different application runtimes or even framework versions. No more worrying about setting up rate limits for each application individually, no more worrying about context paths for how things are deployed - you can configure all of that in your web server, even if you don't use a Kubernetes Ingress controller.

Oh, and forget something like jQuery from the old days, especially when you'd integrate with numerous low quality plugins that wouldn't even work that well half of the time. Just use something like Vue with PrimeVue/PrimeFlex or any other premade component library, with Pinia for state management. You avoid the trouble of using React with Redux (though React Query is nice) or the complexity of Angular, while still getting the benefits of writing small, mostly self-contained application components. No more thousand line JavaScript controllers, no more messing around with global state, or god forbid using something like AngularJS. And with JSX, it actually ends up feeling more convenient to write front end code, in addition to Vue getting hooks right, better than React IMO: https://vuejs.org/

But the actual applications? Most of the time, they should be more boring. Using Java? Just go for Spring Boot or Dropwizard; something like Quarkus or Vert.X are nice, but not quite ready yet. Using Node? Look at Express.js, it does everything you need. Python? Django or Flask. PHP? Laravel or Symfony. Ruby? Rails. Every time I've seen someone go for a non-standard solution or actually writing their own framework, it's been an utter dumpsterfire. Good luck debugging some uncommented code that has not enough tests when there's a production outage and the few code comments that you might stumble upon are in Lithuanian or something.

Databases? As a rule of thumb, go for PostgreSQL or MariaDB/MySQL. If you need data storage, use something S3 compatible. If you need key-value storage, use Redis. If you need document storage, either store JSON in your RDBMS or cautiously go for MongoDB. In each of these spaces, there are one or two established options and using anything outside of those should only be done when you have person-years to throw at every problem, e.g. the expertise and the $$$ to innovate.

In most circumstances, just use what has worked for other people well, as long as their circumstances are similar to yours. (a bit long winded, but just felt like writing a bit today)




I've encountered a code written in the 12factor style of using environment variables for configuration, and in that particular case there was no validation nor documentation of the configuration options. Is this typical?

For onboarding new members, I would have thought it preferable to have a JSON configuration, where both documentation and validation of configuration options are provided by a JSON Schema file.


> I've encountered a code written in the 12factor style of using environment variables for configuration, and in that particular case there was no validation nor documentation of the configuration options. Is this typical?

This just feels like bad development and isn't unlike being given a random .properties/.ini file with no explanations of what the values mean. Sounds like someone didn't do their job, or the processes to encourage (require) them to do so weren't in place.

> For onboarding new members, I would have thought it preferable to have a JSON configuration, where both documentation and validation of configuration options are provided by a JSON Schema file.

You know, this can work, but then you need your applications to be able to read that file and feeding it in through your container management solution (which many use for a variety of reasons) wouldn't be as easy. Even without containers, you'd still need to look out so you don't end up with 20 JSON files all of which might need to be changed for a new environment.

Honestly, something like JSON5 https://json5.org/ was pretty cool because of added comments, but otherwise JSON is a bit cumbersome to use. That said, some web servers like Caddy have gone for accepting JSON configuration as well, which lends itself nicely to automation, so it's still a valid approach: https://caddyserver.com/docs/json/


> I've encountered a code written in the 12factor style of using environment variables for configuration, and in that particular case there was no validation nor documentation of the configuration options. Is this typical?

I think it comes down to how your team values the code they write.

You can have a .env.example file commit to version control which explains every option in as much or as little detail as you'd like. For my own personal projects, I tend to document this file like this https://github.com/nickjj/docker-flask-example/blob/main/.en....


Yeah I think this is why I liked "novelty budget" as a term. To me it implies a limit, but it also implies something which you should spend. Doing something a little bit different can be immensely valuable as you've highlighted. Also everything was new at one time.


> Also everything was new at one time.

Hah, this is a good point, but in my eyes lots of things that were new... never really grew up and were just deprecated and died.

For example, if someone based their setup on IronFunctions, they might have run into a bit of a painful situation, seeing as the project has been largely abandoned: https://github.com/iron-io/functions

Same for a database solution like Clusterpoint, the support for which just ended and you were left to migrate away to something else: https://github.com/clusterpoint

Ergo, I'd say that it's good for others to suffer the consequences (in a manner of speaking) of being trend setters and making wild bets on new and risky products and to just reap the benefits of their efforts later yourself, when things are safer. If a project has survived for a reasonably long time, it's a good indicator that it'll probably keep surviving in the future as well (there was a name for this, sadly can't recall what that was).


> don't cripple your own horizontal scalability by always reaching for local storage (e.g. when S3 might be better suited) or local application memory (e.g. when Redis might be a good idea).

Is reaching for local storage\memory crippling or not?

Where does the 12factor talk about it?


I'd say that the closest 12 Factor concept is "Backing services": https://12factor.net/backing-services

Whenever there is something that might need to service more than one request, reach for attached external resources. You don't want to store business state (e.g. something like the current status of an auction or its bids) in application memory, unless you're okay with your app being a singleton application: one that can only ever have a single instance running concurrently, with all of the risks that it brings.

Similarly, if your application generates reports, generally it's good to put them somewhere like S3 and perhaps persist the metadata about this, instead of just spewing them in your local file system, because at a certain scale there are issues related to the filesystem approach (e.g. max number of files in a folder, inode limits), though admittedly something like ActiveStorage in Ruby at least makes an honest attempt at solving it for most folks.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: