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:

  1. Set the build commands to npm run generate.
  2. Set the baseDirectory location to be dist.

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:

  1. Nuxt Generate -> Local folder -> AWS S3 Bucket -> AWS CloudFront CDN -> Browser
  2. [ nuxt generate ] [ gulp deploy ]
  3. [ 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.

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:

  1. deploy.sh - run `nuxt generate` and `gulp deploy`
  2. gulpfile.js - `gulp deploy` code to push files to S3 and invalidate CloudFront

Setting it up

  1. Make a S3 bucket and configure it for static site hosting
  2. Create a CloudFront distribution
  3. Configure security access
  4. 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 .

  1. #!/bin/bash
  2. export AWS_ACCESS_KEY_ID="key"
  3. export AWS_SECRET_ACCESS_KEY="secret"
  4. export AWS_BUCKET_NAME="example.com"
  5. export AWS_CLOUDFRONT="UPPERCASE"
  6. # Load nvm (node version manager), install node (version in .nvmrc), and npm install packages
  7. [ -s "$HOME/.nvm/nvm.sh" ] && source "$HOME/.nvm/nvm.sh" && nvm use
  8. # Npm install if not already.
  9. [ ! -d "node_modules" ] && npm install
  10. npm run generate
  11. gulp deploy

4.2) Make deploy.sh runnable and DON’T CHECK INTO GIT (deploy.sh has secrets in it)

  1. chmod +x deploy.sh
  2. echo "
  3. # Don't commit build files
  4. node_modules
  5. dist
  6. .awspublish
  7. deploy.sh
  8. " >> .gitignore

4.3) Add Gulp to your project and to your command line

4.4) Create a gulpfile.js with the build script

  1. const gulp = require('gulp')
  2. const awspublish = require('gulp-awspublish')
  3. const cloudfront = require('gulp-cloudfront-invalidate-aws-publish')
  4. const parallelize = require('concurrent-transform')
  5. // https://docs.aws.amazon.com/cli/latest/userguide/cli-environment.html
  6. const config = {
  7. // Required
  8. params: {
  9. Bucket: process.env.AWS_BUCKET_NAME
  10. },
  11. credentials: {
  12. accessKeyId: process.env.AWS_ACCESS_KEY_ID,
  13. secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  14. signatureVersion: 'v3'
  15. },
  16. // Optional
  17. deleteOldVersions: false, // NOT FOR PRODUCTION
  18. distribution: process.env.AWS_CLOUDFRONT, // CloudFront distribution ID
  19. region: process.env.AWS_DEFAULT_REGION,
  20. /* 'Cache-Control': 'max-age=315360000, no-transform, public', */
  21. },
  22. // Sensible Defaults - gitignore these Files and Dirs
  23. distDir: 'dist',
  24. indexRootPath: true,
  25. cacheFileName: '.awspublish',
  26. concurrentUploads: 10,
  27. }
  28. gulp.task('deploy', function () {
  29. // create a new publisher using S3 options
  30. // http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#constructor-property
  31. const publisher = awspublish.create(config)
  32. let g = gulp.src('./' + config.distDir + '/**')
  33. // publisher will add Content-Length, Content-Type and headers specified above
  34. // If not specified it will set x-amz-acl to public-read by default
  35. g = g.pipe(
  36. parallelize(publisher.publish(config.headers), config.concurrentUploads)
  37. )
  38. // Invalidate CDN
  39. if (config.distribution) {
  40. console.log('Configured with CloudFront distribution')
  41. g = g.pipe(cloudfront(config))
  42. } else {
  43. console.log(
  44. 'No CloudFront distribution configured - skipping CDN invalidation'
  45. )
  46. }
  47. // Delete removed files
  48. if (config.deleteOldVersions) {
  49. g = g.pipe(publisher.sync())
  50. }
  51. // create a cache file to speed up consecutive uploads
  52. g = g.pipe(publisher.cache())
  53. // print upload updates to console
  54. g = g.pipe(awspublish.reporter())
  55. return g
  56. })

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.