I just managed to deploy my Nuxt application via Serverless on AWS. Basically everything works as expected but in some cases the Lambda function just runs into a timeout and can't serve my Nuxt application. Since my application is a SPA the timeout only happens during a refresh of the browser window or when I visit my page in a new tab, but only sometimes. I already increased the Lambda timeout to 30s (meets the timeout of the API Gateway) which should be enough but the timeout still occurs.
Here's my serverless.yml:
service:
name: test-app
plugins:
- serverless-nuxt-plugin
- serverless-dotenv-plugin
- serverless-domain-manager
resources:
Resources:
AssetsBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:custom.nuxt.bucketName}
CorsConfiguration:
CorsRules:
- AllowedMethods:
- GET
- HEAD
AllowedOrigins:
- "*"
provider:
name: aws
region: eu-central-1 # this field is used for the assets files s3 path.
stage: ${env:APP_ENV}
runtime: nodejs12.x
environment:
NODE_ENV: ${env:APP_ENV}
tags: # Optional service wide function tags
usecase: test-app
environment: ${self:provider.stage}
domain: ${env:DEPLOY_DOMAIN}
custom:
nuxt:
version: app-${self:provider.stage}-v1
bucketName: test-app-static-${self:provider.stage}
cdnPath: https://cdn.XXX.com
customDomain:
domainName: ${env:DEPLOY_DOMAIN}
certificateName: ${'*.'}${env:DEPLOY_DOMAIN}
createRoute53Record: true
endpointType: 'regional'
functions:
nuxt:
handler: lambda-handler.render
memorySize: 512 # in MB with steps of 64
timeout: 30 # in seconds
events:
- http: ANY /
- http: ANY /{proxy+}
And my Lambda handler:
const awsServerlessExpress = require('aws-serverless-express');
const express = require('express');
const { Nuxt } = require('nuxt-start'); // eslint-disable-line
const nuxtConfig = require("./nuxt.config.js");
const app = express();
const nuxt = new Nuxt({
...nuxtConfig,
dev: false,
_start: true,
});
app.use(async (req, res) => {
if (nuxt.ready) {
await nuxt.ready()
}
nuxt.render(req, res)
});
const server = awsServerlessExpress.createServer(app, void 0, [
'application/javascript',
'application/json',
'application/manifest+json',
'application/octet-stream',
'application/xml',
'font/eot',
'font/opentype',
'font/otf',
'image/gif',
'image/jpeg',
'image/png',
'image/svg+xml',
'image/x-icon', // for favicon
'text/comma-separated-values',
'text/css',
'text/html',
'text/javascript',
'text/plain',
'text/text',
'text/xml',
'application/rss+xml',
'application/atom+xml',
]);
module.exports.render = (event, context) => {
awsServerlessExpress.proxy(server, event, context);
};
Additionally, I setup a CloudFront distribution in front of my API Gateway to redirect http traffic to https. So nothing really special, I guess.
Here's an example of my CloudWatch logs that shows an example timeout:
So the duration of the Lambda is pretty distributed and I can't really understand why. I even found durations of 100ms but they can get up until the timeout of 30s. Is there anything wrong in my setup or something I missed? I'm aware of the cold start bottleneck for Lambdas but these timeout calls are not caused by a cold start.
I really appreciate your help!
if(nuxt.ready)actually a thing? you can just haveawait nuxt.ready()by itself which will wait until ready to render. I'm not too familiar with Nuxt but I can't find any reference toreadyas a property. - cyberwombatnuxt.ready()really exists. - Ferdinand Frank