ENGINEERING ★ 41 upvotes 2021

Ask HN: Do you run apps bare metal?

The Founder's Submission

Direct narrative and submission text authored by @sdevonoes on Hacker News:

So, I am working on a side project and the way I deploy my (golang) application is basically:

- build binary

- copy binary, config files and static assets to the production server

- do blue green deployment (with nginx) to get zero-downtime deployment

- profit

(This is automated of course! I use Ansible, and I can easily rollback if needed. I can also deploy the same app to multiple machines if needed).

On my local machine I use Docker to test the Go code, but I don't really see the benefit of deploying my Go app in a container. My colleage told me "it's easier to deploy Docker containers. You just pull the image and voila!". I don't see how my approach could be "more complicated". Also, isn't my approach better in terms of performance? If my golang app runs "bare metal" instead of via a container, then sure the performance should be better, right?

Retrospective Overview & Key Insights

Distilled analysis of the business dynamics, operational challenges, and strategic takeaways:

In this technical retrospective (2021), @sdevonoes shares practical architectural lessons learned from running, scaling, or migrating production software under lean constraints.

Core Principles for Independent Builders:
1
Defaulting to simpler architectures (such as monolithic frameworks, SQLite, or managed VPS) prevents early engineering bankruptcy.
2
Evaluating true compute and egress costs reveals that high cloud bills can often be slashed by 80%+ through judicious re-platforming.
3
Code you write at 2 AM as a solo engineer must be easy to debug six months later without complex microservice dependencies.
Community Debate Themes:

HN engineers debated the tradeoffs between cloud convenience and raw server economics, database indexing strategies, and resisting premature architectural complexity.

Community Discussions & Critical Reviews

High-signal perspectives, counter-arguments, and peer founder insights debated on Hacker News (73 total discussions):

WH @whalesalad Peer Contributor

It would help to clarify some words:

"Bare metal" means that your application is running on the same OS that is also running the raw hardware (metal), aka no virtualization. Containers are not (generally) the same as virtualization.

The analog to bare metal is virtualized, where the hardware your program is seeing is not necessarily the hardware that is running on the actual host machine.

A docker container could ostensibly be considered running on bare metal. A container is really just isolation but the parent OS/kernel is in command. Here is a graphic that illustrates the differences: https://www.sdxcentral.com/wp-content/uploads/2019/05/ContainersvsVMs_Image.jpg

What you are really asking is do you need an abstraction layer or orchestration tool to manage doing this.

The short answer is that no you do not need it at all. If you can DIY this and are happy with it, that is sufficient. For example, a current deployment process for one of my clients (EC2 environment) involves stopping a custom systemd service, pulling the new binary/deps and then starting the systemd service. Really simple with a small instant of downtime, but within this environment that is not a problem.

AN @andrewstuart2 Peer Contributor

Your performance should not noticeably differ (on linux) between docker and just running as an uncontainerized process on the host. There's almost no difference as far as the kernel is concerned; it just tags your process slightly differently (different kernel namespaces and cgroups, but these apply to every process).

Bare metal usually refers to running without hardware or software virtualization (kernels within kernels), and if that were the case (docker on linux does not virtualize) it would be meaningfully faster, but that's not the case here.

The primary benefits you get from Docker may not be immediately apparent, so go for whatever works. Eventually, you'll probably find that it's substantially easier to scale out appropriately and automatically with some sort of orchestration tech, which is nearly all built on containers these days. Don't sweat it til you need it but at the same time, it's easier to learn sooner than when you're knee deep in tech debt for a dozen services.

TW @twic Peer Contributor

Yes.

Our contract is that a unit of deployment is a .tar.gz file, and inside that there is an executable file bin/run which starts the app. We build apps in a few languages, but they all have a start script like that.

You can use static or dynamic linking, compiled or interpreted languages, anything you like, as long as the start script sets it up correctly. For Go apps the script can be trivial.

Tarballs must be self-contained - binaries, libraries, config files, static assets. We make an exception for interpreters, because those are huge and change slowly. Those are manually installed in /opt/something. I'd like it if we did something more disciplined and reproducible, but it's good enough for now.

We don't have many machines. Maybe 20? You can get a lot done with 20 full-size physical machines.

I don't see how something like Docker would help us here. It would just be the same, but less hackable.

GN @gnfargbl Peer Contributor

There's nothing really wrong with what you're doing. Apps were deployed like that for decades before docker came along.

To my mind the main benefit of containerization would be that the

binary, config files and static assets

would be bundled together inside the container, so there is less risk of you running a half-baked version where (e.g.) the binary gets updated but the other files don't. However since you're using Ansible to deploy, that risk already feels small. You could also consider using the embed feature in go1.16 to bundle all the assets inside the binary.

Arguably there might also some security benefit to running in a container, but I wouldn't want to try and make that argument without knowing a lot more about the specific details of your binary's behaviour.

AN @analognoise Peer Contributor

Yes, I frequently don't use any operating system and write bare metal C code, usually for Zynq (normally RFSoC or MPSoC class) FPGAs, although I also frequently use a Microblaze soft processor with it's entire memory in BRAM when doing initial system bring up (say for a new board).

Lots of people in here don't know what "Bare metal" means. There's no operating system - at all. Anything else is not bare metal.

To go further: Sometimes (if you're bringing up a new processor design) you don't even get cstdlib - you have to write it (or the processor's architecture won't even support C!). "Bare metal" means exactly that - it isn't the same as "no virtualization"... at all.

HISTORICAL ERA Pandemic Bubble (2020–2022)
COMMUNITY SCORE ★ 41 points
TOTAL DISCUSSIONS 73 comments
TOPICS & TECH STACK:
More Retrospectives by @sdevonoes