GiggleGigs is a job board I run: Django + DRF on the backend, React + Vite on the front, Celery for background work, all in Docker, on a single 2 GB DigitalOcean droplet .
Deploys were the cookiecutter-django default: GitHub Actions SSHes into the droplet, runs git pull , then docker compose build , then restarts everything. It's simple, and it worked fine right up to the first time it didn't.
The problem: the droplet was also the build server
Most deploys only change application code, so Docker reuses the cached pip layer and the build finishes quickly. But any change to requirements/*.txt invalidates that layer, and the droplet then has to rebuild every wheel from scratch.
On 2 GB of RAM, that's dangerous. One build compiled psycopg-c from source, ran the box out of memory, and froze it so completely that SSH stopped responding.…