I thought I was reading my own blog post :) We use very similar tech stack at my current company:

- Ansible for provisioning

- Python/Django for website/api

- VueJS for frontend(where needed, some pages are simple Django templates)

- Celery for background work

- uWSGI and Nginx as servers with AWS Load balancer

- Elasticsearch for search

- Redis for caching

- Postgres with Postgis as main datastore

- Datadog for monitoring

- Cloudflare for DNS

Some differences as I am working with a team:

- We do use multiple branches and git tags for releases. Feature branches are also common as multiple devs maybe working on different features.

- We use Gitlab-CI a lot for testing and auto-deployment(ansible script can be called from our machine as well)

- Terraform for infrastructure provisioning. We have stopped provisioning any AWS service by console. Once the service is provisioned by terraform, ansible takes over.

I have tinkered with Docker, Hashicorp Packer but this setup has been dead simple to reason and scale reasonably well.

How do you feel about using a dynamically typed language like Python for all your backend code? Whenever I had a codebase that grew past several thousand LOC it became pretty unwieldy pretty quickly for me personally. I'm curious if there's a conscious tradeoff for people using Python/Django to start because it's really fast to get up and running with (for existing or new devs).

Python supports optional static typing annotations now.

There are four popular typecheckers that I'm aware of (mypy [1], pyre [2], pyright [3], pytype [4]), which is a little confusing, but any of the four will catch a lot of type issues that typical statically typed language compilers would catch. It's not as robust as true static typing - there are sometimes false positives and false negatives - but I find it helpful.

[1] https://github.com/python/mypy

[2] https://github.com/facebook/pyre-check

[3] https://github.com/microsoft/pyright

[4] https://github.com/google/pytype