Independent comparison · no paid rankings
Home / Blog / Docker for application hosting: start without stacking containers
Guide

Docker for application hosting: start without stacking containers

A clean Dockerfile and one app container are often enough to deploy. Save multi-service docker-compose for real needs — not fashion.

5 min read Updated Jul 19, 2026

You read a tutorial: Node app, Redis, Postgres, Nginx, worker — five docker-compose containers copy-pasted. On an 8 GB VPS, the stack starts… and falls under real load because nobody sized resources or configured healthchecks. Docker was not the problem. Premature stacking was.

Docker solves one pain: "it worked on my machine." It freezes dependencies and the start command. To host a web app, start with one well-built application container — not a Rube Goldberg factory.

Step 1: a readable Dockerfile

Start from an official pinned base (node:20-alpine, php:8.3-fpm). Use a multi-stage build: one stage to compile assets, one minimal runtime stage. Run the final process as a non-root user, add a simple HTTP HEALTHCHECK, and keep an aggressive .dockerignore — no local node_modules or embedded .git.


FROM node:20-alpine AS build

WORKDIR /app

COPY package*.json ./

RUN npm ci

COPY . .

RUN npm run build



FROM node:20-alpine

USER node

WORKDIR /app

COPY --from=build /app/dist ./dist

COPY --from=build /app/node_modules ./node_modules

EXPOSE 3000

CMD ["node", "dist/server.js"]

A Dockerfile is a runtime contract. If it exceeds one page, simplify the app or split services later.

Step 2: data outside the container

Uploads must not live in the container ephemeral layer: use a volume or object storage. SQL must not run without a named volume unless you prefer managed database at the host. Logs can go to stdout, but plan external aggregation. Secrets must never be baked into the image: inject them at runtime, as the guide Deployment secrets reminds.

On a small project, app in Docker, managed Postgres at the host avoids operating a database on the same VPS.

Step 3: docker-compose only when needed

Compose makes sense for local development or a small single-tenant VPS with two or three coupled services. In production, keep it if you self-host Redis and the app on one machine, or if you need an internal app ↔ redis network without exposing Redis publicly. Otherwise one app service behind a reverse proxy (Caddy or Nginx on the host, or a single reverse-proxy container) is enough.

Deploy on VPS: simple pattern

Build the image in CI, push to a registry (GHCR, Scaleway Registry…), then on the VPS run docker pull and docker run with volumes and --restart unless-stopped. Terminate TLS on a host reverse proxy pointing to the container port. Centralize logs via docker logs or an agent, and update by redeploying a tagged image — never :latest without an explicit pin.

Container PaaS options (Clever Cloud, Fly.io, Render) absorb registry and light orchestration if you prefer to skip VPS administration.

Document the exact docker run flags or compose file you use in production: port mapping, volume paths, environment file location. When the only person who knows the command leaves, a one-container setup becomes harder to recover than a plain systemd service if nothing is written down.

Beginner production mistakes

Avoid :latest without a pinned version: deploy becomes non-reproducible. Do not run the container as root: escape is more dangerous. Set memory limits: silent OOM kill can surprise you. Do not copy a dev compose to prod with exposed ports and weak passwords. Finally, do not confuse Docker with orchestration: Docker alone does not deliver multi-node HA — Kubernetes is another league.

The peak: Docker simplifies deploy, not architecture

Before stacking, ask: what must scale separately? If the answer is "nothing yet", one container is enough.

Decide and move forward without blind spots

Write a multi-stage Dockerfile with a non-root user, externalize the database and heavy files, and reserve Compose for services that truly co-locate. Wire CI to build and push the image, then pull a tagged version on the VPS. Compare Docker and PaaS hosts via the directory and the guide PaaS or server to place complexity elsewhere if needed.

Frequently asked questions

Does Docker replace a classic VPS?

No. Docker encapsulates the application; you still need a host machine. It standardizes the runtime environment without replacing infrastructure.

One container or docker-compose from day one?

One app container with managed database is often enough. Compose becomes useful if Redis or PostgreSQL run on the same machine as the app.

Where to store persistent data?

Docker volumes or managed services — not ephemeral filesystem alone, or you lose data on restart.

Docker on shared hosting?

Rarely available. Docker targets VPS, dedicated, or container PaaS.


Docker for application hosting is not collecting containers. It is one deployable artifact — then as many services as your architecture actually requires.

Compare European hosts

Filter by compliance, location and use case — then open the sheets to verify the real scope.

Browse the directory
Blog

Related reading

All articles →