aws-amplify / aws-amplify/amplify-hosting

NextJS deployment issue. 503 & Missing Image and ISR services.

Open
#2,430 25 comments 0 reactions 0 assignees View on GitHub
ssr
Dominant language
Dockerfile
Stars
481
Forks
123
PR merge metrics
No merged PRs in 30d

Description

### Before opening, please confirm:

- [X] I have checked to see if my question is addressed in the [FAQ](https://github.com/aws-amplify/amplify-console/blob/master/FAQ.md).
- [X] I have [searched for duplicate or closed issues](https://github.com/aws-amplify/amplify-console/issues?q=is%3Aissue+).
- [X] I have read the guide for [submitting bug reports](https://github.com/aws-amplify/amplify-console/blob/master/CONTRIBUTING.md).
- [X] I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.

### App Id

arn:aws:amplify:us-west-2:707129987630:apps/d30o3wao502f5x

### Region

us-west-2

### Amplify Console feature

Build settings, Monorepo

### Describe the bug

Quick and simple. I rewrote my app to stop using NX and just work with Yarn workspaces. After a few days it's finally deploying and it looks good. The issue revolves around the services that are deployed after build. When I deploy the app, the only services that are spun up are `SSR Lambda@Edge, CloudFront Domain and S3 Bucket`.

It looks like ISR and Image optimization are both not created during deployment. When I check the lambda logs the only issue I get is
```
{
"errorType": "Error",
"errorMessage": "Cannot find module '../../webpack-runtime.js'\nRequire stack:\n- /var/task/pages/restaurant/[id].js\n- /var/task/index.js\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js",
"code": "MODULE_NOT_FOUND",
"requireStack": [
"/var/task/pages/restaurant/[id].js",
"/var/task/index.js",
"/var/runtime/UserFunction.js",
"/var/runtime/index.js"
],
"stack": [
"Error: Cannot find module '../../webpack-runtime.js'",
"Require stack:",
"- /var/task/pages/restaurant/[id].js",
"- /var/task/index.js",
"- /var/runtime/UserFunction.js",
"- /var/runtime/index.js",
" at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15)",
" at Function.Module._load (internal/modules/cjs/loader.js:667:27)",
" at Module.require (internal/modules/cjs/loader.js:887:19)",
" at require (internal/modules/cjs/helpers.js:74:18)",
" at /var/task/pages/restaurant/[id].js:1577:27",
" at Object. (/var/task/pages/restaurant/[id].js:1583:3)",
" at Module._compile (internal/modules/cjs/loader.js:999:30)",
" at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)",
" at Module.load (internal/modules/cjs/loader.js:863:32)",
" at Function.Module._load (internal/modules/cjs/loader.js:708:14)"
]
}
```
It's weird this now only appears on a single page that uses getSSRprops and takes a query param. Otherwise the site works (minus the images).

I read this could be a Next 12 issue, however, I solved the 503 error by removing the transpile modules plugin and I originally the day Next12 came out successfully deployed a Next 12 app with Webpack 5.

### Expected behavior

The expected services that should be deployed are `SSR Lambda@Edge, CloudFront Domain, S3 Bucket, API Lambda@Edge, Image optimization, ISR Lambda and ISR SQS Queue.`

### Reproduction steps

# PKG JSON
```
{
"name": "fox-app",
"version": "0.0.2",
"license": "MIT",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"amplify-build": "yarn share:static:hardlink && cross-env AMPLIFY_NEXTJS_EXPERIMENTAL_TRACE=true next build",
"vercel-build": "yarn share:static:hardlink && cross-env NEXTJS_BUILD_TARGET=serverless next build",
"clean": "rimraf --no-glob ./.next ./out ./coverage ./tsconfig.tsbuildinfo ./.eslintcache && jest --clear-cache",
"start": "next start",
"?share:static:symlink": "echo 'Use this command to link assets, locales... from shared static folder'",
"share:static:symlink": "rimraf ./public/shared-assets && symlink-dir ../../static/assets ./public/shared-assets",
"?share:static:hardlink": "echo 'Use this command to link assets, locales... from shared static folder'",
"share:static:hardlink": "rimraf ./public/shared-assets && syncdir ../../static/assets ./public/shared-assets --copy",
"bundle:analyze": "cross-env ANALYZE=true yarn build",
"bundle:check-size": "size-limit",
"test": "run-s 'test:*'",
"test:unit": "jest --config jest.config.js --maxWorkers=50% --color $@",
"test:e2e": "playwright test",
"test:e2e:prod": "cross-env E2E_PLAYWRIGHT_MODE=BUILD_AND_START playwright test",
"ci-test:unit": "jest --config jest.config.js --runInBand --color $@",
"typecheck": "tsc --project ./tsconfig.json --noEmit",
"lint": "eslint . --ext .ts,.tsx,.js,.jsx",
"fix:staged-files": "lint-staged --allow-empty",
"fix:all-files": "eslint . --ext .ts,.tsx,.js,.jsx --fix"
},
"dependencies": {
"@aws-amplify/api": "4.0.28",
"@aws-amplify/auth": "4.3.18",
"@aws-amplify/storage": "4.4.11",
"@babel/core": "7.16.0",
"@date-io/date-fns": "2.11.0",
"@dnd-kit/core": "^4.0.3",
"@dnd-kit/sortable": "^5.1.0",
"@dnd-kit/utilities": "3.0.1",
"@fox-dls/banner": "1.0.1",
"@fox-dls/card": "1.0.1",
"@fox-dls/carousels": "1.0.1",
"@fox-dls/checkbox": "1.0.1",
"@fox-dls/datepicker": "1.0.1",
"@fox-dls/drawer": "1.0.1",
"@fox-dls/editor": "1.0.1",
"@fox-dls/error": "1.0.1",
"@fox-dls/filepond": "1.0.1",
"@fox-dls/footer": "1.0.1",
"@fox-dls/hours": "1.0.1",
"@fox-dls/layout": "1.0.1",
"@fox-dls/loading": "1.0.1",
"@fox-dls/map": "1.0.1",
"@fox-dls/mobile-navigation": "1.0.1",
"@fox-dls/modal": "1.0.1",
"@fox-dls/navigation": "1.0.1",
"@fox-dls/overlays": "1.0.1",
"@fox-dls/pulse": "1.0.1",
"@fox-dls/routes": "1.0.1",
"@fox-dls/select": "1.0.1",
"@fox-dls/skeleton": "1.0.1",
"@fox-dls/textfield": "1.0.1",
"@fox-dls/theme": "1.0.1",
"@fox-dls/timepicker": "1.0.1",
"@fox-dls/utils": "1.0.1",
"@googlemaps/js-api-loader": "^1.12.11",
"@material-ui/styled-engine": "npm:@material-ui/styled-engine-sc@next",
"@mui/core": "^5.0.0-alpha.54",
"@mui/icons-material": "5.2.0",
"@mui/lab": "^5.0.0-alpha.58",
"@mui/material": "^5.2.2",
"@reduxjs/toolkit": "^1.6.2",
"@sentry/nextjs": "^6.15.0",
"@sentry/node": "6.15.0",
"@styled-icons/boxicons-logos": "^10.38.0",
"@styled-icons/boxicons-regular": "^10.38.0",
"@styled-icons/boxicons-solid": "^10.38.0",
"@styled-icons/entypo": "^10.34.0",
"@styled-icons/evaicons-outline": "^10.34.0",
"@styled-icons/fluentui-system-filled": "^10.35.0",
"@styled-icons/fluentui-system-regular": "^10.35.0",
"@styled-icons/foundation": "^10.34.0",
"@styled-icons/heroicons-outline": "^10.36.0",
"@styled-icons/ionicons-outline": "^10.34.0",
"@styled-icons/ionicons-solid": "^10.34.0",
"@styled-icons/material": "^10.34.0",
"@styled-icons/octicons": "^10.44.0",
"@tinymce/tinymce-react": "^3.13.0",
"@tsed/exceptions": "6.93.0",
"aws-amplify": "^4.3.10",
"axios": "^0.24.0",
"core-js": "^3.19.2",
"cors": "2.8.5",
"date-fns": "2.27.0",
"filepond": "^4.30.3",
"filepond-plugin-file-poster": "^2.5.0",
"filepond-plugin-file-validate-size": "^2.2.5",
"filepond-plugin-file-validate-type": "^1.2.6",
"filepond-plugin-image-preview": "^4.6.10",
"formik": "^2.2.9",
"framer-motion": "^5.3.3",
"google-map-react": "^2.1.10",
"graphql": "^16.0.1",
"graphql-request": "^3.7.0",
"html-react-parser": "^1.4.1",
"i18next": "21.5.4",
"ky": "0.28.7",
"micro": "9.3.4",
"next": "^12.0.7",
"next-compose-plugins": "^2.2.1",
"next-connect": "0.11.0",
"next-seo": "^4.28.1",
"nextjs-cors": "^2.1.0",
"nx": "^13.2.3",
"picocolors": "1.0.0",
"react": "^17.0.2",
"react-cookie": "^4.1.1",
"react-dom": "^17.0.2",
"react-filepond": "^7.1.1",
"react-i18next": "11.14.3",
"react-input-mask": "2.0.4",
"react-is": "17.0.2",
"react-merge-refs": "^1.1.0",
"react-query": "^3.34.0",
"react-redux": "^7.2.6",
"react-select": "^5.2.1",
"react-use": "^17.3.1",
"redux": "4.1.2",
"regenerator-runtime": "0.13.9",
"rooks": "5.8.0",
"sharp": "0.29.3",
"styled-components": "^5.3.3",
"superjson": "1.8.0",
"swiper": "^7.3.1",
"tslib": "^2.3.1",
"type-fest": "2.8.0",
"use-places-autocomplete": "^1.11.0",
"uuid": "^8.3.2",
"yup": "^0.32.11"
},
"devDependencies": {
"@babel/core": "^7.16.0",
"@babel/preset-react": "^7.16.0",
"@changesets/changelog-github": "0.4.2",
"@changesets/cli": "2.18.1",
"@next/bundle-analyzer": "12.0.6",
"@size-limit/file": "7.0.3",
"@storybook/react": "^6.4.7",
"@svgr/webpack": "6.1.0",
"@testing-library/jest-dom": "5.16.0",
"@testing-library/react": "12.1.2",
"@testing-library/react-hooks": "7.0.2",
"@types/cors": "2.8.12",
"@types/date-fns": "2.6.0",
"@types/eslint": "8.2.1",
"@types/jest": "27.0.3",
"@types/node": "16.11.11",
"@types/react": "17.0.37",
"@types/react-dom": "17.0.11",
"@types/react-is": "17.0.3",
"@types/react-redux": "^7.1.20",
"@types/shell-quote": "1.7.1",
"@types/styled-components": "^5.1.16",
"@typescript-eslint/eslint-plugin": "5.5.0",
"@typescript-eslint/parser": "5.5.0",
"autoprefixer": "10.4.0",
"babel-jest": "27.4.2",
"babel-loader": "^8.2.3",
"babel-plugin-module-resolver": "^4.1.0",
"babel-plugin-styled-components": "^2.0.2",
"cross-env": "7.0.3",
"cypress": "^9.1.1",
"dotenv": "^10.0.0",
"dotenv-flow": "3.2.0",
"dotenv-flow-cli": "1.0.0",
"duplicate-package-checker-webpack-plugin": "^3.0.0",
"eslint": "8.4.0",
"eslint-config-airbnb": "^19.0.2",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^16.1.0",
"eslint-config-next": "12.0.6",
"eslint-config-prettier": "8.3.0",
"eslint-import-resolver-babel-module": "^5.3.1",
"eslint-import-resolver-typescript": "2.5.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-import": "2.25.3",
"eslint-plugin-jest": "25.3.0",
"eslint-plugin-jest-formatting": "3.1.0",
"eslint-plugin-jsx-a11y": "6.5.1",
"eslint-plugin-prettier": "4.0.0",
"eslint-plugin-react": "7.27.1",
"eslint-plugin-react-hooks": "4.3.0",
"eslint-plugin-regexp": "1.5.1",
"eslint-plugin-sonarjs": "0.11.0",
"eslint-plugin-testing-library": "5.0.1",
"eslint-plugin-unused-imports": "^2.0.0",
"husky": "^7.0.4",
"is-ci": "3.0.1",
"jest": "27.4.3",
"lint-staged": "^12.1.2",
"ngx-deploy-npm": "^3.0.6",
"nock": "^13.2.1",
"npm-run-all": "4.1.5",
"prettier": "2.5.1",
"react-test-renderer": "17.0.2",
"rimraf": "3.0.2",
"sass": "1.44.0",
"shell-quote": "1.7.3",
"size-limit": "7.0.3",
"symlink-dir": "5.0.1",
"sync-directory": "4.0.7",
"ts-jest": "27.0.7",
"ts-node": "10.4.0",
"typescript": "4.5.2",
"typescript-plugin-styled-components": "^2.0.0"
},
"resolutions": {
"@mui/styled-engine": "npm:@mui/styled-engine-sc@latest"
}
}
```

# Amplify YML

```
- appRoot: apps/fox
env:
variables:
#AMPLIFY_DIFF_DEPLOY: true
backend:
phases:
build:
commands:
- '# Execute Amplify CLI with the helper script'
- echo BACKEND BUILD
- yarn set version 1.22.1
- amplifyPush --simple
frontend:
phases:
preBuild:
commands:
- export YARN_ENABLE_IMMUTABLE_INSTALLS=true
- cd ../..
- nvm install 14
- nvm use 14
# - yarn set version berry
- echo "//registry.npmjs.org/:_authToken=TOKEN" > .npmrc
# - yarn add @endemolshinegroup/cosmiconfig-typescript-loader
# - yarn plugin import @yarnpkg/plugin-constraints
# - yarn plugin import @yarnpkg/plugin-workspace-tools
# - yarn plugin import @yarnpkg/plugin-interactive-tools
# - yarn plugin import https://yarn.build/latest
# Replicates NPM CI with RM and Frozen Lock
# This install isn't really needed.
- yarn install --frozen-lockfile
- export NODE_OPTIONS=--max-old-space-size=8192
- echo POST YARN
- ls
build:
commands:
- ls
# - aws s3 cp amplify.yml s3://fox-sandbox/public/
- cd apps/fox
- yarn install --frozen-lockfile
- yarn amplify-build
- echo CD FOX
# Copy custom serverless to apps root.
- cp config/serverless.yml serverless.yml
# - aws s3 cp serverless.yml s3://fox-sandbox/public/
postBuild:
commands:
- ls
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- node_modules/**/*
```

# App Id
`d30o3wao502f5x`

# Next Config
```
// @ts-nocheck

// @ts-ignore
const pc = require('picocolors');

const packageJson = require('./package.json');

// @ts-ignore
const NEXTJS_IGNORE_ESLINT = process.env.NEXTJS_IGNORE_ESLINT === '1' || false;
const NEXTJS_IGNORE_TYPECHECK =
// @ts-ignore
process.env.NEXTJS_IGNORE_TYPECHECK === '1' || false;

// @ts-ignore
const isProd = process.env.NODE_ENV === 'production';

// Tell webpack to compile those packages
// @link https://www.npmjs.com/package/next-transpile-modules
const tmModules = [
// for legacy browsers support (only in prod)
...(isProd
? [
// ie: '@react-google-maps/api'...
]
: []),
// ESM only packages are not yet supported by NextJs if you're not
// using experimental experimental esmExternals
// @link {https://nextjs.org/blog/next-11-1#es-modules-support|Blog 11.1.0}
// @link {https://github.com/vercel/next.js/discussions/27876|Discussion}
// @link https://github.com/vercel/next.js/issues/23725
// @link https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
...[
// ie: newer versions of https://github.com/sindresorhus packages
]
];

/**
* A way to allow CI optimization when the build done there is not used
* to deliver an image or deploy the files.
* @link https://nextjs.org/docs/advanced-features/source-maps
*/
// @ts-ignore
const disableSourceMaps = process.env.NEXT_DISABLE_SOURCEMAPS === 'true';
if (disableSourceMaps) {
console.info(
`${pc.green(
'notice'
)}- Sourcemaps generation have been disabled through NEXT_DISABLE_SOURCEMAPS`
);
}

/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
reactStrictMode: false,
productionBrowserSourceMaps: !disableSourceMaps,

experimental: {
// // Prefer loading of ES Modules over CommonJS
// // @link {https://nextjs.org/blog/next-11-1#es-modules-support|Blog 11.1.0}
// // @link {https://github.com/vercel/next.js/discussions/27876|Discussion}
// esmExternals: true,

// Experimental monorepo support
// @link {https://github.com/vercel/next.js/pull/22867|Original PR}
// @link {https://github.com/vercel/next.js/discussions/26420|Discussion}
externalDir: true
},

// @link https://nextjs.org/docs/basic-features/image-optimization
images: {
formats: ['image/webp'],
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
domains: [
DOMAINS
]
},

typescript: {
ignoreBuildErrors: NEXTJS_IGNORE_TYPECHECK
},

eslint: {
ignoreDuringBuilds: true
},

webpack: (config, { isServer }) => {
if (!isServer) {
// Swap sentry/node by sentry/browser
// config.resolve.alias['@sentry/node'] = '@sentry/browser';
}

config.module.rules.push({
test: /\.svg$/,
issuer: /\.(js|ts)x?$/,
use: [
{
loader: '@svgr/webpack',
// https://react-svgr.com/docs/webpack/#passing-options
options: {
svgo: true,
// @link https://github.com/svg/svgo#configuration
svgoConfig: {
multipass: false,
datauri: 'base64',
js2svg: {
indent: 2,
pretty: false
}
}
}
}
]
});

return config;
},

env: {
APP_NAME: packageJson.name,
APP_VERSION: packageJson.version,
BUILD_TIME: new Date().toISOString(),
GMAPS_API: 'KEY',
GMAPS_DEV_API: 'KEY',
YARN_ENABLE_IMMUTABLE_INSTALLS: false
},
serverRuntimeConfig: {
// to bypass https://github.com/zeit/next.js/issues/8251
// @ts-ignore
// PROJECT_ROOT: __dirname
}
};

let config;
config = nextConfig;

// @ts-ignore
if (process.env.ANALYZE === 'true') {
// @ts-ignore
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: true
});
config = withBundleAnalyzer(config);
}

module.exports = config;
```

### Build Settings

_No response_

### Additional information

_No response_

Contributor guide

Open the contributing guide

Research direction

Start with the provided package JSON and Amplify YML, then run the amplify-build command to inspect the deployment output. Review the failing pages/restaurant/[id].js entry shown in the Lambda stack trace and compare its behavior with the reported 503 and missing services. Done means the deployment creates the expected API Lambda@Edge, image optimization, ISR Lambda, and ISR SQS Queue without the module-not-found error.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, next.js, react, webpack
Domain
backend, ci-cd, cloud, devops
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.