How to Deploy a Node.js Application with Docker on a VPS
Docker packages your Node.js app together with its exact Node version and dependencies into a container that runs identically on your laptop, a VPS, or anywhere else. It ends "works on my machine" problems and makes deployment repeatable.
Why containerise a Node app?
- Consistency — the same environment everywhere, so no version surprises.
- Isolation — the app and its dependencies are self-contained.
- Easy deployment — ship one image; run it anywhere Docker runs.
Writing a Dockerfile
A solid, cache-friendly Dockerfile:
FROM node:lts-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
Copying package*.json and installing before copying the rest lets Docker cache the dependency layer, so rebuilds are fast when only your code changes.
Build and run
docker build -t myapp .
docker run -d -p 3000:3000 --env-file .env --restart unless-stopped myapp
--restart unless-stopped keeps it running across reboots and crashes, and --env-file supplies your environment variables.
Production tips
- Use multi-stage builds to keep images small — build in one stage, copy only what you need into a slim final image.
- Run as a non-root user inside the container for security.
- Put Nginx in front for SSL and routing.
- Automate builds with CI/CD.
Frequently asked questions
Do I need Docker for a simple app?
Not necessarily — PM2 or systemd is simpler for a single app. Docker shines when you want reproducible environments, multiple services, or easy portability between servers.
Why use npm ci instead of npm install?
npm ci installs exactly what your lockfile specifies, giving reproducible builds — ideal for containers and CI. npm install can update the lockfile, which you do not want in a build.
Can I run Docker on shared hosting?
Generally no — Docker needs a VPS or dedicated server with the right access. Shared hosting does not permit it. See shared vs VPS vs dedicated.
Was this article helpful?