Docker & Containers

Crafting the Perfect Dockerfile: A Step-by-Step Guide for Microservice

By the Domain India teamPublished 6 min read
Knowledge base article
Contents (5 sections)

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.

Key takeaways

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.

For the complete, tested walkthrough

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 install can change versions between builds. npm ci installs exactly what package-lock.json says.
  • 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

dockerfile
# 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:

text
node_modules
.git
.env
*.env
npm-debug.log
coverage

If 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

Pin your base image
Use a specific tag such as a 24.x release, never just latest, so builds are repeatable.
Order for the cache
Put steps that rarely change at the top and your code near the bottom.
Keep it small
Use slim images, skip dev dependencies, and use multi-stage builds for compiled code.
Never bake in secrets
Pass API keys and database passwords at run time with environment variables or your platform's secrets.
Run as non-root
Switch to an unprivileged user such as node before CMD.
Listen on 0.0.0.0 and PORT
A service bound to localhost inside a container can't be reached from outside it.

4. Build and run it

bash
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

WhereDocker?How it works
cPanel or DirectAdmin shared hostingNoDocker can't run on shared hosting
App PlatformYou supply the Dockerfile, we build and run itNode.js is detected automatically; other languages build from your Dockerfile
VPSYes, you install itA 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 PORT and bind to 0.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.
App Developer
₹250/mo + GST
  • 512 MB RAM per app
  • 1.5 GB RAM total
  • 2 vCPU
  • 10 GB NVMe SSD
See plan details
VPS Starter
₹552.65/mo + GST
  • 1 vCPU
  • 2 GB DDR4 RAM
  • 64 GB NVMe SSD Storage
  • 2 TB Monthly Bandwidth
See plan details

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 your container on the App Platform

Deploy from GitHub or with a deploy token, with PostgreSQL and free SSL included on every plan.

See App Platform plans

Was this article helpful?

Your answer helps us decide what to improve next.

Still need help? Open a support ticket and our team will reply.

Prefer an app? Add this site to your home screen.Get the app
Write a Dockerfile for a Microservice | Domain India