Run Docker on a VPS with a production operating plan
Docker makes an application easier to package, but a container becoming reachable is only the beginning of operating it. A VPS still needs a resource budget, deliberate network exposure, recoverable data and a release process someone can maintain.
The practical takeaway
Treat the Compose project as a reproducible application definition, keep persistent data explicit, publish only intended entry points and test a recovery path before relying on the deployment.
Describe the application and the single-host boundary
Start with a diagram containing the public reverse proxy, application, database, workers and persistent files. Write down which components must reach each other and which need access from the Internet. A small Compose deployment can be a practical operating model for one VPS. It does not become a highly available cluster merely because several containers are running.
Identify the host-level responsibilities: operating-system updates, Docker maintenance, administrative access, firewall policy and backup scheduling. Container restart behaviour can help recover a stopped process, but it cannot repair lost data, unavailable storage or a failed host. Decide what the project does when the entire VPS is unavailable and how the application would be recreated elsewhere.
Check the selected operating system and the application image architecture against the software documentation. Keep development conveniences separate from production decisions. A source-code bind mount, debug mode or local-only credential that was useful on a laptop should not become part of the public deployment simply because it appears in the same Compose file.
Budget memory, CPU and temporary disk together
| Component | Example memory allowance | What to measure |
|---|---|---|
| Host and supporting agents | 1 GB | Operating system and routine operational overhead |
| Database | 2 GB | Buffers, concurrent connections and real query workload |
| Application processes | 2 GB | Normal load and realistic request peaks |
| Background workers | 1 GB | Imports, image processing and scheduled tasks |
| Unallocated headroom | 2 GB | Release overlap and unusual operational activity |
This illustrative 8 GB budget is a planning exercise, not a measured requirement or a hosting performance promise. Confirm actual usage with the intended application and configure resource controls appropriate to your Docker setup. A database and a worker can peak together even when each looked comfortable during separate tests. A container count is not a useful substitute for a workload measurement.
Disk planning needs more than the current database size. Include images, persistent volumes, application uploads, logs and temporary space during imports or application deployments. Keep a reserve that allows investigation and recovery work. If a deployment needs to download a new image while retaining the previous one, a disk that is already almost full can turn an ordinary update into an outage.
Define persistent data and prove its recovery
Use explicit named volumes or carefully documented bind mounts for data that must survive replacing a container. Name the owner and purpose of each mount. Keep database files, uploads and disposable caches distinguishable in the operating notes. The writable layer inside an individual container should not be the only place a customer document exists.
A Docker volume persists independently of a container, but persistence is not an independent backup. Choose a supported consistent backup method for the database, capture related application files and test restoration into an isolated deployment. Do not assume copying a live database volume produces a usable recovery point. Record how the volume, application release and database state are matched during recovery.
Before attaching a mount, confirm both its source and destination. Mounting a volume over a directory can hide files already present at that container path. When an application unexpectedly appears empty after a deployment, check the actual mount and selected volume before taking a destructive cleanup action. The data may be in a different volume rather than absent.
Publish entry points deliberately and test them externally
Usually the public entry point is the reverse proxy, while the application database remains reachable only through the intended internal path. Distinguish a port used between containers from a port published on the host. Avoid exposing database, administrative and metrics interfaces merely to make a connection test easier. Protect management access separately from the public website.
Docker creates networking and firewall rules on Linux. Its published-port traffic can bypass the host firewall path an operator expects when using ufw. Follow Docker documentation for the installed networking and firewall backend, then verify the result from outside the VPS. A reassuring host rule list is not proof that a published container port is unreachable.
For the first production review, list every externally reachable port and assign it a purpose. Check the application hostname over HTTPS and confirm that unintended administrative paths are not public. Keep private configuration outside image source and public repositories. Review the privileges, mounts and host interfaces granted to each service rather than automatically giving every container broad access.
Keep releases reproducible and logs bounded
Record an explicit image version or digest for each release and retain the configuration used to deploy it. Review production-specific Compose settings, including restart behaviour, ports, environment and mounts. Test the replacement application before accepting it. Rolling back an image is only safe when any database schema changes remain compatible or have their own rehearsed recovery procedure.
Set a deliberate logging policy. Docker logging drivers differ, and the default json-file configuration can grow without rotation. Choose an appropriate bounded configuration and confirm it on the containers actually running; changing a daemon default does not automatically reconfigure existing containers. Keep useful application events without recording passwords, tokens or complete sensitive request bodies.
- The documented image and Compose configuration can recreate the application.
- Persistent data has a separate, tested recovery procedure.
- Only approved ports are reachable from outside the VPS.
- Logs have a verified size and retention policy.
- A named operator owns updates, alert review and checks after each deployment.
Start with a deployment small enough to understand. Add orchestration complexity only when a measured requirement justifies it and the team can operate the extra components. A clear single-host recovery plan is more useful than a collection of containers whose data and responsibilities nobody can trace.