learning_ai_common_plat/AI.dev/PROMPTS/docker-production-prep.md
saravanakumardb 32c7b1ba7e docs(prompts): add 14 reusable AI prompts for ecosystem-wide workflows
- roadmap-execution: phased roadmap execution with checkpoints
- new-product-scaffold: scaffold new ByteLyst product repos
- prd-to-implementation: convert PRDs to concrete plans
- cross-repo-debug: systematic multi-repo debugging
- backend-module-crud: Fastify CRUD modules (types/repo/routes/tests)
- platform-integration: wire products into common platform
- refactor-with-tests: test-first safe refactoring
- test-gap-analysis: coverage gap identification and remediation
- type-safety-sweep: TypeScript error triage and fix
- dependency-health-check: cross-repo dependency audit
- pre-release-validation: comprehensive release checklist
- docker-production-prep: production Docker images
- agents-md-sync: keep AI instruction files accurate
- ecosystem-audit: full ecosystem health dashboard
2026-05-17 16:48:58 -07:00

5.0 KiB

name description argument-hint agent
docker-production-prep Prepare Docker images for production deployment following ByteLyst conventions for corporate network, multi-stage builds, and security. Product and surface, e.g. "efforise backend", "flowmonk backend + web", "all product backends" agent

Docker Production Prep Prompt

Build production-ready Docker images for ByteLyst services following network, security, and performance best practices.

Context — ByteLyst Docker Conventions

Critical rules from corporate network:

  • Never use Alpineapk cannot bypass TLS interception; use node:22-slim (Debian)
  • Never use corepack in Dockerfiles — use npm install -g pnpm@10 or plain npm
  • Always add npm config set strict-ssl false before any npm install in build stages
  • Always add ENV NODE_TLS_REJECT_UNAUTHORIZED=0 in build stages with native modules
  • Production images don't need these workarounds (only build stages)

Dockerfile Template (Backend Service)

# ── Build Stage ────────────────────────────────────
FROM node:22-slim AS builder

# Corporate network workaround (build stage only)
RUN npm config set strict-ssl false
ENV NODE_TLS_REJECT_UNAUTHORIZED=0

WORKDIR /app

# Install pnpm (never use corepack)
RUN npm install -g pnpm@10

# Copy workspace files
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY backend/package.json backend/
COPY shared/ shared/

# Copy @bytelyst/* tarballs (if using prep-consumer.sh)
COPY .bytelyst-tarballs/ .bytelyst-tarballs/

# Install dependencies
RUN pnpm install --frozen-lockfile

# Copy source and build
COPY backend/ backend/
RUN cd backend && pnpm build

# ── Production Stage ───────────────────────────────
FROM node:22-slim AS production

WORKDIR /app

# Non-root user for security
RUN groupadd -r appuser && useradd -r -g appuser appuser

# Copy only production artifacts
COPY --from=builder /app/backend/dist/ ./dist/
COPY --from=builder /app/backend/package.json ./
COPY --from=builder /app/shared/ ./shared/
COPY --from=builder /app/node_modules/ ./node_modules/

# Security headers
ENV NODE_ENV=production

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD node -e "fetch('http://localhost:${PORT:-4020}/health').then(r => r.ok ? process.exit(0) : process.exit(1)).catch(() => process.exit(1))"

# Run as non-root
USER appuser

EXPOSE ${PORT:-4020}

CMD ["node", "dist/server.js"]

Preparation Steps

1. Pack @bytelyst/* Dependencies

If the Docker build doesn't have access to the sibling common_plat repo:

cd ../learning_ai_common_plat
./scripts/prep-consumer.sh /path/to/<product>

This packs tarballs and rewrites file: refs in package.json.

2. Create/Update docker-compose.yml

services:
  backend:
    build:
      context: .
      dockerfile: backend/Dockerfile
    ports:
      - "${PORT:-4020}:${PORT:-4020}"
    env_file: ./backend/.env
    restart: unless-stopped
    depends_on:
      platform-service:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "node", "-e", "fetch('http://localhost:${PORT:-4020}/health')"]
      interval: 30s
      timeout: 3s
      retries: 3

  web:
    build:
      context: .
      dockerfile: web/Dockerfile
    ports:
      - "3000:3000"
    environment:
      - NEXT_PUBLIC_API_URL=http://backend:${PORT:-4020}

3. Build & Test Locally

# Build
docker compose build

# Run
docker compose up -d

# Verify health
docker compose ps
curl -s http://localhost:<port>/health | jq .

# Check logs
docker compose logs backend --tail=20

# Run smoke test
curl -s http://localhost:<port>/api/<endpoint> | jq .

# Cleanup
docker compose down

4. Security Scan

# Scan the built image
docker scout cves <image>

# Check for leaked secrets
docker history <image> --no-trunc | grep -i "secret\|key\|password"

5. Optimize Image Size

# Check image size
docker images | grep <product>

# Target: < 200MB for backend services
# If too large, check:
# - Are devDependencies excluded? (use --prod install)
# - Is the build stage copying unnecessary files?
# - Are node_modules pruned in the production stage?

6. Commit

git add Dockerfile docker-compose.yml
git commit -m "chore(docker): production-ready Docker setup

- Multi-stage build (builder + production)
- Non-root user for security
- Health check configured
- Corporate network workarounds in build stage only
- Production image: ~NMB"
git push

Checklist

  • Base image: node:22-slim (never Alpine)
  • No corepack usage
  • strict-ssl false in build stage
  • Multi-stage build (builder → production)
  • Non-root user in production stage
  • Health check configured
  • NODE_ENV=production in production stage
  • No secrets in image layers
  • .dockerignore excludes: node_modules, .git, .env, dist, coverage
  • Image size < 200MB