Skip to main content

JavaScript (server-side)

This Dockerfile builds a JavaScript app with a server, and creates a Docker image that runs it.

Without dependencies

The following Dockerfile does not deploy the node_modules folder. The build tool needs to bundle everything that the application needs.

If your build tool relies on node_modules, refer to the next section.

# --- Build ---

FROM node:20 AS build-env
WORKDIR /app

ENV CI=true

COPY ./package.json /app/package.json
COPY ./package-lock.json /app/package-lock.json

RUN npm ci

COPY . /app

RUN npm run build


# --- Run ---

FROM gcr.io/distroless/nodejs20:nonroot
WORKDIR /app

# Assuming the build step generated its output in ./out
COPY --from=build-env /app/out /app

ENV NODE_ENV=production
CMD ["main.js"]

EXPOSE 80

With dependencies

Some build tools (such as Astro) produce an output that needs node_modules to be deployed as well. With the following Dockerfile, the production dependencies are also included in the container.

# --- Build ---

FROM node:20 AS build-env
WORKDIR /app

ENV CI=true

COPY ./package.json /app/package.json
COPY ./package-lock.json /app/package-lock.json

RUN npm ci

COPY . /app

RUN npm run build

# --- Dependencies ---
FROM node:20 AS dependencies
WORKDIR /app

ENV CI=true
ENV NODE_ENV=production

COPY ./package.json /app/package.json
COPY ./package-lock.json /app/package-lock.json

RUN npm ci


# --- Run ---

FROM gcr.io/distroless/nodejs20:nonroot
WORKDIR /app

# Assuming the build step generated its output in ./out
COPY --from=build-env /app/out /app
COPY --from=dependencies /app/node_modules /app/node_modules

ENV NODE_ENV=production
CMD ["main.js"]

EXPOSE 80