kconner / next-js-in-docker-example

Next.js + Docker + Compose + Kubernetes + VS Code + TypeScript + Jest + Storybook
113 stars 28 forks source link

How to add jest and cypress testing inside a container? #31

Closed alamenai closed 8 months ago

alamenai commented 9 months ago

Thank you @kconner for this amazing repository.

I used the docker example from NextJS, however, I did not figure out how to add and run my tests inside the container.

This is my Dockerfile.prod:

FROM node:20-alpine AS base

# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app

# Install dependencies based on the preferred package manager
COPY package.json ./

# You can use these package managers
# yarn.lock* package-lock.json* pnpm-lock.yaml*

# RUN \
#   if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
#   elif [ -f package-lock.json ]; then npm ci; \
#   elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
#   else echo "Lockfile not found." && exit 1; \
#   fi

RUN npm install --legacy-peer-deps --verbose

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry during the build.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN npm run build

# If using npm comment out above and use below instead
# RUN npm run build

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public

# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT 3000
# set hostname to localhost
ENV HOSTNAME "0.0.0.0"

# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD ["node", "server.js"]

This is my package.json:

{
  "name": "esg-suite",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "predev": "node scripts/babel/backup.js",
    "prebuild": "node scripts/babel/backup.js",
    "precypress-run-component": "node scripts/babel/restore.js",
    "precypress-open-component": "node scripts/babel/restore.js",
    "precypress-run-e2e": "node scripts/babel/restore.js",
    "precypress-open-e2e": "node scripts/babel/restore.js",
    "dev": "next dev",
    "build": "next build",
    "test": "jest",
    "test-watch": "jest --watch",
    "start": "next start",
    "lint": "next lint",
    "lint-staged": "npx lint-staged",
    "lint-style": "npx stylelint src/*.css src/**/**/*.css",
    "cypress-open-component": "cypress open --component",
    "cypress-open-e2e": "cypress open --e2e",
    "cypress-run-component": "cypress run --component --headless",
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build"
  },
  "dependencies": {
    "@headlessui/tailwindcss": "^0.2.0",
    "@mapbox/mapbox-gl-geocoder": "^5.0.2",
    "@mapbox/search-js-react": "1.0.0-beta.18",
    "@mdx-js/loader": "^3.0.0",
    "@mdx-js/react": "^3.0.0",
    "@next/mdx": "^14.1.0",
    "@radix-ui/react-accordion": "^1.1.2",
    "@radix-ui/react-alert-dialog": "^1.0.5",
    "@radix-ui/react-checkbox": "^1.0.4",
    "@radix-ui/react-collapsible": "^1.0.3",
    "@radix-ui/react-dialog": "^1.0.5",
    "@radix-ui/react-dropdown-menu": "^2.0.6",
    "@radix-ui/react-label": "^2.0.2",
    "@radix-ui/react-popover": "^1.0.7",
    "@radix-ui/react-scroll-area": "^1.0.5",
    "@radix-ui/react-separator": "^1.0.3",
    "@radix-ui/react-slot": "^1.0.2",
    "@radix-ui/react-tabs": "^1.0.4",
    "@radix-ui/react-toggle": "^1.0.3",
    "@radix-ui/react-toggle-group": "^1.0.4",
    "@reduxjs/toolkit": "^1.9.7",
    "@sentry/nextjs": "^7.94.1",
    "@testing-library/jest-dom": "^6.2.0",
    "@tremor/react": "^3.13.2",
    "@trivago/prettier-plugin-sort-imports": "^4.3.0",
    "@types/mdx": "^2.0.10",
    "@types/node": "20.4.0",
    "@types/react": "^18.2.48",
    "@types/react-dom": "^18.2.18",
    "chai-colors": "^1.0.1",
    "chart.js": "^4.4.1",
    "class-variance-authority": "^0.7.0",
    "classnames": "^2.5.1",
    "clsx": "^2.1.0",
    "cmdk": "^0.2.0",
    "contentlayer": "^0.3.4",
    "eslint-config-next": "^14.1.0",
    "eslint-plugin-simple-import-sort": "^10.0.0",
    "framer-motion": "^10.18.0",
    "i18next": "^23.7.17",
    "i18next-browser-languagedetector": "^7.2.0",
    "i18next-resources-to-backend": "^1.2.0",
    "istanbul-lib-coverage": "^3.2.2",
    "jest-environment-jsdom": "^29.7.0",
    "lucide-react": "^0.312.0",
    "mapbox-gl": "^3.1.0",
    "next": "^14.1.0",
    "next-contentlayer": "^0.3.4",
    "next-themes": "^0.2.1",
    "normalize.css": "^8.0.1",
    "react": "^18.2.0",
    "react-chartjs-2": "^5.2.0",
    "react-dom": "^18.2.0",
    "react-i18next": "^13.5.0",
    "react-icons": "^4.12.0",
    "react-redux": "^8.1.3",
    "react-to-print": "^2.14.15",
    "redux-persist": "^6.0.0",
    "sharp": "^0.32.6",
    "stylelint": "^15.11.0",
    "swr": "^2.2.4",
    "tailwind-merge": "^2.2.0",
    "tailwindcss-animate": "^1.0.7",
    "tsconfig-paths-jest": "^0.0.1",
    "whatwg-fetch": "^3.6.20",
    "zod": "^3.22.4"
  },
  "devDependencies": {
    "@babel/preset-react": "^7.23.3",
    "@commitlint/cli": "^17.8.1",
    "@commitlint/config-conventional": "^17.8.1",
    "@cypress/code-coverage": "^3.12.18",
    "@istanbuljs/nyc-config-typescript": "^1.0.2",
    "@jest/globals": "^29.7.0",
    "@storybook/addon-essentials": "^7.6.10",
    "@storybook/addon-interactions": "^7.6.10",
    "@storybook/addon-links": "^7.6.10",
    "@storybook/addon-onboarding": "^1.0.10",
    "@storybook/blocks": "^7.6.10",
    "@storybook/nextjs": "^7.6.10",
    "@storybook/react": "^7.6.10",
    "@storybook/testing-library": "^0.2.2",
    "@testing-library/react": "^14.1.2",
    "@typescript-eslint/eslint-plugin": "^6.19.0",
    "@typescript-eslint/parser": "^6.19.0",
    "autoprefixer": "^10.4.17",
    "babel-plugin-istanbul": "^6.1.1",
    "cypress": "^13.6.3",
    "cypress-react-selector": "^3.0.0",
    "eslint": "^8.56.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-cypress": "^2.15.1",
    "eslint-plugin-import": "^2.29.1",
    "eslint-plugin-jsx-a11y": "^6.8.0",
    "eslint-plugin-react": "^7.33.2",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-storybook": "^0.6.15",
    "fetch-mock": "^9.11.0",
    "husky": "^8.0.3",
    "jest": "^29.7.0",
    "jest-next-dynamic": "^1.0.1",
    "lint-staged": "^13.3.0",
    "msw": "^1.3.2",
    "node-fetch": "^3.3.2",
    "nyc": "^15.1.0",
    "postcss": "^8.4.33",
    "prettier": "^3.2.4",
    "storybook": "^7.6.10",
    "stylelint-config-standard": "^34.0.0",
    "stylelint-prettier": "^4.1.0",
    "tailwindcss": "^3.4.1",
    "ts-jest": "^29.1.1",
    "ts-node": "^10.9.2",
    "typescript": "^5.3.3"
  }
}
alamenai commented 8 months ago

I solved the issue by moving the test in independent layer in the pipeline.