Deploying a Docker Compose stack to a Vultr VPS with Nginx and HTTPS
You have a Flask frontend, a FastAPI backend, a Redis instance and a Celery worker, all wired together with Docker Compose. It works on your laptop. Now it needs to work on the internet, where nobody will forgive a missing environment variable.
Managed services such as Google Cloud Run are simpler. Sometimes you want more control, a predictable base server cost, or you simply enjoy getting your hands dirty with server administration. That is where a Virtual Private Server (VPS) such as Vultr comes in.
A VPS deployment is a single-host production setup where you own the whole stack (operating system, container runtime, reverse proxy and TLS certificates) in exchange for a fixed monthly base price rather than per-request billing. Storage, backups and bandwidth can still add to the bill. The limits are real too: one server means one point of failure, and updates cause a brief outage. I will say where that matters as we go.
This post takes a complete example from a blank Vultr server to HTTPS, with Nginx as the reverse proxy and Certbot with Letβs Encrypt for certificates. I wrote it after deploying another app to Vultr, and the docker group trap in Step 3 comes straight from my own deployment notes.
Prerequisites
- A Vultr account: If you do not have one, sign up at Vultr.
- A domain name: Registered with a provider such as GoDaddy.
- An SSH client: For Windows, PuTTY or Git Bash; for macOS and Linux, your built-in terminal.
- Git: Installed on your local machine.
- Your project in a Git repository: GitHub or similar, reachable from the server. The example below is small enough to type in yourself.
Throughout, I use one Ubuntu version, 22.04.5 LTS, because it is the one I have actually run this on, so every command in the post matches a single tested environment. Standard support for 22.04 ends in April 2027, so for a brand-new server you may prefer 24.04 LTS. Dockerβs installation page lists 24.04 and 26.04 as supported too, and the steps should carry over, but I have not followed this post on them.
The example project: Flask, FastAPI, Redis and Celery
π Subscribe to keep reading.
Deployment walkthrough: from blank VPS to HTTPS
π Subscribe to keep reading.
Verification: what success looks like at each layer
π Subscribe to keep reading.
Operations: logs, resources, backups, updates and troubleshooting
π Subscribe to keep reading.
Production hardening, briefly
π Subscribe to keep reading.
Pre-launch checklist for a Docker Compose VPS
π Subscribe to keep reading.
Final thoughts
π Subscribe to keep reading.
References
π Subscribe to keep reading.
You've hit a Deep Dive tutorial.
I spend dozens of hours researching, coding, and breaking things to write these guides. This content is free, but reserved for my subscriber community. Drop your email below to unlock this guide (and all past/future deep dives):
Full content temporarily unavailable β refresh in a moment
Already a subscriber? Use the magic link from your last newsletter, or reset your password.
Log in to unlock
New subscribers get an inbox mail: Set a password to unlock articles. The form does not log you in β use the same email afterwards.