Hosting a static generated Nuxt app on AWS w/ the Amplify Console is powerful and cheap.
First, push your Nuxt app to the Git provider of your choice. Then, visit the . Click the GET STARTED button under the Deploy header if you haven’t used Amplify Hosting before, otherwise click the Connect App button.
On the “From your existing code” page, select your Git provider and click Continue.
Add repository branch
On the “Add repository branch” page, select your repository and the branch you want to deploy. Then, click Next.
Configure build settings
On the “Configure build settings” page, click the button under the “Build and test settings”. Change the following:
- Set the build commands to
npm run generate
. - Set the
baseDirectory
location to bedist
.
The settings should look like this once you are done editing them:
Then, click Save and Next.
On the review page, click Save and deploy.
Then, your application will deploy. This may take a few minutes.
Once Provision
, Build
, Deploy
, and Verify
are green, click on the URL that the Amplify Console provides to view your site.
AWS w/ S3 + CloudFront
Overview
We’ll host super cheap with some AWS services. Briefly:
- S3
- cloud data “bucket” for our website files
- can be configured to host static websites
- CloudFront
- a CDN (content delivery network)
- offers free HTTPS certs
- Makes your site load faster
We’ll push the site like this:
Nuxt Generate -> Local folder -> AWS S3 Bucket -> AWS CloudFront CDN -> Browser
[ nuxt generate ] [ gulp deploy ]
[ deploy.sh ]
First, we’ll generate the site with nuxt generate
(<= v2.12). Then, we’ll use Gulp to publish the files to a S3 bucket and invalidate a CloudFront CDN.
- gulp-awspublish
- concurrent-transform (for parallel uploads)
Our deploy script needs these environment variables set:
- AWS_BUCKET_NAME=”example.com”
- AWS_CLOUDFRONT=”UPPERCASE”
- AWS_ACCESS_KEY_ID=”key”
- AWS_SECRET_ACCESS_KEY=”secret”
We’ll have these files:
deploy.sh - run `nuxt generate` and `gulp deploy`
gulpfile.js - `gulp deploy` code to push files to S3 and invalidate CloudFront
Setting it up
- Make a S3 bucket and configure it for static site hosting
- Create a CloudFront distribution
- Configure security access
- Setup build script in your project
Please follow this tutorial to setup your S3 and CloudFront for step one and two.
You should now have this data:
- AWS_BUCKET_NAME=”example.com”
- AWS_CLOUDFRONT=”UPPERCASE”
AWS: Configure security access
For step 3, we need to create a user that can:
- Update the bucket contents
- Invalidate the CloudFront distribution (propagates changes to users faster)
Create a programmatic user with this policy:
Then .
You should now have this data:
- AWS_ACCESS_KEY_ID=”key”
- AWS_SECRET_ACCESS_KEY=”secret”
Laptop: Setup your project’s build script
4.1) Create a deploy.sh
script. See optional .
#!/bin/bash
export AWS_ACCESS_KEY_ID="key"
export AWS_SECRET_ACCESS_KEY="secret"
export AWS_BUCKET_NAME="example.com"
export AWS_CLOUDFRONT="UPPERCASE"
# Load nvm (node version manager), install node (version in .nvmrc), and npm install packages
[ -s "$HOME/.nvm/nvm.sh" ] && source "$HOME/.nvm/nvm.sh" && nvm use
# Npm install if not already.
[ ! -d "node_modules" ] && npm install
npm run generate
gulp deploy
4.2) Make deploy.sh
runnable and DON’T CHECK INTO GIT (deploy.sh has secrets in it)
chmod +x deploy.sh
echo "
# Don't commit build files
node_modules
dist
.awspublish
deploy.sh
" >> .gitignore
4.3) Add Gulp to your project and to your command line
4.4) Create a gulpfile.js
with the build script
const gulp = require('gulp')
const awspublish = require('gulp-awspublish')
const cloudfront = require('gulp-cloudfront-invalidate-aws-publish')
const parallelize = require('concurrent-transform')
// https://docs.aws.amazon.com/cli/latest/userguide/cli-environment.html
const config = {
// Required
params: {
Bucket: process.env.AWS_BUCKET_NAME
},
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
signatureVersion: 'v3'
},
// Optional
deleteOldVersions: false, // NOT FOR PRODUCTION
distribution: process.env.AWS_CLOUDFRONT, // CloudFront distribution ID
region: process.env.AWS_DEFAULT_REGION,
/* 'Cache-Control': 'max-age=315360000, no-transform, public', */
},
// Sensible Defaults - gitignore these Files and Dirs
distDir: 'dist',
indexRootPath: true,
cacheFileName: '.awspublish',
concurrentUploads: 10,
}
gulp.task('deploy', function () {
// create a new publisher using S3 options
// http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#constructor-property
const publisher = awspublish.create(config)
let g = gulp.src('./' + config.distDir + '/**')
// publisher will add Content-Length, Content-Type and headers specified above
// If not specified it will set x-amz-acl to public-read by default
g = g.pipe(
parallelize(publisher.publish(config.headers), config.concurrentUploads)
)
// Invalidate CDN
if (config.distribution) {
console.log('Configured with CloudFront distribution')
g = g.pipe(cloudfront(config))
} else {
console.log(
'No CloudFront distribution configured - skipping CDN invalidation'
)
}
// Delete removed files
if (config.deleteOldVersions) {
g = g.pipe(publisher.sync())
}
// create a cache file to speed up consecutive uploads
g = g.pipe(publisher.cache())
// print upload updates to console
g = g.pipe(awspublish.reporter())
return g
})
4.5) Deploy and debug
Run it:
You should get an output similar to this:
Note that the is the only output from the CloudFront invalidation npm package. If you don’t see that, it’s not working.