Docker (and docker-compose) is super useful for local development environments. Sure, there are problems with docker on windows and with non-root containers. But docker is way better then most of the other tools I used for this (vagrant and whatnot).
A main problem in my opinion is, that old images are no longer published (or removed from dockerhub). I doubt very much, that you can build docker images that are written now in 2030.
But I assume the same happens with Packer + Terraform. In both cases you need to make sure the image is saved and accessible at a place you control, because the build will stop working at some point in time. Also the nice thing about docker is, it runs local (developer machine) and in production. I am not sure how you archive that with AMIs.
Building fat binaries is only easy for some specific languages and tools. In docker, it is easy for everything. At the end docker gives you a standardized way to deploy (image, environment variables, network, volumes and off you go!).
Now about docker in production. I had lots of problems with that. But if you use docker for local and don't have a ops department, it is the natural way to go. You run your integration tests with the same image that later runs on prod, so you don't need to worry, what stack is running on in a different environment. As a developer with a fully automated CI chain, I can control the entire deployment from my IDE (Dockerfile, Jenkinsfile, ...). My college can review the entire deployment in the PR (code-changes and infrastructure changes). And also docker has for most external software a ready to use image. Those are big benefits for small dev teams in small companies.
Also cloud providers offer docker tooling like a private image repository and docker support in most CI tools. I mention all of this, because the tooling around a container solution is important. You may dislike docker, but it integrates in most cloud providers and has images for almost everything.
The argument about complexity is true. If something doesn't work and you have no idea about the parts under the docker layer then its game over. But this is a very general argument against complexity. Complexity in software makes everything easy until you need to go down an abstraction layer. Nobody forces you to run your MySQL or Elasticsearch in docker container. This is definitely an unnecessary (and potentially dangerous) layer of complexity.
But to run the 10 years old PHP 5 application that needs memcached version 0.1.5, docker is very very useful: you spend a week to put all that legacy stuff in an docker image, push the image and all the team members can run it locally. Even the designer that knows a bit of jquery can run "docker-compose up" on his windows machine.
A main problem in my opinion is, that old images are no longer published (or removed from dockerhub). I doubt very much, that you can build docker images that are written now in 2030.
But I assume the same happens with Packer + Terraform. In both cases you need to make sure the image is saved and accessible at a place you control, because the build will stop working at some point in time. Also the nice thing about docker is, it runs local (developer machine) and in production. I am not sure how you archive that with AMIs.
Building fat binaries is only easy for some specific languages and tools. In docker, it is easy for everything. At the end docker gives you a standardized way to deploy (image, environment variables, network, volumes and off you go!).
Now about docker in production. I had lots of problems with that. But if you use docker for local and don't have a ops department, it is the natural way to go. You run your integration tests with the same image that later runs on prod, so you don't need to worry, what stack is running on in a different environment. As a developer with a fully automated CI chain, I can control the entire deployment from my IDE (Dockerfile, Jenkinsfile, ...). My college can review the entire deployment in the PR (code-changes and infrastructure changes). And also docker has for most external software a ready to use image. Those are big benefits for small dev teams in small companies.
Also cloud providers offer docker tooling like a private image repository and docker support in most CI tools. I mention all of this, because the tooling around a container solution is important. You may dislike docker, but it integrates in most cloud providers and has images for almost everything.
The argument about complexity is true. If something doesn't work and you have no idea about the parts under the docker layer then its game over. But this is a very general argument against complexity. Complexity in software makes everything easy until you need to go down an abstraction layer. Nobody forces you to run your MySQL or Elasticsearch in docker container. This is definitely an unnecessary (and potentially dangerous) layer of complexity.
But to run the 10 years old PHP 5 application that needs memcached version 0.1.5, docker is very very useful: you spend a week to put all that legacy stuff in an docker image, push the image and all the team members can run it locally. Even the designer that knows a bit of jquery can run "docker-compose up" on his windows machine.