Launch Your App: Why We Don’t Use Docker (We Don’t Need It)
launchyourapp.meezeeworkouts.com
launchyourapp.meezeeworkouts.com
I think you're only seeing Docker as a packaging format and missing the distribution aspect. There's a lot of value in telling users "My app is accessible with a single `docker run` command", that doesn't involve them downloading a standalone binary manually, placing it in their PATH, etc., and also works across platforms and operating systems. Or worse, having to setup the Go toolchain and compile it themselves, no matter how easy it is for a developer (and ignoring what can go wrong with Go modules).
Of course, then you open yourself up to all sorts of support questions related to Docker, but I still think it's a missed opportunity to not use it to make your software as widely and most easily accessible as possible.
Tested RabbitMQ this weekend, and the getting started was soo easy.
As a mac user, I'm not sure I agree with this. Docker does technically work cross platform of course. But it's slow everywhere except for linux. I'd much rather have binary (or even better a `brew install`) than a docker image.
I'm not saying it should be the _only_ distribution option, and standalone binaries and other packages should be provided as well, but there's no reason for Docker to not be one of them.
Still not as fast as on Linux, but within 10% of running it natively for me.
What about server workloads where the storage is completely inside the container / on a different server?
The circumstances you're describing sound like it wouldn't be suffering this specific issue in the first place, so I'm not sure how much it'd help.
It would be much nicer if apple coexisted instead of apple-language, apple-frameworks, apple-laserlike-navel-focus. Do community interaction, not just over-the-wall to opensource.apple.com
a native apple docker would be great. Imagine:
FROM macos:10.13.2
RUN xcode-build ....They're perfectly willing to ruin the lives of countless devs / CI/CD devs, who have to support their crappy platforms, because you can't virtualize MacOS (only AWS can, and even then, it can only be rented in 24h increments at super high prices).
Apple controls the end users, their end users have money so devs just have to come crawling to be able to make and sell their apps.
Docker is a packaging format with a distribution platform and a common execution interface. I see offering it as an option to users only as a net positive. Not to mention that it opens the orchestration door making the application easy to integrate into CI pipelines and complex workflows.
Containers are peripheral to my work so I don’t understand but I’m curious.
This does mean that you end up with multiple copies of the same utilities and libraries on the system - although docker does have a mechanism to avoid duplication between different docker containers. It also means that if you take your docker container and move it over to a different system with a newer operating system (or a different distribution) all the parts of the operating system it cares about come with it.
The Linux kernel - the part that gets shared between containers - is mostly just responsible for process and memory management, networking and interacting with the computer hardware.
That's the greatest lie that Docker managed to convince people of.
Docker is not portable, its images are not portable. It runs on Linux and that's it. It doesn't even run on other *NIXen.
Docker on Mac runs inside a VM. Docker on Windows runs inside a VM. Technically Docker for Windows supports Windows containers. But they only run on... Windows.
Docker is as portable as any software I can get my hands on and that I can run inside a VM. So almost all the desktop software I know of.
Docker just managed to package its software in a nicer way so that many people don't even realize that there's a VM behind the scenes (most usually notice because Docker is slower/much slower on non-Linux platforms).
So you can publish for two platforms.
Java is still a good way to have bulletproof cross-platform experience, but JRE is sort of large. JDK 10 or 11, IIRC, allows to package your code, only the needed parts of stdlib, and the VM into a reasonably lean self-contained executable.
What matters is whether my app and the myriad of dependencies it relies on can be run easily and consistently.
> go build
> Testing is as easy as
> go test
> Deploying the app is as easy as:
> scp app user@host:
> ssh user@host “nohup ./app”
I suppose we'll see in 1-3 years whether the decision to skip any/all build and deploy tools in favor of staking a business on someone scp'ing to prod servers was a good idea. I have a very strong assumption, but who knows.
Plus the article never mentions "we'll never need to add more ci/cd", they're simply saying they don't need it right now.
The key for me is making sure you are taking the time to reassess those early life decisions so when the time comes you can course-adjust
$ cat deploy.sh
#!/bin/sh
scp app user@host;
ssh user@host "nohup ./app"
At some point you have to use something to get it to the production server. Why not scp?Because this way doesn't leave explicit audit/deployment logs.
Do you think using only scp will prevent you from deploying the wrong artifact? Or deploying to all-but-one production node? Or scping but forgetting to run the nohup?
Honestly setting up a github action to do this takes very little time, doesn't depend on containers, doesn't really add complexity to your stack. CircleCI exists and is equally easy. To suggest that your above-posted script is just as good is, to me, mostly just NIH + developer bikeshedding. YAGNI is great for being honest about the needs of an org and ignoring tools or frameworks that aren't appropriate, but there really are tools that exist that add consistency in ways that don't really increase complexity all that much.
Not focusing on docker from the start forces you to have a clean build and runtime software chain, and reduces the amount of magic required (ironically, going to containers was supposed to be the opposite, but many server-side packages are now docker-only because the build and/or runtime requirements are so messed up, e.g. discourse).
Sure you could convert later, but now you have to move your whole workflow over during a time you're in dire need of the new features instead of casually from the start. Now instead of your artifact history being consistent, its truncated at the point you switched over.
I guess I don't understand whats so complicated about docker?
Overlay filesystem performance across distros?
Attaching a debugger to a process?
Idk. Just some ideas off the top of my head. I don’t think it’s unimaginable to consider how docker is an increase in complexity and understanding.
You can just use --net=host if you don't like it.
> Overlay filesystem performance across distros?
I've used docker on several distros and never noticed an issue with this.
> Attaching a debugger to a process?
This is also not an issue if you don't use bridge networking.
I imagine one could install GDB in the container and connect to it remotely? Or from the container's shell?
IIRC, you just need to install gdb when you build your image and use `docker run -it bash` to run any shell commands in your container
Since the remote stuff is sometimes an incredible pain to set up and use, I usually install gdb and just use its CLI in the container. That's usually trivial in comparison, and it's a decent skill to learn regardless since so many debuggers use a similar CLI UX. It's extremely cross-platform and cross-language, so you can just jump on a new thing and be a wizard from day 1.
Without this, deployment starts being spread over various bash files with often poor documentation (they’re already mentioning such a script in their article). Then when it becomes too messy, time to write that Dockerfile I guess, except now it’s more complicated than if it had been done from the start.
Maybe the deployment is on "pet servers" and not on-demand, which means if you are a responsible admin and have a nftables config you need to analyze how docker will mess up your rules (or why it is not working).
Maybe you don’t want to lose time setting up an artifactory, and a docker registry with proper access controls.
Maybe you don’t want to have to focus on the ops side of things until you actually need it. Yes that may mean losing time later when you need it fast, but at the same time this can be done iteratively when things are ramping up.
From experience at a previous workplace, using docker as part of your local development process can be a huge PITA, and getting developers to adopt it without grumbling and complaining about it every day is also a hurdle. Given enough computers, you will get weird network errors, some borked modules due to an upgrade, some containers refusing to die, etc…
I am not saying it cannot be done, and in the general case docker mostly works without (too many) glitches, but it is always another layer that hinders your productive work.
(also, "docker" in production nowadays is mostly a shortcut for k8s, and that is a whole new amount of investment required)
It didn't help that Docker tied docker compose to swarm and then swarm kinda died. So I'm really scratching my head at the people recommending docker in this thread. I'm assuming they mean K8S but at the same time surely they can't be serious.
Today if you need something at the startup/mid range level you're probably looking at Dokku, Caprover, or maybe even nomad. This is still more complexity than scp, of course.
You get turn key environments with a ton of flexibility for what is honestly much less effort than even maintaining the setup documentation for installing the apps directly.
Using legitimate tools to handle building and deploying has nothing to do with Docker, but the author of this blog post has combined them.
For go apps, docker isn't really doing much over golang binaries. The bigger transition was more just moving us away from any unneeded dependence on system level apps. This happened at the same time we were dockerizing.
I think the ECS abstraction is better than the simple daemon scripts we were using and scp for deploys, but we made it work up to around 30k servers before we hit scale limits. We could have pretty easily taken it even further forward but ecs is simpler and better integrated with the rest of AWS and our build tools. It only matters for a few special teams.
The real issue with SCP at some point was the parallelism of deploys: opening 30k ssh connections single threaded or with bash starts bogging down at some point, and we were at the point of writing a massively parallel version when we switched to ECS for much of this (also around the time ECS became stable).
Who is running this scp? Where do they get the build? Do they have to know which hosts to scp to? Questions/problems like this are not solved at all, which generally need to be solved one way or another to scale any production system.
I would definitely not be okay with an engineer in my organization telling me their plan is to ignore CI/CD, especially in the present age where GitHub Actions is trivially easy to set up, and rather set up some custom procedure over SSH. Technical choices aside, it fails the "hit by a bus" test - if you disappear for some reason, or even just your laptop gets stolen, does the company grind to a halt?
As in, no one in the whole company knows how to scp a binary?
Boss: "Alice, can you release Super Mega Money Maker"
Alice: clicks deploy on a UI It'll be out in 5 minutes.
Boss: "Thanks!"
Without CI
Boss: "Bob is out sick, can you deploy Super Mega Money Maker?"
Alice: "Ok. hmm... I pulled the code and I'm trying to run the build but I'm getting an error. It wants a super-secret-token.pem file. Do you know where that is?"
Boss: "Let me call Bob" "Ok, he said it's a file on his laptop but he left his laptop in the office. He's on his way in."
I would guess you are more likely to be in the situation where only one developer really knows your complicated build tools and how exactly they are put together. That's your actual "hit by a bus" vulnerability.
GitHub Actions is not complicated.
On what planet does a non-technical person even know what a Docker container is?
I wrote it about it here if anyone interested https://logicai.io/blog/recommendation-systems-in-rust/.
If only there was a tool to:
- bundle, distribute and deploy applications
- ...and configuration files
- ...and systemd unit files
- ...even directories containing a Python virtualenv
- keep track of what is installed and in what version
- roll forward or roll back
I would call it Advanced Packaging Tool.
I watched it happen with virtualization. Everyone was so hyped about virtualization that everything was run in VMs. Later there was a counterrevolution of folks going "hey, we discovered that running things on bare metal servers is a thing you can do, and it's way faster and cheaper", a push that has mostly died out now that virtualization has hit near bare metal performance anyway and cloud hosting is the norm. But that counterrevolution happened because everyone embraced VMs and cloud services without dwelling on its actual use case, or in what cases it was an improvement over bare metal hosting. I watched similar happen with both the NoSQL and Serverless revolutions, and now we're watching it with containers.
So yes, this would be better setup as a deb package, or deployed as part of a cloudinit startup script or similar. But if you came in when everyone was just shoving docker down each other's throats, you don't know what stages there were before that, and which one is the most appropriate one for your use.
However, Docker is so simple to work with and so valuable in what it delivers that a headline like this reads to me a bit like "We don't need git". Sure, you might not need it. But it would probably be nice.
Same can be achieved with node/java/C#. There are 3rd party tools to achieve this for many languages, but at least dotnet has this option built-in: https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotne...
Things do become more complicated when your app is a single logical unit that depends on a number of resources / services. Maybe you want an nginx reverse proxy in front of it, a database engine behind it; maybe Go isn't the only language you're going to use. Maybe you want the ability to effortlessly run the exact same setup as your production environment somewhere else without having to run a bunch of Ansible playbooks on the target host, and without worrying about the Linux distribution on it. Docker and docker-compose can help with these use-cases and get you up and running quickly.
I'm not saying Docker is ever a _necessity_. But it can be a great convenience. In the end, use the simplest solution that fits your requirements, and make sure you can extend it later on if those requirements change.
I can understand not wanting to take the time to learn it because growing a business, but if you know how to write a bash script you'll probably pick it up in like a few hours, once. It's not like we're talking about k8s or something, which I can understand not wanting to immerse yourself in for weeks only to wonder why you didn't just pay for Heroku and hire an ops guy in a year to get off of it.
Honestly, i've never really got the point of fat jars. Fat jars come with all sorts of annoyances (what do you do with the manifests from each jar?). Unpacking a zip is not hard.
no hate from me. it's perfectly fine to run one's stuff without docker.
It doesn't address runtime configuration like remote hosts, passwords, etc. It doesn't even address the difference between provisioning and deploying a host.