A Dockerfile is the recipe Docker follows to build an image: which base image to start from, which files to copy, what to install and which command starts your service. A good one builds fast, produces a small image, runs as a non-root user and keeps secrets out. This page gives you the current pattern for a microservice and links to the full walkthrough.
Start from a small, supported, pinned base image (for Node.js, node:24-slim), copy the dependency files first and install with a lockfile (npm ci --omit=dev), then copy your code, switch to a non-root user and start the service with CMD in JSON form. Add a .dockerignore, pass secrets at run time, and make the service read PORT and listen on 0.0.0.0. You can run the image on your own VPS, or let the Domain India App Platform build it from your Dockerfile.
This page is the short version. The full guide, with the reasons behind every line, a health check, testing steps and Docker Compose, is Containerizing the user service with Docker.
1. What changed since older Dockerfile guides
Many older tutorials start with FROM node:14, COPY . . and RUN npm install. That pattern still builds, but it is out of date:
- Node.js 14, 16, 18 and 20 are past end of life and get no security fixes. Use a current LTS line: Node.js 24 or 22.
npm installcan change versions between builds.npm ciinstalls exactly whatpackage-lock.jsonsays.- Copying everything before installing throws away Docker's build cache every time any file changes, so every build reinstalls all dependencies.
- Running as root inside the container gives an attacker more to work with if the service is compromised.
2. A current Dockerfile for a Node.js microservice
# syntax=docker/dockerfile:1
FROM node:24-slim
ENV NODE_ENV=production
WORKDIR /app
# Dependencies first, so this layer is cached until they change
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
# Then the code, owned by the image's unprivileged user
COPY --chown=node:node . .
USER node
ENV PORT=8080
EXPOSE 8080
CMD ["node", "server.js"]Next to it, a .dockerignore keeps local clutter and secrets out of the build:
node_modules
.git
.env
*.env
npm-debug.log
coverageIf your service needs a build step, such as TypeScript, use a multi-stage build: install everything and compile in a first stage, then copy only the compiled output and production dependencies into a clean final stage. The same ideas apply to other languages: for Python, start from python:3.12-slim or newer and install from a pinned requirements.txt with pip install --no-cache-dir.
3. The rules that matter most
4. Build and run it
docker build -t my-service:1.0 .
docker run -d --name my-service -p 8080:8080 --env-file .env my-service:1.0
docker logs -f my-service-p 8080:8080 maps port 8080 on the host to port 8080 in the container. On a public server, put a reverse proxy such as nginx or Caddy with HTTPS in front of the service rather than exposing application ports directly. Rebuild regularly to pick up security fixes in the base image, and scan images with a tool such as Docker Scout or Trivy.
5. Where to run your image on Domain India
| Where | Docker? | How it works |
|---|---|---|
| cPanel or DirectAdmin shared hosting | No | Docker can't run on shared hosting |
| App Platform | You supply the Dockerfile, we build and run it | Node.js is detected automatically; other languages build from your Dockerfile |
| VPS | Yes, you install it | A self-managed Linux server with root access |
- App Platform: deploy from GitHub or with a deploy token, and the platform builds your Dockerfile, runs the container and serves it over HTTPS. Your service must read
PORTand bind to0.0.0.0. There is no SSH access. See Getting started with the App Platform. - VPS: full root access to install Docker and Docker Compose yourself. You look after updates, the firewall and backups.
- Shared hosting: see Docker on cPanel and DirectAdmin for why it isn't possible and what to do instead.
- 512 MB RAM per app
- 1.5 GB RAM total
- 2 vCPU
- 10 GB NVMe SSD
- 1 vCPU
- 2 GB DDR4 RAM
- 64 GB NVMe SSD Storage
- 2 TB Monthly Bandwidth
The cards show live Domain India prices, excluding 18% GST.
Which base image should a Node.js Dockerfile use in 2026?
A current Node.js LTS line such as node:24-slim or node:22-slim, pinned to a specific release for repeatable builds. Node.js 20 and older are past end of life.
Why copy package.json before the rest of the code?
Docker caches each step. Copying only the dependency files first means the install step is reused until dependencies change, so most rebuilds take seconds instead of minutes.
Should I use npm install or npm ci in a Dockerfile?
Use npm ci. It installs exactly the versions in package-lock.json and fails if the lockfile and package.json disagree. Add --omit=dev for production images.
How do I pass secrets to a container?
At run time, with --env-file or -e on docker run, or through your platform's environment settings. Never write them into the Dockerfile or copy a .env file into the image.
Can I run Docker on Domain India shared hosting?
No. Use the App Platform, which builds and runs your Dockerfile for you, or a VPS where you install Docker yourself.
Ready to ship your service? Compare App Platform plans and VPS plans, or open a support ticket if you're not sure which fits.
Deploy from GitHub or with a deploy token, with PostgreSQL and free SSL included on every plan.
See App Platform plans