Skip to content

Deploy with Docker

Package your Stoma gateway as a Docker container for deployment to Kubernetes, ECS, or any container platform.

  1. Create Dockerfile

    Dockerfile
    FROM node:22-alpine AS builder
    WORKDIR /app
    COPY package*.json ./
    RUN npm ci
    COPY src ./src
    RUN npm run build
    FROM node:22-alpine AS runner
    WORKDIR /app
    COPY --from=builder /app/dist ./dist
    COPY --from=builder /app/node_modules ./node_modules
    COPY --from=builder /app/package.json ./
    EXPOSE 3000
    CMD ["node", "dist/server.js"]
  2. Build and run

    Terminal window
    docker build -t stoma-gateway .
    docker run -p 3000:3000 stoma-gateway

For minimal image size (~55MB):

Dockerfile
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY src ./src
RUN npm run build
FROM node:22-alpine
WORKDIR /app
RUN addgroup -g 1001 -S nodejs && \
adduser -S stoma -u 1001
COPY --chown=stoma:nodejs --from=builder /app/dist ./dist
COPY --chown=stoma:nodejs --from=builder /app/node_modules ./node_modules
COPY --chown=stoma:nodejs --from=builder /app/package.json ./
USER stoma
EXPOSE 3000
ENV NODE_ENV=production
CMD ["node", "dist/server.js"]

Build and run:

Terminal window
docker build -t stoma-gateway:alpine .
docker run -p 3000:3000 stoma-gateway:alpine

Best for production with separate build and runtime stages:

Dockerfile
# Stage 1: Dependencies
FROM node:22-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
# Stage 2: Builder
FROM node:22-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# Stage 3: Runner
FROM node:22-alpine AS runner
WORKDIR /app
RUN addgroup -g 1001 -S stoma && \
adduser -S stoma -u 1001
COPY --from=builder --chown=stoma:stoma /app/dist ./dist
COPY --from=builder --chown=stoma:stoma /app/node_modules ./node_modules
COPY --from=builder --chown=stoma:stoma /app/package.json ./
USER stoma
EXPOSE 3000
ENV NODE_ENV=production PORT=3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
CMD ["node", "dist/server.js"]

For maximum security (no shell or package manager):

Dockerfile
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY src ./src
RUN npm run build
# Copy build artifacts to distroless base
FROM gcr.io/distroless/nodejs:22
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
EXPOSE 3000
ENV NODE_ENV=production
CMD ["dist/server.js"]
Base ImageSizeUse Case
node:22~1GBDevelopment only
node:22-alpine~55MBProduction
gcr.io/distroless/nodejs:22~100MBProduction (smallest)
node:22-slim~300MBProduction (debugging)