Single Page App deploy with fullstack-serverless
Project setup #
create-react-app spa-test
cd spa-test
rm src/*
touch src/index.js
# edit index.js file (see below)
yarn start
yarn build
yarn add --dev serverless fullstack-serverless
touch serverless.yml
# edit serverless.yml (see below)
# add AWS credentials (see below)
# add "deploy": "serverless deploy" to package.json scripts
src/index.js
:
import React from "react";
import ReactDOM from "react-dom";
const App = () => (
<div>
<h1>Hello</h1>
<p>You are on {window.location.pathname}</p>
</div>
);
ReactDOM.render(<App />, document.getElementById("root"));
serverless.yml
:
plugins:
- fullstack-serverless
service: spa-test
provider:
name: aws
runtime: nodejs6.10
#stage: dev # Set the default stage used. Default is dev
#region: us-east-1 # Overwrite the default region used. Default is us-east-1
custom:
fullstack:
domain:
certificate:
bucketName: deploy
distributionFolder: build # Path to the client assets to be uploaded to S3
indexDocument: index.html # The index document to use (not used in this config)
errorDocument: error.html # The error document to use (not used in this config)
singlePageApp: true # If true 403 errors will be rerouted (missing assets) to your root index document
apiPath: api # The path prefix for your API Gateway lambdas.
clientCommand: yarn build # Command to generate the client assets. Defaults to doing nothing
clientSrcPath: . # The path to where you want to run the clientCommand
~/.aws/credentials
:
[default]
aws_access_key_id = ACCESS_KEY
aws_secret_access_key = SECRET_KEY
First deploy #
The first time, it takes more than 10 minutes
yarn deploy
Result:
Serverless: Packaging service...
Serverless: Removing logging bucket...
Serverless: Setting price class PriceClass_All...
Serverless: Setting ApiGateway stage to 'dev'...
Serverless: Setting API path prefix to 'api'...
Serverless: Configuring distribution for single page web app...
Serverless: Setting up 'spa-test-dev-deploy' bucket...
Serverless: Setting indexDocument to 'index.html'...
Serverless: Setting errorDocument to 'error.html'...
Serverless: ApiGatewayRestApi not found, removing orgin from CloudFront...
Serverless: Creating Stack...
....
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Validating template...
Serverless: Updating Stack...
....
Serverless: Stack update finished...
Serverless: Generating client...
Serverless: Client generation process succeeded...
Serverless: This deployment will:
Serverless: - Remove all existing files from bucket 'spa-test-dev-deploy'
Serverless: - Upload all files from 'build' to bucket 'spa-test-dev-deploy'
Serverless: Looking for bucket 'spa-test-dev-deploy'...
Serverless: Bucket found...
Serverless: Deleting all objects from bucket...
Serverless: Uploading client files to bucket...
Serverless: Success! Client deployed.
Service Information
service: spa-test
stage: dev
region: us-east-1
stack: spa-test-dev
resources: 5
api keys:
None
endpoints:
None
functions:
None
layers:
None
CloudFront domain name
d2fnezabgre4sw.cloudfront.net (CNAME: null)
https://console.aws.amazon.com/s3/buckets/spa-test-dev-deploy/?region=us-east-1&tab=overview
Configuring domain and https #
Setup DNS #
Depends on your DNS provider. Add a CNAME to the cloudfront domain name.
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html
Add the domain name to serverless.yml
Amazon Certificate Manager #
https://console.aws.amazon.com/acm/home?region=us-east-1#/
Add certificate to serverless.yml
More deploys #
Cloudfront cache are not invalidated when deploying, so I use this (package.json) scripts (that uses aws-cli):
"deploy": "serverless deploy -v && yarn run cloudfront:invalidate",
"cloudfront:invalidate": "aws cloudfront create-invalidation --distribution-id AWS_DIST_ID --paths '/*'",
Then yarn deploy