I don't think I agree with this. Docker is an amazing tool, I've used it for everything I've done in the last 7 years, but this is not how I'd approach it.
1. I think the idea of local-equal-to-prod is noble, and getting them as close as possible should be the goal, but is not possible. In the example, they're using a dockerized postgres, prod is probably a managed DB service. They're using docker compose, prod is likely ECS/K8S/DO/some other service that uses the image (with more complicated service definitions). Local is probably some VM linux kernel, prod is some other kernel. Your local dev is using mounted code, prod is probably baked in code. Maybe local is ARM64, and prod is AMD64.
I say this not because I want to take away from the idea of matching dev and prod as much as possible, but to highlight they're inherently going to be very different. So deploying your code with linters, or in debug mode, and getting slower container start times at best, worse production performance at worse - just to pretend envs which are wildly different aren't different seems silly. Moreover if you test in CI, you're much more likely to get to a prod-like infra than a laptop.
2. Cost will also prohibit this. Do you have your APM service running on every dev node, are you paying for that for all the developer machines for no benefit so things are the same. If you're integrating with salesforce, do you pay for a sandbox for every dev so things are the same. Again, keeping things as similar as possible should be a critical goal, but their are cost realities that again make that impossible to be perfect.
3. In my experience if you actually want to achieve this, you need a remote dev setup. Have your code deployed in K8S / ECS / whatever with remote dev tooling in place. That way your DNS discovery is the same, kernels are the same, etc. Sometimes this is worth it, sometimes it isn't.
I don't want to be negative, but if one of my engineers came to me saying they wanted to deploy images built from their machine, with all the dev niceties enabled, to go to prod, rather than proper CI/CD of prod optimized images, I'd have a hard time being sold on that.
After going through a bunch of evolutions using Docker as co-founder/engineer #1 at a startup to > 100 engineers, hard agree on this take.
One other reason to not overbloat your images (besides physical storage cost and perf) is security considerations. If you find yourself in a place where you need to meet enterprise security standards, keeping more dependencies in your image and linked to your app code widens your risk vector for vulnerabilities.
> I don't want to be negative, but if one of my engineers came to me saying they wanted to deploy images built from their machine, with all the dev niceties enabled, to go to prod, rather than proper CI/CD of prod optimized images, I'd have a hard time being sold on that.
That's why there is the meme. Docker doesn't always solve this, or even often on its own. You can't just "build image to docker" and expect things to go okay and pretend you can be agnostic about its prod environment (you kind of can, but usually requires an ops team supporting whatever assumptions your image made).
It's been addressed in other comments but you have:
- differences in architectures, CPU, memory
- if the docker image has a volume attached, unless local perfectly represents prod, you're going to have issues
- networking and firewall rules can be drastically different than a production environment and the assumptions made there
- differences in RBAC/IAM/etc. between local and prod
could go on and on.
In reality, this is a nice idea, in practicality, it almost never works 1:1. The common refrain is "well just make the local/dev/sandbox exactly match prod" and my point is this is often unrealistic to the point it cannot/won't happen. If you can do it, good for you, I just personally have never seen this work as simply the author describes it in a system of any kind of complexity.
Whereas this was true (for a long time), making an argument that because remote and local are so “inherently” different that one shouldn’t strive for this parity is silly, especially considering the differences outlined are pretty easily solvable by k8s to local parity.
Whereas it’s still clunky to dev with tools like skaffold and minikube, I strongly believe they are the future. We have essentially eliminated deployment bugs using skaffold for local dev and deployment. Everything is caught locally, on a dev machine or in CI, as it should be.
"widely different" seems like a stretch e.g. ECS is pretty directly translatable to docker compose, and if you do cross-platform builds with buildx then I don't see why doing the building locally or on a cloud service matters much.
1. I think the idea of local-equal-to-prod is noble, and getting them as close as possible should be the goal, but is not possible. In the example, they're using a dockerized postgres, prod is probably a managed DB service. They're using docker compose, prod is likely ECS/K8S/DO/some other service that uses the image (with more complicated service definitions). Local is probably some VM linux kernel, prod is some other kernel. Your local dev is using mounted code, prod is probably baked in code. Maybe local is ARM64, and prod is AMD64.
I say this not because I want to take away from the idea of matching dev and prod as much as possible, but to highlight they're inherently going to be very different. So deploying your code with linters, or in debug mode, and getting slower container start times at best, worse production performance at worse - just to pretend envs which are wildly different aren't different seems silly. Moreover if you test in CI, you're much more likely to get to a prod-like infra than a laptop.
2. Cost will also prohibit this. Do you have your APM service running on every dev node, are you paying for that for all the developer machines for no benefit so things are the same. If you're integrating with salesforce, do you pay for a sandbox for every dev so things are the same. Again, keeping things as similar as possible should be a critical goal, but their are cost realities that again make that impossible to be perfect.
3. In my experience if you actually want to achieve this, you need a remote dev setup. Have your code deployed in K8S / ECS / whatever with remote dev tooling in place. That way your DNS discovery is the same, kernels are the same, etc. Sometimes this is worth it, sometimes it isn't.
I don't want to be negative, but if one of my engineers came to me saying they wanted to deploy images built from their machine, with all the dev niceties enabled, to go to prod, rather than proper CI/CD of prod optimized images, I'd have a hard time being sold on that.